Tips Untuk Koding PHP yang Aman

Bila kita berbicara soal keamanan, Kita jangan hanya terpaku pada isu-isu keamanan dari platform dan sistem operasi yang digunakan saja, tapi juga harus memikirkan bagaimana agar aplikasi yang sedang Kita bangun terbebas dari masalah-masalah keamanan yang mungkin saja bisa terjadi.
Ketika kita berurusan dengan bahasa pemrograman PHP baik itu dalam membangun aplikasi ataupun web, Disarankan untuk selalu menanamkan beberapa kebiasaan berikut ini:
  • Validasi GPC (GET, POST, COOKIE)
  • Pengamanan File System
  • Pengamanan Database
  • Pengamanan data Session
  • Pengamanan terhadap XSS vulnerabilities

Validasi GPC (GET, POST, COOKIE)


Kenapa?... Sebagian besar pengguna aplikasi atau web yang Kita bangun memang hanya pengguna biasa yang melakukan input dan mengirimkannya dengan menggunakan Form yang telah kita sediakan, tapi tahukan Anda, dari sekian banyak user yang baik tersebut kadang Kita juga menjumpai beberapa user yang berniat untuk masuk, mencuri data atau bahkan merusak sistem atau aplikasi Kita dengan cara merubah request yang dikirimkan. Oleh karena itu jangan pernah mempercayai variabel tersebut sebagai variabel yang valid.
Apa mungkin?... Ya, tentu saja. Variabel $_GET dapat dengan mudah dimodifikasi pada browser dengan mengubah alamat pada bagian query, misalnya http://contoh.com/index.php?variabel=variabel+yang+dikirim+dapat+diubah. Variabel $_POST dapat dengan mudah diubah bila Kita menggunakan plugin browser pada request bagian body. Variabel $_COOKIE juga dapat dengan mudah di rubah pada preferensi browser atau ketika melakukan request dengan plugin browser, atau yang lebih parah lagi user dapat menggunakan telnet atau aplikasi socket lainnya dan membuat sendiri request HTTP yang dia inginkan.
Berikut adalah beberapa cara untuk menghindari pemanfaatan GPC dalam isu keamanan:
  • Selalu aktifkan magic_quotes_gpc pada php.ini dan Selalu waspada dengan karakter petik dan petik ganda. Berhubungan juga dengan Pengamanan Database.Konfigurasi magic_quotes_gpc berfungsi untuk menambahkan karakter backslash pada karakter-karakter escape seperti petik dan petik ganda untuk variabel GPC. Hal ini dapat mengurangi kemungkinan untuk melakukan penyerangan pada SQL ketika melakukan query pada database..
  • Jangan pernah mengirimkan path atau lokasi suatu file pada variabel-variabel tersebut. Akan dibahas pada Pengamanan File System. User bisa saja merubah alamat berikut index.php?modul=home.php menjadi index.php?modul=/etc/passwd sehingga dapat membaca isi dari file yang dimaksud.
  • Selalu gunakan htmlspecialchars untuk menampilkan variabel tersebut pada halaman web. Akan dibahas pada Pengamanan terhadap XSS vulnerabilities. Karakter-karakter < dan > merupakan hal yang sangat riskan pada HTML, sehingga dapat dimanfaatkan oleh user untuk mengubah tampilan, menambah gambar, bahkan menambahkan javascript pada suatu halaman web.
  • Jangan pernah memasukan username atau password pada form atau cookie Akan dibahas pada Pengamanan data Session. User bisa saja merubah variabel cookie yang berisi username miliknya dengan username milik orang lain dan melakukan aktifitas yang tidak diinginkan dengan menggunakan account milik orang lain.
  • Selalu buat daftar yang diijinkan. Bila Kita hanya mengijinkan data yang diperbolehkan adalah 'Pria' dan 'Wanita', buatlah daftar yang diijinkan dan selalu periksa variabel GPC tersebut. Bila data yang dikirimkan berisi 'Waria' maka data tersebut harus dikategorikan palsu dan jangan diproses.

Pengamanan File System


Hal yang sering menjadi blunder untuk para programmer web dengan PHP adalah mengirimkan nama file pada modul web yang sedang di akses pada variabel GPC khususnya GET. Sebisa mungkin hindari kebiasaan ini, dan gunakan metode lain misalnya dengan $_SERVER['REQUEST_URI'] yang di parsing dengan karakter /, atau sebagainya. Bila tidak memungkinkan, Kita masih dapat memanfaatkan fasilitas GET tersebut dengan persyaratan-persyaratan yang harus selalu dipertimbangkan:
  • Jangan pernah memasukan nama file dan ekstensi nya. Bila Akan memanggil file PHP dari variabel GET tersebut, kirim seperti berikut index.php?modul=home, dan ketika akan memanggilnya, gunakan include "{$_GET['modul']}.php";.
  • Jangan pernah mengijinkan karakter slash atau backslash, sangat disarankan untuk tidak pernah sekalipun memperbolehkan slash atau backslash untuk variabel modul tersebut, karena user dapat dengan mudah merubah variabel GET tersebut untuk mengakses file lain yang berada pada direktori lainnya.
  • Gunakan ereg_replace("\/\\","",$_GET['modul']); untuk memastikan tidak terdapat slash dan backslash..
  • Periksa Keberadaan File. Selalu periksa keberadaan file yang di include berdasarkan variabel $_GET['modul'] tersebut, sehingga Kita dapat menampilkan halaman error atau melakukan redirect ke halaman home atau lainnya.
Berikut adalah contoh penggunaan GET untuk akses modul dengan aman.
<?php 
$modul = $_GET['modul']; 

/* Menghilangkan Slash dan Backslash */ 
$modul = str_replace('/','',str_replace('\\','',$modul)); 
$boleh_include = true; 

/* Cek Keberadaan File */ 
/* Biasakan modul berada pada direktori khusus */ 
if (!file_exists("modul/{$modul}.php")){ 
$boleh_include = false; 
} 

/* Cek file yang tidak boleh di include */ 
if (($modul=='index')||($modul=='konfigurasi')){ 
$boleh_include = false; 
} 

if (!$boleh_include){ 
/* Redirect */ 
header('location:index.php'); 
exit(); 
} 

/* Sekarang sudah aman untuk melakukan include */ 
include "modul/{$modul}.php"; 
?> 

Pengamanan Database


Permasalahan utama yang datang pada keamanan dalam database dengan PHP adalah penggunaan escape characters yang tidak baik, sehingga user dapat memanipulasi SQL yang dijalankan. Oleh karena itu konfigurasi "magic_quotes_gpc=on" sangat dianjurkan.Berikut adalah contoh SQL yang dapat dimanipulasi bila konfigurasi"magic_quotes_gpc=off"
<?php 
mysql_query("SELECT * FROM `user` WHERE `id`='{$_GET['id']}'"); 
?> 
Bila user merubah URL dengan:
index.php?id=1%27%3BDELETE+%2A+FROM+%60user%60+WHERE+%60id%60%21%3D%27 
maka apa yang terjadi?, SQL yang dikirimkan ke server akan berubah menjadi:
SELECT * FROM `user` WHERE `id`='1';DELETE * FROM `user` WHERE `id`!='' 
Tapi bila konfigurasi "magic_quotes_gpc=On", Query akan menjadi:
SELECT * FROM `user` WHERE `id`='1\';DELETE * FROM `user` WHERE `id`!=\'' 
Tidak terlalu membahayakan. Tapi tetap hal ini masih kurang memadai. Dalam kasus ini, variabel$_GET['id'] yang kita inginkan hanya berupa integer, maka penerapan yang lebih baik adalah sebagai berikut:
<?php 
$id=(int) $_GET['id']; 
mysql_query("SELECT * FROM `user` WHERE `id`='{$id}'"); 
?> 
Jangan lupa juga untuk menggunakan mysql_real_escape_string() untuk WHERE yang memiliki algoritma seperti LIKE, sehingga user tidak dapat memasukan karakter-karakter seperti % yang merupakan karakter khusus dalam SQL untuk menyatakan ANY.

Hal lain yang harus selalu di ingat. Jangan pernah memasukan password ke dalam database tanpa dilakukan enkripsi. Bila memungkinkan, gunakan enkripsi atau hash yang tidak mungkin untuk dapat di dekripsi. Misalnya dengan MD5 dan SHA dengan catatan, tambahkan SALT [^] (Karakter Tambahan) sehingga password yang dimaksud tidak dapat di dekripsi dengan menggunakan database dekripsi. Contoh:
<?php 

$password = "{$_POST['username']}-{$_POST['password']}-{$_POST['username']}-SALT"; 
$password = md5($password); 

?> 
Hal tersebut harus dilakukan, karena selain isu keamanan pada aplikasi yang kita bangun, isu keamanan juga dapat muncul pada bug-bug yang ada pada platform atau operasi sistem yang digunakan sehingga mungkin saja ada suatu user yang dapat masuk ke server dan mengakses database server tersebut karena kesalahan konfigurasi server atau bug yang berada pada os itu sendiri.


Pengamanan Data Session


Secara default, Informasi Session dalam PHP ditulis ke direktori sementara (Temporary Directory). PHP membuat suatu cookie sebagai ID dan menyimpan data sessionnya di server, hal ini lebih aman daripada kita menggunakan COOKIE dan menyimpan semua datanya pada COOKIE di browser, karena dapat dimanipulasi oleh user sendiri. Tapi apakah dengan menggunakan fasilitas SESSION tersebut semua session yang disimpan sudah aman? Tentu saja tidak. Untuk data session yang begitu penting, Kita jangan pernah mengambil resiko, gunakan selalu enkripsi dan custom handler untuk session seperti pada contoh berikut:
<?php 
function open($save_path, $session_name) 
{ 
/* custom code */ 
return (true); 
} 

function close() 
{ 
/* custom code */ 
return (true); 
} 

function read($id) 
{ 
/* custom code */ 
return (true); 
} 

function write($id, $sess_data) 
{ 
/* custom code */ 
return (true); 
} 

function destroy($id) 
{ 
/* custom code */ 
return (true); 
} 

function gc($maxlifetime) 
{ 
/* custom code */ 
return (true); 
} 

session_set_save_handler("open", "close", "read", "write", "destroy", "gc"); 

?> 
Dan jika memungkinkan, buat Private & Public Key tersendiri untuk setiap session dengan menggunakan fungsi-fungsi OpenSSL[^] yang terdapat pada PHP, sehingga data session hanya dapat diakses oleh pengguna session itu sendiri.
Pengamanan terhadap XSS vulnerabilities
XSS vulnerabilities mewakili sebagian besar dari semua kerentanan Web-site yang didokumentasikan pada tahun 2007 ( link external [^] ). Sebuah XSS vulnerabilities terjadi bila pengguna memiliki kemampuan untuk menyuntikkan kode HTML ke halaman Web Anda. Kode HTML dapat membawa kode JavaScript di dalam tag script, sehingga memungkinkan JavaScript untuk berjalan setiap kali halaman direquest.
Untuk menjaga terhadap serangan XSS, filter masukan Form dengan fungsi htmlentities() atau htmlspecialchars() bila akan menampilkan variabel kedalam output (echo atau print). Ingatlah untuk mengikuti kebiasaan pertama validasi data input dengan isi variabel yang diperbolehkan pada nama, alamat, e-mail, nomor telepon, dan informasi lainnya.
Berikut adalah contoh aman untuk mencegah XSS vulnerabilities:
<html> 
<head> 
<title>Demonstrasi XSS</title> 
</head> 
<body> 
<?php 
echo("<p>Anda menuliskan isi:</p>"); 
echo("<p>"); 
echo(htmlentities($_POST['text'])); 
echo("</p>"); 
?> 
</body> 
</html> 
Kesimpulan :
Sebenarnya masih banyak hal-hal yang harus dipertimbangkan untuk keamanan aplikasi/web yang sedang Anda bangun dengan menggunakan PHP, tapi dengan beberapa hal yang diuraikan tersebut, minimal Kita dapat mengurangi potensi hole sistem yang sedang kita bangun, karena hal-hal tersebut di atas merupakan beberapa hal yang sering dilupakan programmer dan ironisnya sering menjadi incaran para hacker.
Seperti yang diungkapkan pada PHP Manual bahwa "A completely secure system is a virtual impossibility" - "Sistem yang sepenuhnya aman hampir menjadi hal yang mustahil". Sehingga pendekatan yang sering digunakan dalam menerapkan keamanan adalah menyeimbangkan resiko dan kegunaan. Jika setiap variabel yang diajukan oleh pengguna diperlukan dua bentuk validasi biometric (seperti scan retina dan sidik jari), Anda akan memiliki tingkat akuntabilitas sangat tinggi. Hal ini juga akan mengambil setengah jam untuk mengisi formulir yang cukup kompleks, yang akan cenderung mendorong pengguna untuk menemukan cara-cara untuk melewati keamanan.
Keamanan terbaik adalah sering tidak mengganggu atau cukup untuk memenuhi kebutuhan tanpa pengguna dicegah dari menyelesaikan pekerjaan mereka, atau terlalu membebani programmer dengan kompleksitas yang berlebihan. Dan buktinya beberapa serangan keamanan terjadi pada sistem yang lebih kompleks daripada sistem yang sangat sederhana.

Source : http://amarullz.blog.unikom.ac.id/