MySQL - ve SQL Enjeksiyonu

Bir web sayfası üzerinden kullanıcı girdisi alır ve bunu bir MySQL veritabanına eklerseniz, bir güvenlik sorunu için kendinizi tamamen açık bırakmış olabilirsiniz. SQL Injection. Bu bölüm size bunun olmasını nasıl engelleyeceğinizi öğretecek ve komut dosyalarınızı ve MySQL ifadelerinizi güvenli hale getirmenize yardımcı olacaktır.

SQL Enjeksiyonu genellikle bir kullanıcıdan adı gibi bir girdi istediğinizde oluşur ve bir isim yerine size bilmeden veritabanınızda çalıştıracağınız bir MySQL ifadesi verir.

Bir kullanıcı tarafından sağlanan verilere asla güvenmeyin, bu verileri yalnızca doğrulamadan sonra işleyin; kural olarak bu, örüntü eşleştirmesi ile yapılır. Aşağıdaki örnekte, kullanıcı adı alfasayısal karakterler artı alt çizgi ve 8 ila 20 karakter arasındaki bir uzunlukla sınırlandırılmıştır - bu kuralları gerektiği gibi değiştirin.

if (preg_match("/^\w{8,20}$/", $_GET['username'], $matches)) {
   $result = mysql_query("SELECT * FROM users WHERE username = $matches[0]");
} else  {
   echo "username not accepted";
}

Bu sorunu göstermek için aşağıdaki alıntıyı düşünün.

// supposed input
$name = "Qadir'; DELETE FROM users;";
mysql_query("SELECT * FROM users WHERE name = '{$name}'");

İşlev çağrısının, kullanıcı tablosundan, ad sütununun kullanıcı tarafından belirtilen adla eşleştiği bir kaydı alması beklenir. Normal şartlar altında, $ isim sadece alfanümerik karakterler ve belki boşluklar içerecektir. Ancak burada, tamamen yeni bir sorgu ekleyerek$nameveritabanına yapılan çağrı bir felakete dönüşür. Enjekte edilen DELETE sorgusu, tüm kayıtları kullanıcılardan kaldırır.

Neyse ki, MySQL kullanıyorsanız, mysql_query()işlev, tek bir işlev çağrısında birden çok sorgunun yığınlanmasına veya yürütülmesine izin vermez. Sorguları yığınlamaya çalışırsanız, çağrı başarısız olur.

Ancak, diğer PHP veritabanı uzantıları, örneğin SQLite ve PostgreSQL, mutlu bir şekilde yığılmış sorgular gerçekleştirin, tek bir dizede sağlanan tüm sorguları yürütün ve ciddi bir güvenlik sorunu yaratın.

SQL Enjeksiyonunu Önleme

PERL ve PHP gibi komut dosyası dillerinde tüm kaçış karakterlerini akıllıca işleyebilirsiniz. PHP için MySQL uzantısı şu işlevi sağlar:mysql_real_escape_string() MySQL'e özel giriş karakterlerinden çıkış yapmak için.

if (get_magic_quotes_gpc()) {
   $name = stripslashes($name);
}

$name = mysql_real_escape_string($name);
mysql_query("SELECT * FROM users WHERE name = '{$name}'");

GİBİ İkilemi

LIKE sorgusunu ele almak için, özel bir kaçış mekanizmasının kullanıcı tarafından sağlanan% ve _ karakterlerini değişmez değerlere dönüştürmesi gerekir. Kullanımaddcslashes(), kaçış için bir karakter aralığı belirlemenizi sağlayan bir işlev.

$sub = addcslashes(mysql_real_escape_string("%something_"), "%_");
// $sub == \%something\_
mysql_query("SELECT * FROM messages WHERE subject LIKE '{$sub}%'");