En son web geliştirme öğreticiler
 

SQL Enjeksiyon


Bir SQL Injection veritabanınızı yok edebilir.


Web Sayfaları SQL

Önceki bölümlerde yeniden alma öğrendik (and update) SQL kullanarak, veritabanı verilerini.

SQL bir web sayfasındaki verileri görüntülemek için kullanıldığında, web kullanıcılarının giriş kendi arama değerlerini bildirmek için yaygındır.

SQL ifadeleri metin olduğundan sadece, dinamik seçilen verilerle kullanım sağlamak için SQL ifadelerini değiştirmeye, bilgisayar küçük bir kod parçası ile, kolaydır:

Sunucu Kodu

txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = " + txtUserId;

Yukarıdaki örnekte, bir değişken ekleyerek seçme deyimini oluşturur (txtUserId) seçilmiş bir dizeye. Değişken kullanıcı girişi olarak getirildiğinden, (Request) sayfasına.

Bu bölümün geri kalanı SQL ifadelerinde kullanıcı girişi kullanmanın potansiyel tehlikeleri açıklar.


SQL Injection

SQL enjeksiyon kötü niyetli kullanıcıların web sayfası girişi üzerinden, SQL deyimine SQL komutları ekleyebilir bir tekniktir.

Enjekte SQL komutlarının SQL deyimi değiştirebilir ve bir web uygulaması güvenliğini tehlikeye atabilir.


1 = 1 dayanarak SQL Injection Daima Doğru

Yukarıdaki örnekte de bir kez daha bak.

kodunun orijinal amacı belirli bir kullanıcı kimliği ile bir kullanıcıyı seçmek için bir SQL deyimi yaratmak olduğunu varsayalım.

Girmesini önlemek için bunu bir şey yoksa "wrong" girişi, kullanıcı bazı girebilir "smart" böyle girdi:

Kullanıcı adı:

Sunucu Sonucu

SELECT * FROM Users WHERE UserId = 105 or 1=1

SQL yukarıdaki geçerlidir. 1 = 1 her zaman doğrudur NEREDE, çünkü tablo Kullanıcılar'dan tüm satırları döndürür.

Yukarıdaki örnek mu tehlikeli görünüyor? Ne Kullanıcılar tablo adları ve parolalar içeriyorsa?

Yukarıdaki SQL deyimi bu kadar aynıdır:

SELECT UserId, Name, Password FROM Users WHERE UserId = 105 or 1=1

Bir akıllı korsan basitçe giriş kutusuna 105 veya 1 = 1 ekleyerek bir veritabanında tüm kullanıcı adları ve şifreleri erişmek olabilir.


Dayanarak SQL Injection ""="" Her zaman True

İşte bir web sitesine kullanıcı girişi doğrulamak için kullanılan ortak bir inşaat şöyledir:

Kullanıcı adı:

Parola:

Sunucu Kodu

uName = getRequestString("UserName");
uPass = getRequestString("UserPass");

sql = "SELECT * FROM Users WHERE Name ='" + uName + "' AND Pass ='" + uPass + "'"

Bir akıllı korsan basitçe ekleme "veya bir veritabanında kullanıcı adları ve şifreleri erişmek olabilir ""=" içine kullanıcı adı veya şifre metin kutusu.

sunucuda kodu şöyle geçerli bir SQL deyimi oluşturur:

Sonuç

SELECT * FROM Users WHERE Name ="" or ""="" AND Pass ="" or ""=""

Sonuç SQL geçerlidir. "" = "" Her zaman doğrudur NEREDE, çünkü tablo Kullanıcılar'dan tüm satırları döndürür.


Dok SQL deyimleri dayanarak SQL Injection

Çoğu veritabanları noktalı virgülle ayrılmış toplu iş SQL deyimi destekler.

Örnek

SELECT * FROM Users; DROP TABLE Suppliers

SQL yukarıdaki Kullanıcılar tablosundaki tüm satırları döndürür ve sonra masayı denilen Tedarikçi silin.

Biz aşağıdaki sunucu kodu olsaydı:

Sunucu Kodu

txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = " + txtUserId;

Ve aşağıdaki girişi:

Kullanıcı adı:

sunucuda kodu şöyle geçerli bir SQL deyimi yaratacak:

Sonuç

SELECT * FROM Users WHERE UserId = 105; DROP TABLE Suppliers

Koruma Parametreleri

Bazı web geliştiricileri bir kullanma "blacklist" SQL enjeksiyon saldırıları önlemek için SQL girişinde aramak için kelime veya karakter.

Bu çok iyi bir fikir değildir. Bu kelimelerin çoğu (like delete or drop) ve karakterler (like semicolons and quotation marks) , ortak dilde kullanılır ve girdi birçok çeşit izin verilmelidir.

(Aslında bu giriş veritabanı alanında bir SQL deyimi için tamamen yasal olmalıdır.)

SQL enjeksiyon saldırıları bir web sitesini korumak için kanıtlanmış tek yolu, SQL parametreleri kullanmaktır.

SQL parametreler, kontrollü bir şekilde, yürütülmesi sırasında bir SQL sorgusu eklenir değerlerdir.

ASP.NET Jilet Örneği

txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = @0";
db.Execute(txtSQL,txtUserId);

parametreler @ işareti ile SQL deyiminde temsil unutmayın.

SQL motoru onun sütun için doğru ve tam anlamıyla tedavi edilir ve SQL parçası yürütülecek değil emin olmak için her bir parametre 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);

Sadece SQL enjeksiyon önlemek için öğrendik. Üst web sitesi açıkları biri.


Örnekler

Aşağıdaki örnekler bazı ortak web dillerinde parametreli sorguları nasıl oluşturulacağını gösterir.

ASP.NET İÇİNDE SEÇ TABLOSU:

txtUserId = getRequestString("UserId");
sql = "SELECT * FROM Customers WHERE CustomerId = @0";
command = new SqlCommand(sql);
command.Parameters.AddWithValue("@0",txtUserID);
command.ExecuteReader();

ASP.NET İÇİNDE TABLOSU: INSERT INTO

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 İÇİNDE TABLOSU: INSERT INTO

$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();