TL; DR
- Uygulama girişimi kabul eder, bu durumda 'Nancy', denemeden
- özel karakterlerden kaçmak gibi girdiyi sterilize edin- özel karakterlerden kaçmak gibi girdiyi sterilize edin
okul => Öğrencilerin DEĞERLERİNE EKLE ('Nancy');=> INSERT INTO öğrencilerin DEĞERLER ( 'Nancy' );
INSERT 0 1INSERT 0 1
- SQL enjeksiyonu, bir veritabanı komutuna giriş,- SQL enjeksiyonu, bir veritabanı komutuna giriş,
- veritabanı sunucusunun rastgele SQL çalıştırmasına neden olur- veritabanı sunucusunun rastgele SQL çalıştırmasına neden olur
okul => Öğrencilerin DEĞERLERİNE EKLE ('Robert'); DROP TABLO öğrencileri; - ');=> INSERT INTO öğrencilerin DEĞERLER ( 'Robert' ); DROP TABLO öğrencileri ; - ');
INSERT 0 1INSERT 0 1
DÜŞME TABLOSUDÜŞME TABLOSU
- Öğrenci kayıtları artık bitti - daha da kötü olabilirdi!- Öğrenci kayıtları artık bitti - daha da kötü olabilirdi!
okul => SEÇ * öğrencilerden;=> SEÇ * DAN öğrenciler ;
HATA: "öğrenciler" ilişkisi mevcut değil: İlişkisi "öğrenciler" does not var
LINE 1: Öğrencilerden SELECT *;1 : SEÇİN * GELEN öğrenciler ;
^^
Bu, öğrenci masasını düşürür (siler).
( Bu yanıttaki tüm kod örnekleri bir PostgreSQL 9.1.2 veritabanı sunucusunda çalıştırılmıştır. )
Neler olduğunu netleştirmek için, bunu yalnızca ad alanını içeren basit bir tabloyla deneyelim ve tek bir satır ekleyelim:
okul => TABLO öğrencileri OLUŞTUR (adı METİN PRİMER ANAHTARI);=> TABLO öğrencileri OLUŞTUR ( adı METİN PRİMER ANAHTARI );
DİKKAT: CREATE TABLE / PRIMARY KEY, "öğrenciler" tablosu için örtük dizin "students_pkey" oluşturur: CREATE TABLE / İLKÖĞRETİM KEY olacak oluşturmak örtülü endeksi "students_pkey" için tablo "öğrenci"
TABLO OLUŞTURTABLO OLUŞTUR
okul => Öğrencilerin DEĞERLERİNE EKLE ('John');=> INSERT INTO öğrencilerin DEĞERLER ( John ' );
INSERT 0 1INSERT 0 1
Uygulamanın tabloya veri eklemek için aşağıdaki SQL'i kullandığını varsayalım:
INSERT INTO öğrencilerin DEĞERLER ( 'filanca' );
foobar
Öğrencinin gerçek adıyla değiştirin . Normal bir takma işlemi şöyle görünecektir:
- Giriş: Nancy
okul => INSERT INTO öğrencilerin DEĞERLER ( 'Nancy' ); INSERT 0 1
Tabloyu sorguladığımızda şunu elde ederiz:
Okul => SEÇ * DAN öğrenciler ;
isim
-------
John
Nancy
( 2 sıra )
Küçük Bobby Tables'ın adını masaya eklediğimizde ne olur?
- Girdi: Robert '); DROP TABLO öğrencileri; -
Okul => INSERT INTO öğrencilerin DEĞERLER ( 'Robert' ); DROP TABLO öğrencileri ; - '); INSERT 0 1 DÜŞME TABLOSU
Buradaki SQL enjeksiyonu, ifadeyi sonlandıran ve ayrı bir DROP TABLE
komut içeren öğrencinin adının sonucudur ; girişin sonundaki iki tire, aksi takdirde hataya neden olan kalan kodları yorumlamak üzere tasarlanmıştır. Çıktının son satırı, veritabanı sunucusunun tabloyu bıraktığını doğrular.
INSERT
İşlem sırasında uygulamanın herhangi bir özel karakter için girişi denetlemediğini ve bu nedenle SQL komutuna rastgele giriş girilmesine izin verdiğini fark etmek önemlidir. Bu, kötü niyetli bir kullanıcının, normalde kullanıcı girişi için amaçlanan bir alana, veritabanı sisteminin çalıştırmasını sağlamak için rastgele SQL koduyla birlikte tırnak işaretleri gibi özel simgeler, dolayısıyla SQL enjeksiyonu ekleyebileceği anlamına gelir .
Sonuç?
Okul => SEÇ * DAN öğrenciler ;
HATA : ilişkisi "öğrenciler" yok değil var
SATIR 1 : SEÇİN * GELEN öğrenciler ; ^
SQL yerleştirme , bir işletim sistemindeki veya uygulamadaki uzaktan rasgele kod yürütme güvenlik açığına eşdeğer veritabanıdır . Başarılı bir SQL enjeksiyon saldırısının potansiyel etkisi göz ardı edilemez - veritabanı sistemine ve uygulama yapılandırmasına bağlı olarak, bir saldırgan tarafından veri kaybına (bu durumda olduğu gibi) neden olmak, verilere yetkisiz erişim sağlamak ve hatta yürütmek için kullanılabilir ana makinenin kendisinde rastgele kod.
XKCD çizgi romanının belirttiği gibi, SQL enjeksiyon saldırılarına karşı korunmanın bir yolu, altta yatan SQL komutunu değiştirememeleri ve dolayısıyla keyfi SQL kodunun yürütülmesine neden olmaması için özel karakterlerden kaçmak gibi veritabanı girişlerini sterilize etmektir. SqlParameter
ADO.NET'te kullanmak gibi parametreli sorgular kullanırsanız , giriş en azından SQL enjeksiyonuna karşı koruma sağlamak için otomatik olarak sterilize edilir.
Ancak, girdileri uygulama düzeyinde dezenfekte etmek daha gelişmiş SQL enjeksiyon tekniklerini durduramayabilir. Örneğin , mysql_real_escape_string
PHP işlevini atlatmanın yolları vardır . Ek koruma için, birçok veritabanı sistemi hazırlanmış ifadeleri destekler . Arka uçta düzgün bir şekilde uygulanırsa, hazırlanan ifadeler veri girişlerini komutun geri kalanından anlamsal olarak ayrı tutarak SQL enjeksiyonunu imkansız hale getirebilir.