Common Security Vulnerability PHP

PHP (Hypertext Preprocessor) adalah sebuah bahasa pemrograman scripting yang berjalan pada server atau biasa dikenal dengan server side rendering. Seperti pada bahasa pemrograman lainnya, PHP memiliki syntax penulisannya sendiri serta fitur-fitur tertentu seperti data processing, form validation, upload file, session management, send email, dan komunikasi dengan MySQL, PostgreSQL, MongoDB, SQlite, lalu support untuk banyak protocol seperti XML, JSON, SOAP, REST. Dilansir dari W3Techs per 2 februari 2024, secara statistik PHP menempati bahasa pemrograman yang paling banyak dipakai diantara bahasa lainnya dengan statistik 76.5%. Disamping penggunaannya banyak digunakan, PHP memiliki banyak kerentanan, berikut beberapa contoh kerentanan pada vanilla PHP:

  1. SQL Injection

SQL injection merupakan suatu vulnerability yang memanfaatkan atau memanipulasi atau merubah payload query yang dijalankan untuk dapat membaca/manipulasi/mengakses data dari database

Contoh implementasi serangan SQL injection pada code PHP: 

https://github.com/jonathansantoso/csc_phpVuln/tree/sqli pada branch “sqli” github repository berikut terdapat code PHP yang rentan dengan SQL Injection  dan pada branch “sqli_patched” terdapat versi secure atau versi patched-nya.

Berikut ini merupakan source code dari “controller.php” yang terdapat pada link github diatas:

Pada code tersebut terdapat payload query sebagai berikut

$query = “SELECT * FROM USERS where username = ‘$username’ and password = ‘$password'”;

Dimana pada query ini akan memilih atau mengambil semua data dari tabel “USERS” dan melakukan validasi dimana “username” dan “passwordnya” dicocokan dengan “$username” dan “$password” yang merupakan input dari user.

Secara singkat SQL Injection akan dilakukan dengan merubah logic query yang ada seperti pada bagian “username” dimasukan petik ( ‘ ) sehingga payload akan menjadi seperti berikut

SELECT * FROM USERS where username = ‘ ‘ ‘ and password = ‘$password’.

Pada query ini akan terdapat broken logic karena kelebihan 1 petik pada bagian username=’ ‘ ‘  dengan begitu kita dapat memanfaatkan broken logic tersebut dengan menggunakan comment pada SQL language yaitu ‘– -’ atau ‘#’ sehingga sisa query di belakangnya tidak dijalankan. Maka payload akan menjadi seperti berikut ketika memasukan ‘# pada kolom “username”

SELECT * FROM USERS where username = ”# ‘ and password = ‘$password’

Maka sisa payload setelah comment (#) tidak akan dijalankan 

SELECT * FROM USERS where username = ”# ‘ and password = ‘$password’

Setelah itu, common payload yg digunakan untuk melakukan bypass login adalah dengan menambahkan logic “ OR 1=1 . Maka maka payload yg dijalankan adalah sebagai berikut

SELECT * FROM USERS where username = ” OR 1=1 #  ‘ and password = ‘$password’

Dengan begini maka payload akan dijalankan dengan validasi “username” sama dengan kosong (null) atau 1=1 (true). Payload ini juga memanfaatkan gerbang logika OR dimana ketika salah satu datanya true maka hasilnya akan true, sehingga validasi “username” pada payload akan bernilai true. Dengan validasi bernilai true ini maka kita dapat langsung login tanpa mengetahui username, karena apapun yang kita masukan akhirnya akan bernilai true.

Hal ini dapat terjadi karena kesalahan pada design code dimana query atau payload yang dibuat langsung mengambil username dan password sebagai suatu input dan digabungkan ke dalam query yang akan dijalankan, sehingga ketika memasukan command SQL language maka akan ikut tereksekusi. 

Lalu untuk mencegah SQL injection ini dapat menggunakan prepared statement, dimana query yang kita siapkan akan dijalankan terlebih dahulu dan menunggu input username dan password dari user. Bedanya disini adalah query atau payload kita sudah dalam proses sehingga username dan password yang kita input akan tetap dianggap sebuah string apapun yang kita masukan dan tidak akan diproses atau dieksekusi oleh server.

Contoh penerapannya adalah sebagai berikut:

$query = “SELECT * FROM USERS where username = ‘$username’ and password = ‘$password'”;

$res = $db->prepare(“SELECT * FROM USERS where username = ? and password = ?”);

$res->bind_param(“ss”, $username, $password);

$res->execute();

$result = $res->get_result();

  1. CSRF Attack

Cross Site Request Forgery (CSRF) adalah sebuah serangan yang memaksa user yang sudah ter authenticated  pada suatu aplikasi melakukan aksi tanpa sepengetahuan pengguna, umumnya serangan ini terjadi ketika user mengunjungi suatu website/aplikasi eksternal mengunjungi baik sengaja atau tidak sengaja yang sudah disiapkan sedemikian rupa untuk melakukan malicious request seakan-akan korban yang login melakukan request tersebut. 

Syarat dari serangan ini adalah request pada malicious website harus mengikuti request website asli-nya baik dalam sisi parameter yang dikirim, http request header, dll. Jika terdapat perbedaan akan gagal dalam melakukan serangan ini. 

Sebagai contoh pada https://github.com/jonathansantoso/csc_phpVuln/tree/sqli repo yang sama terdapat fitur mengganti username dengan tampilan seperti ini 

Dan source code nya akan terlihat seperti ini:

Dan controllernya akan terlihat seperti ini:

Untuk testing serangan CSRF kita akan membuat suatu imitasi dari request changeUsername yang berasal dari csc_phpVuln_fake file maliciousRequest.php, yang akan mengarahkan request-nya ke csc_phpVuln yang asli. 

Jika di eksekusi di eksekusi pada malicious website dengan catatan terdapat user yang sedang login, akan mengganti username dari user yang login dengan apapun yang di request oleh malicious website.

Misal username-nya jadi bernama testbro, pada point of view korban jika refresh, akan mengganti username sesuai yang di request dari malicious website.

Itu adalah flow manual bagaimana serangan CSRF bisa terjadi, serangan umum pada CSRF adalah ketika korban tidak sengaja redirect ke website malicious yang sudah dibuat sedemikian rupa agar berjalan dibelakang layar, contoh serangan yang mungkin terjadi adalah penghapusan account, melakukan transaksi, ganti password, kirim pesan, dll

Lalu bagaimana cara mengatasi masalah ini? Terdapat berbagai cara untuk mengatasi serangan ini, cara pertama dan paling umum digunakan adalah dengan generate token CSRF dan kirim token tersebut setiap melakukan request, kurang lebih bentuknya akan seperti ini: bisa dilihat pada form change profile, akan melakukan generate token CSRF yang nantinya akan divalidasi saat submit form untuk diproses, kurang lebih akan seperti ini

Pada saat form change profile di submit akan ada pengecekan apakah token csrf yang dikirim itu sama dengan yang ada pada session saat itu juga, jika sama permintaan ganti username akan diproses, lalu apakah itu sudah cukup? Bagaimana terdapat kasus seseorang login dan tidak melakukan apapun (idle), bisa saja token csrf yang digenerate itu diambil dan disalahgunakan, maka dari itu ada baiknya kita memakai expire time pada token csrf.

akan dilakukan generate to expire time pada csrf token yang berlaku untuk satu jam kedepan. Lalu pada saat dikirimkan akan diproses apakah token yang di generate tadi sudah expired atau belum.

    3. XSS Attack

Untuk mengetahui apakah suatu aplikasi memiliki kerentanan pada XSS, kiita masih memakai halaman change profile untuk XSS attack dan menggunakan payload

<script>alert(“test”)</script>

<script>alert(document.cookie)</script>

 

Jika berhasil akan memunculkan pop up yang berisi tentang cookie yang saat ini sedang aktif

 

Bayangkan jika suatu website memakai cookie sebagai alat untuk authentication, bisa saja orang yang tidak berhak, login dengan cookie yang ia dapat. Untuk mencegah hal ini. Bisa menggunakan sanitation terhadap inputan user, kurang lebih code nya akan seperti ini

 

Kita akan memakai function bawaan dari php yaitu HTML entities untuk mengganti character khusus menjadi code html yang kalau diinterpretasikan akan sama dengan character yang kita inginkan, sebagai contoh jika kita menginputkan ‘<script>alert(“t”)</script>’ Akan menjadi seperti ini

 

Dengan menggunakan htmlentities, payload tersebut akan disimpan sebagai character code html tersendiri.

Reference :

SQL injection

https://www.aquasec.com/cloud-native-academy/application-security/php-security/#:~:text=Because%20of%20PHP’s%20popularity%2C%20it,site%20request%20forgery%20(CSRF).

https://medium.com/@alrazak/php-6506742d443b

https://medium.com/@london.lingo.01/10-reasons-why-php-is-still-relevant-in-2023-d533ed6dc687

https://medium.com/swlh/basics-of-php-b6cab90787cf

https://www.kodingakademi.id/bahasa-pemrograman-php-apakah-masih-menarik-di-2023-ini/#:~:text=Statistik%20tahun%202022%20menunjukkan%20bahwa,situs%20web%20masih%20menggunakan%20PHP.

https://security.stackexchange.com/questions/643/why-do-people-say-that-php-is-inherently-insecure

https://www.linkedin.com/pulse/why-php-considered-insecure-yassine-mabrouk

https://w3techs.com/technologies/overview/programming_language

CSRF attack

https://owasp.org/www-community/attacks/csrf

https://www.synopsys.com/glossary/what-is-csrf.html#:~:text=Definition,has%20in%20an%20authenticated%20user.

Jonathan, Johanes, Pitra Winarianto