Belajar bagaimana untuk menghindari kesilapan yang biasa dilakukan dalam PHP, menjadikan sistem atau laman web kita adalah selamat.

PHP adalah bahasa sangat mudah untuk dipelajari, dan ramai yang pernah menggunakannya tidak mempunyai latar belakang yang hebat dalam pengaturcaraan. Dan ianya mudah untuk menghasilkan sebuah laman web yang sangat berinteraktif.

Walau bagaimanapun, kebanyakan daripada kita mungkin tidak terlalu menekankan kepada isu dan potensi risiko kepada keselamatan sistem itu sendiri. Berikut adalah perkara biasa yang berlaku dan langkah-langkah untuk mengatasinya.

#1 Jangan, jangan dan jangan sesekali mempercayai pengguna

Sememangnya kita perlu sedar bahasa jangan sesekali atau terlalu mempercayai pengguna menghantar sesuatu data yang dalam jangkaan. Letakkan ke tepi tanggapan lapuk kita ini kerana walaupun tiada pengguna yang berniat untuk melakukan perkara yang akan menjejaskan sesuatu sistem, namun kesilapan secara tidak sengaja boleh berlaku.

Global variables

Dalam kebanyakan pengaturcaraan, kita selalu menggunakan pembolehubah bagi memudahkan sebarang urusan. Dalam PHP, terdapat satu pilihan iaitu "register_globals" yang boleh diset di dalam php.ini untuk membenarkan setiap satu pembolehubah digunakan secara global.

Perhatikan kepada kod aturcara ini:

if ($password == "my_password") {
    $authorized = 1;
}

if ($authorized == 1) {
    echo "Banyak perkara sulit berada di sini.";
}

Kod di atas kelihatan biasa sahaja bagi kebanyakan pengguna dan fakta mengesahkan ianya digunakan pada kebanyakan sistem laman web. Walau bagaimanapun, sekiranya pelayan tersebut mengaktifkan penggunaan register_globals, maka kita boleh masukkan arahan ?authorized=1 pada alamat URL. Seterusnya ia akan memaparkan maklumat dan perkara sulit yang tidak sepatutnya dipaparkan kepada umum.

Terdapat cara yang mudah kes seperti ini iaitu memastikan bahawa register_globals dimatikan atau diset kepada off. Yang kedua adalah menggunakan pemboleh ubah yang nilainya hanya diketahui dan ditentukan oleh kita sendiri. Sebagai contoh, kita tambahkan $authorized = 0 pada permulaan skrip:

$authorized = 0;
if ($password == "my_password") {
    $authorized = "nilai_sendiri";
}

if ($authorized == "nilai_sendiri") {
    echo "Banyak perkara sulit berada di sini.";
}

Mesej ralat

Mesej ralat merupakan alatan yang sangat berguna kepada pembangun dan pengodam. Pembangun memerlukan bagi mengesan dan membaik pulih sebarang ralat yang berlaku. Manakala pengodam menggunakannya sebagai jalan untuk mengumpul dan mendapatkan seberapa banyak maklumat sulit mengenai sistem kita termasuklah sistem fail, struktur pangkalan data dan maklumat spesifikasi pelayan.

PHP boleh diarahkan untuk menyahaktifkan perekodan dan pemaparan semua ralat menerusi .htaccess atau php.ini dengan setkan konfigurasi error_reporting kepada 0. Pada waktu pembangunan, gunakan alternatif lain bagi perekodan ralat ini.

SQL Injection

Salah satu kekuatan PHP adalah keupayaannya untuk berinteraksi dan berkomunikasi dengan pangkalan data, yang selalunya adalah MySQL. Banyak pembangun yang menggunakan sepenuhnya kelebihan ini, tidak ketinggalan laman web yang hebat-hebat termasuk Kripkorn Studios sendiri yang bergantung sepenuhnya kepada pangkalan data.

Perkara lazim yang mengancam keselamatan pangkalan data adalah SQL Injection (rujuk artikel: SQL Injection) apabila wujudnya interaksi dengan pangkalan data. Pengodam berupaya untuk menjalankan kueri yang mengancam maklumat dan data terus ke dalam pangkalan data.

Sebagai contoh, kita lihat kepada baris kod yang mengendali proses pendaftaran log masuk yang memeriksa nama pengguna dan kata laluan daripada borang yang disediakan. Kod di bawah menunjukkan proses pengesahan ke ruangan pentadbiran laman:

$check = mysql_query("SELECT Username, Password, UserLevel FROM Users WHERE Username = '".$_POST['username']."' and Password = '".$_POST['password']."'");

Kod tersebut sangat biasa bukan? Tetapi tidak berhenti di situ. Sekiranya saya masukkan arahan kod pada ruang medan nama pengguna dalam borang log masuk seperti di bawah ini:

' OR 1=1 #

Kueri yang akan dijalankan oleh sistem diterjemahkan seperti berikut:

SELECT Username, Password FROM Users WHERE Username = '' OR 1=1 #' and Password = ''

Simbol hash (#) memberitahu MySQL bahawa semua baris kod yang diikuti selepasnya adalah satu komen dan abaikannya. Jadi apa yang berlaku SQL hanya dijalan kueri sehingga poin sebelum simbol hash. Disebabkan oleh 1 adalah sentiasa sama dengan 1, SQL akan menghantar semua nama pengguna dan kata laluan daripada pangkalan data.

Kebiasaanya akaun untuk pentadbir adalah selalunya akaun yang pertama dihasilkan, pengodam akan menggunakan maklumat tersebut dan log masuk kembali ke dalam sistem sebagai pentadbiran dan mendapat semua kebenaran dan kuasa mengendalikan sistem.

Antara langkah untuk mengatasi masalah ini adalah dengan meneutralkan semua simbol-simbol sebelum ianya dihantar ke dalam pangkalan data untuk diproses. Kod tersebut adalah seperti berikut:

function make_safe($variable) {
    $variable = mysql_real_escape_string(trim($variable));
    return $variable;
}

Sekarang, kita lakukan modifikasi terhadap kod sebelum ini. Berbanding menggunakan terus pembolehubah $_POST, kita jalankan proses tapisan terlebih dahulu dalam fungsi make_safe dengan kod seperti di bawah:

$username = make_safe($_POST['username']);
$password = make_safe($_POST['password']);
$check = mysql_query("SELECT Username, Password, UserLevel FROM Users WHERE Username = '".$username."' and Password = '".$password."'");

Sekarang, seandainya suntikan yang sama dilakukan sebelum ini, kueri yang akan dijalankan langsung tidak mengancam sistem. Apa yang akan diterjemahkan pada suntikan menjadi \' OR 1=1 #.

SELECT Username, Password, UserLevel FROM Users WHERE Username = '\' OR 1=1 #' and Password = ''

Sekarang seandainya pengodam menggunakan teknik yang sama, apa yang dipaparkan kepadanya hanyalah skrin kosong. Tersangatlah penting untuk memeriksa semua data-data sebelum ianya dilepaskan ke dalam pangkalan data.

Manipulasi fail

Sesetengah laman web sekarang menjalankan operasi dan kod seperti di bawah:

index.php?page=contactus.html

Apa yang berlaku adalah fail index.php memanggil fail contactus.html ke dalam paparannya dan ia berjalan tanpa sebarang masalah. Walau bagaimanapun ia membenarkan pengguna untuk mengubah contactus.html ke sebarang fail yang diingini. Sebagai contoh, seandainya kita menggunakan Apache mod_auth untuk melindungi fail-fail penting contohnya fail .htpasswd bagi menyimpan kata laluan, maka mereka berupaya untuk mendapatkan maklumat tersebut dengan arahan:

index.php?page=.htpasswd

Dengan melakukan modifikasi terhadap URL, dalam sesetengah sistem, mereka akan menghala haluan sistem sedia ada untuk menjalankan atau membaca fail daripada lokasi pelayan yang berlainan. Yang mana fail yang dihalakan mengandungi kod-kod dan skrip yang ditulis sendiri untuk dijalankan pada pelayan kita.

Menakutkan bukan? Pertama, pastikan kita meletakkan konfigurasi open_basedir di dalam php.ini serta setkan allow_url_fopen kepada off. Dengan cara ini kita menghalang fail luaran daripada pelayan dipanggil dan dibaca. Tambahan kita perlu memastikan hanya fail-fail yang sah dan diketahui sahaja dipanggil ke dalam sistem.

Penggunaan nilai secara lalai (default)

Semasa pemasangan MySQL, ia akan menetapkan nama pengguna secara lalai kepada "root" dan tanpa kata laluan. Pelayan SQL pula menggunakan "sa" sebagai nama pengguna dan tiada kata laluan. Sekiranya kita belum lagi menetapkan nama pengguna dan kata laluan yang berlainan daripada yang asal, besar kemungkinan maklumat dan data-data anda dicuri dan hilang pada keesokan pagi.

Ia merupakan tips mudah dan diaplikasikan kepada semua perisian. Ubah dan tukar kata nama serta kata laluan yang asal kepada yang berlainan dan sukar untuk dikenal pasti.

Meninggalkan fail pemasangan

Banyak program dan perisian PHP didatangkan bersama dengan fail pemasangan. Selalunya ia dilengkapi dengan arahan untuk dihapuskan secara automatis apabila pernah dilaksanakan. Tetapi masalah dari kebenaran kadang kala menyebabkan fail-fail pemasangan tidak dihapuskan dan masih berada di dalam pelayan. Ini boleh mengundang risiko di mana pengguna mampu untuk menjalankannya sekali lagi.

Mudah diteka

Letakkan diri kira sebagai seorang pengodam. Seandainya saya ingin melakukan satu ancaman terdapat sistem sedia ada, tanggapan mudah terhadap akses ke ruangan pentadbiran adalah dengan menaip URL http://www.example.com/admin (sekiranya ianya wujud). Berkemungkinan besar direktori ini mengandungi fail-fail sulit yang mengawal ke seluruhan sistem.

Sama juga dalam kes penggunaan nama pengguna dan kata laluan yang terlalu biasa dan mudah diteka seperti admin atau administer dan administrator. Gunakan nama atau frasa yang lebih sukar untuk diketahui dan tidak menggunakan norma-norma yang biasa digunakan. Amalkan mengubah kata laluan secara berkala bagi mengelakkan ianya terlalu mudah untuk dikesan.

Penilaian: 
3
Average: 2.5 (2 votes)

Komen

SoLarIZe's picture

Untuk Manipulasi fail, seperti yang telah ditunjuk diatas, adakah lebih elok sekiranya menggunakan mor_rewrite utk mengubah url yang sedia ada spt www.example.com/about.php?user=3&type=boardofdirector kepada www.example.com/about/user/3/boardofdirector

parasolx's picture
Admin

Salam, mod_rewrite digunakan untuk menulis atau mengubah bentuk URL dipaparkan. Dalam kes manipulasi fail, kita nak block daripada user untuk include file luar daripada server kita. Dalam kes mod_rewrite, sekiranya kita biarkan open_basedir dan allow_url_fopen dibuka, user still boleh includekan file luaran walaupun dengan mod_rewrite.

------

Hadafi Solution & Resources: http://parasolx.net
Professional in Drupal web development, theme designing, consultation and training