SQL Enjeksiyonu
SQL Enjeksiyonu
SQL enjeksiyonu, veritabanınızı yok edebilecek bir kod enjeksiyon tekniğidir.
SQL enjeksiyonu, en yaygın web hackleme tekniklerinden biridir.
SQL enjeksiyonu, kötü amaçlı kodun SQL ifadelerine web sayfası girişi yoluyla yerleştirilmesidir.
Web Sayfalarında SQL
SQL enjeksiyonu genellikle bir kullanıcıdan kullanıcı adı/kullanıcı kimliği gibi bir girdi istediğinizde gerçekleşir ve bir ad/kimlik yerine kullanıcı size bilmeden veritabanınızda çalıştıracağınız bir SQL ifadesi verir.
SELECT
Bir seçme dizesine bir değişken (txtUserId) ekleyerek bir ifade oluşturan aşağıdaki örneğe bakın . Değişken, kullanıcı girişinden alınır (getRequestString):
Örnek
txtUserId = getRequestString("UserId");
txtSQL = "SELECT *
FROM Users WHERE UserId = " + txtUserId;
Bu bölümün geri kalanında, SQL deyimlerinde kullanıcı girdisi kullanmanın olası tehlikeleri açıklanmaktadır.
1=1'e Dayalı SQL Enjeksiyonu Her Zaman Doğrudur
Yukarıdaki örneğe tekrar bakın. Kodun asıl amacı, belirli bir kullanıcı kimliğine sahip bir kullanıcıyı seçmek için bir SQL ifadesi oluşturmaktı.
Bir kullanıcının "yanlış" girdi girmesini engelleyecek hiçbir şey yoksa, kullanıcı şöyle bir "akıllı" girdi girebilir:
Kullanıcı kimliği:
Ardından, SQL ifadesi şöyle görünecektir:
SELECT * FROM Users WHERE UserId = 105 OR 1=1;
Yukarıdaki SQL geçerlidir ve VEYA 1=1 her zaman DOĞRU olduğundan, "Kullanıcılar" tablosundaki TÜM satırları döndürür.
Yukarıdaki örnek tehlikeli görünüyor mu? "Kullanıcılar" tablosu adlar ve şifreler içeriyorsa ne olur?
Yukarıdaki SQL ifadesi şuna çok benzer:
SELECT UserId, Name, Password
FROM Users WHERE UserId = 105 or 1=1;
Bir bilgisayar korsanı, giriş alanına 105 VEYA 1=1 girerek bir veritabanındaki tüm kullanıcı adlarına ve parolalara erişebilir.
""="" Temelli SQL Enjeksiyonu Her Zaman Doğrudur
Bir web sitesinde bir kullanıcı oturum açma örneği:
Kullanıcı adı:
Parola:
Örnek
uName = getRequestString("username");
uPass = getRequestString("userpassword");
sql = 'SELECT * FROM Users WHERE Name ="' + uName + '" AND Pass ="' + uPass +
'"'
Sonuç
SELECT * FROM Users WHERE Name ="John Doe" AND Pass ="myPass"
Bir bilgisayar korsanı, yalnızca kullanıcı adı veya parola metin kutusuna " VEYA ""=" ekleyerek bir veritabanındaki kullanıcı adlarına ve parolalara erişebilir:
Kullanıcı adı:
Parola:
Sunucudaki kod, aşağıdaki gibi geçerli bir SQL ifadesi oluşturacaktır:
Sonuç
SELECT * FROM Users WHERE Name ="" or ""="" AND Pass ="" or ""=""
Yukarıdaki SQL geçerlidir ve VEYA ""="" her zaman DOĞRU olduğundan, "Kullanıcılar" tablosundaki tüm satırları döndürür.
Toplu SQL İfadelerine Dayalı SQL Enjeksiyonu
Çoğu veritabanı toplu SQL deyimini destekler.
Toplu SQL ifadeleri, noktalı virgülle ayrılmış iki veya daha fazla SQL ifadesinden oluşan bir gruptur.
Aşağıdaki SQL ifadesi, "Kullanıcılar" tablosundaki tüm satırları döndürecek ve ardından "Tedarikçiler" tablosunu silecektir.
Örnek
SELECT * FROM Users; DROP TABLE Suppliers
Aşağıdaki örneğe bakın:
Örnek
txtUserId = getRequestString("UserId");
txtSQL = "SELECT *
FROM Users WHERE UserId = " + txtUserId;
Ve aşağıdaki giriş:
Kullanıcı kimliği:
Geçerli SQL ifadesi şöyle görünür:
Sonuç
SELECT * FROM Users WHERE
UserId = 105; DROP TABLE Suppliers;
Koruma için SQL Parametrelerini Kullanın
Bir web sitesini SQL enjeksiyonundan korumak için SQL parametrelerini kullanabilirsiniz.
SQL parametreleri, bir SQL sorgusuna yürütme sırasında kontrollü bir şekilde eklenen değerlerdir.
ASP.NET Razor Örneği
txtUserId = getRequestString("UserId");
txtSQL = "SELECT *
FROM Users WHERE UserId = @0";
db.Execute(txtSQL,txtUserId);
Parametrelerin SQL deyiminde bir @ işaretiyle temsil edildiğine dikkat edin.
SQL motoru, kendi sütunu için doğru olduğundan ve yürütülecek SQL'in bir parçası olarak değil, tam anlamıyla ele alındığından emin olmak için her parametreyi kontrol eder.
Başka bir örnek
txtNam = getRequestString("CustomerName");
txtAdd = getRequestString("Address");
txtCit = getRequestString("City");
txtSQL = "INSERT INTO Customers (CustomerName,Address,City) Values(@0,@1,@2)";
db.Execute(txtSQL,txtNam,txtAdd,txtCit);
Örnekler
Aşağıdaki örnekler, bazı yaygın web dillerinde parametreli sorguların nasıl oluşturulacağını gösterir.
ASP.NET'TE BİLDİRİM SEÇİN:
txtUserId = getRequestString("UserId");
sql = "SELECT * FROM Customers WHERE CustomerId = @0";
command = new SqlCommand(sql);
command.Parameters.AddWithValue("@0",txtUserId);
command.ExecuteReader();
ASP.NET'TE BİLDİRİME EKLE:
txtNam = getRequestString("CustomerName");
txtAdd = getRequestString("Address");
txtCit = getRequestString("City");
txtSQL = "INSERT INTO Customers (CustomerName,Address,City) Values(@0,@1,@2)";
command = new SqlCommand(txtSQL);
command.Parameters.AddWithValue("@0",txtNam);
command.Parameters.AddWithValue("@1",txtAdd);
command.Parameters.AddWithValue("@2",txtCit);
command.ExecuteNonQuery();
PHP'DE BİLDİRİME EKLE:
$stmt = $dbh->prepare("INSERT INTO Customers (CustomerName,Address,City)
VALUES (:nam, :add, :cit)");
$stmt->bindParam(':nam', $txtNam);
$stmt->bindParam(':add', $txtAdd);
$stmt->bindParam(':cit', $txtCit);
$stmt->execute();