SQL - Enjeksiyon
Bir web sayfası üzerinden bir kullanıcı girdisi alır ve bunu bir SQL 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 PERL Komut Dosyası gibi sunucu tarafı komut dosyalarınızda komut dosyalarınızı ve SQL ifadelerinizi güvenli hale getirmenize yardımcı olacaktır.
Enjeksiyon genellikle, bir kullanıcıdan adı gibi bir girdi istediğinizde ve bir isim yerine size bilmeden veritabanınızda çalıştıracağınız bir SQL ifadesi verdiğinizde gerçekleşir. Kullanıcı tarafından sağlanan verilere asla güvenmeyin, bu verileri yalnızca doğrulamadan sonra işleyin; kural olarak, bu şu şekilde yapılır:Pattern Matching.
Aşağıdaki örnekte, name alfanümerik karakterler artı alt çizgi ve 8 ila 20 karakter arası bir uzunlukla sınırlıdır (bu kuralları gerektiği gibi değiştirin).
if (preg_match("/^\w{8,20}$/", $_GET['username'], $matches)) {
$result = mysql_query("SELECT * FROM CUSTOMERS
WHERE name = $matches[0]");
} else {
echo "user name not accepted";
}
Sorunu göstermek için bu alıntıyı düşünün -
// supposed input
$name = "Qadir'; DELETE FROM CUSTOMERS;";
mysql_query("SELECT * FROM CUSTOMSRS WHERE name='{$name}'");
İşlev çağrısının, CUSTOMERS tablosundan, ad sütununun kullanıcı tarafından belirtilen adla eşleştiği bir kaydı alması beklenir. Normal şartlar altında,$nameyalnızca alfanümerik karakterler ve belki de ilia dizesi gibi boşluklar içerebilir. Ama burada, $ name'e tamamen yeni bir sorgu ekleyerek, veritabanına yapılan çağrı felakete dönüşüyor; enjekte edilen DELETE sorgusu, MÜŞTERİLER tablosundaki tüm kayıtları kaldırır.
Neyse ki, MySQL kullanıyorsanız, mysql_query()işlevi, tek bir işlev çağrısında birden çok SQL sorgusunun istiflenmesine 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 CUSTOMERS WHERE name='{$name}'");
GİBİ İkilemi
LIKE çıkmazını 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("%str"), "%_");
// $sub == \%str\_
mysql_query("SELECT * FROM messages
WHERE subject LIKE '{$sub}%'");