Diğer cevaplar zaten bilmeniz gerekenleri kapsıyor. Ama belki biraz daha netleştirmeye yardımcı olur:
Orada İKİ ŞEY yapmanız gereken:
1. Form verilerini doğrulayın.
As Jonathan Hobbs'un cevabı gösterileri çok net form girişi için html elemanı seçimi sizin için herhangi güvenilir filtreleme yapmaz.
Doğrulama genellikle verileri değiştirmeyecek, ancak "Lütfen bunu düzeltin" olarak işaretlenmiş alanlarla formu tekrar gösterecek şekilde yapılır.
Çoğu çerçeve ve CMS'de bu görevde size yardımcı olan form oluşturucular bulunur. Ve sadece bu değil, aynı zamanda başka bir saldırı türü olan CSRF'ye (veya "XSRF") karşı da yardımcı olurlar.
2. SQL ifadelerindeki değişkenleri temizle / kaldır ..
.. veya hazırlanmış ifadelerin sizin için işi yapmasına izin verin.
Kullanıcı tarafından sağlanan veya sağlanmayan herhangi bir değişkenle bir (My) SQL ifadesi oluşturursanız, bu değişkenlerden çıkış yapmanız ve bu değişkenlerden alıntı yapmanız gerekir.
Genel olarak, bir MySQL ifadesine eklediğiniz bu tür herhangi bir değişken ya bir dizge ya da PHP'nin MySQL'in sindirebileceği bir dizeye güvenilir bir şekilde dönüştürülebileceği bir şey olmalıdır. Sayılar gibi.
Dizeler için, dizeden kaçmak için birkaç yöntemden birini seçmeniz gerekir, yani MySQL'de yan etkileri olabilecek karakterleri değiştirin.
- Eski usul MySQL + PHP'de, mysql_real_escape_string () işi yapar. Sorun, unutmanın çok kolay olmasıdır, bu nedenle kesinlikle hazırlanmış ifadeler veya sorgu oluşturucular kullanmalısınız.
- MySQLi'de hazırlanmış ifadeleri kullanabilirsiniz.
- Çoğu çerçeve ve CMS, bu görevde size yardımcı olan sorgu oluşturucular sağlar.
Bir sayı ile uğraşıyorsanız, kaçışları ve tırnak işaretlerini atlayabilirsiniz (bu nedenle hazırlanan ifadeler bir tür belirtmeye izin verir).
SQL ifadesi için değişkenlerden kaçtığınızı ve veritabanının kendisi için DEĞİLDİĞİNİZİ belirtmek önemlidir . Veritabanı orijinal dizeyi saklayacaktır, ancak ifadenin öncelenmiş bir sürüme ihtiyacı vardır.
Bunlardan birini atlarsanız ne olur?
Form doğrulamasını kullanmıyorsanız , ancak SQL girişinizi temizliyorsanız, her türlü kötü şey olduğunu görebilirsiniz, ancak SQL enjeksiyonunu görmezsiniz! (*)
İlk olarak, başvurunuzu planlamadığınız bir duruma alabilir. Örneğin, tüm kullanıcıların ortalama yaşını hesaplamak istiyorsanız, ancak bir kullanıcı yaş için "aljkdfaqer" verdiyse, hesaplamanız başarısız olacaktır.
İkinci olarak, göz önünde bulundurmanız gereken her türlü başka enjeksiyon saldırısı olabilir: Örneğin, kullanıcı girişi javascript veya başka şeyler içerebilir.
Veritabanında hala sorunlar olabilir: Örneğin, bir alan (veritabanı tablosu sütunu) 255 karakterle sınırlıysa ve dize bundan daha uzunsa. Veya alan yalnızca sayıları kabul ediyorsa ve bunun yerine sayısal olmayan bir dize kaydetmeye çalışıyorsanız. Ama bu "enjeksiyon" değil, sadece "uygulamanın çökmesi".
Ancak, hiçbir doğrulama olmadan herhangi bir girişe izin verdiğiniz serbest bir metin alanınız olsa bile, bir veritabanı ifadesine gittiğinde doğru şekilde çıkış yaparsanız, bunu yine de veritabanına kaydedebilirsiniz. Sorun, bu dizeyi bir yerde kullanmak istediğinizde ortaya çıkar.
(*) yoksa bu gerçekten egzotik bir şey olurdu.
SQL ifadeleri için değişkenlerden çıkış yapmazsanız , ancak form girişini doğruladıysanız, yine de kötü şeyler olduğunu görebilirsiniz.
İlk olarak, verileri veritabanına kaydettiğinizde ve tekrar yüklediğinizde, artık aynı veriler olmayacak, "çeviride kaybolacak" riskiyle karşı karşıyasınız.
İkinci olarak, geçersiz SQL ifadelerine neden olabilir ve bu nedenle uygulamanızı çökertebilir. Örneğin, herhangi bir değişken bir tırnak veya çift tırnak karakteri içeriyorsa, kullandığınız alıntı türüne bağlı olarak geçersiz MySQL ifadesi alırsınız.
Üçüncüsü, yine de SQL enjeksiyonuna neden olabilir.
Formlardan gelen kullanıcı girdiniz zaten filtrelenmiş / doğrulanmışsa, kasıtlı SQl yerleştirme olasılığı daha az olabilir, EĞER girişiniz sabit kodlu bir seçenekler listesine indirgenirse veya sayılarla sınırlıysa. Ancak, SQL ifadelerindeki değişkenlerden doğru şekilde çıkış yapmazsanız, herhangi bir serbest metin girişi SQL enjeksiyonu için kullanılabilir.
Ve hiç bir form girdiniz olmasa bile, her tür kaynaktan dizeleriniz olabilir: Dosya sisteminden okuyun, internetten kazınmış vs. Hiç kimse bu dizelerin güvenli olduğunu garanti edemez.
<select>
girişinizde dilediği değerleri göndermesini engellemez . Aslında biraz teknik bir kullanıcı bile tarayıcı konsolunu kullanarak ek seçenekler ekleyebilir. mevcut değerlerin bir dizi beyaz listesini tutar ve bununla girdiyi karşılaştırırsanız, bunu azaltabilirsiniz (ve istenmeyen değerleri engellediği için yapmanız gerekir)