Güvenlik Riskleri
Veritabanları genellikle hassas veriler içerir ve tehlikeli işlemlerin gerçekleştirilmesine izin verir. Nette Veritabanı ile güvenli çalışma için temel hususlar şunlardır:
- Güvenli ve güvensiz API arasındaki farkı anlama
- Parametrelendirilmiş sorguları kullanma
- Giriş verilerinin uygun şekilde doğrulanması
SQL Enjeksiyonu Nedir?
SQL enjeksiyonu, veritabanlarıyla çalışırken karşılaşılan en ciddi güvenlik riskidir. Filtrelenmemiş kullanıcı girdisi bir SQL sorgusunun parçası haline geldiğinde ortaya çıkar. Bir saldırgan kendi SQL komutlarını ekleyebilir ve böylece
- Yetkisiz verileri ayıklayın
- Veritabanındaki verileri değiştirme veya silme
- Kimlik doğrulamayı atla
Aynı durum Veritabanı Gezgini için de geçerlidir:
Güvenli Parametreli Sorgular
SQL sorgularına değer eklemenin güvenli yolu parametrelendirilmiş sorgulardır. Nette Veritabanı bunları kullanmak için çeşitli yollar sunar.
En basit yol soru işareti yer tutucuları kullanmaktır:
Bu, Veritabanı Gezgini 'nde soru işareti yer tutucuları ve parametreler içeren ifadelerin eklenmesine izin veren diğer tüm yöntemler için geçerlidir.
INSERT, UPDATE komutları veya WHERE cümleleri için değerleri bir dizi içinde güvenle aktarabiliriz:
Ancak, parametrelerin doğru veri türüne sahip olduğundan emin olmalıyız.
Dizi Anahtarları Güvenli API Değildir
Dizi değerleri güvenli olsa da, bu durum anahtarlar için geçerli değildir!
INSERT ve UPDATE komutları için bu büyük bir güvenlik açığıdır – bir saldırgan veritabanındaki herhangi bir
sütunu ekleyebilir veya değiştirebilir. Örneğin, is_admin = 1
adresini ayarlayabilir veya hassas sütunlara
rastgele veri ekleyebilirler (Toplu Atama Güvenlik Açığı olarak bilinir).
NEREDE koşullarında, operatör içerebildikleri için daha da tehlikelidir:
Bir saldırgan, çalışan maaşlarını sistematik olarak ortaya çıkarmak için bu yaklaşımı kullanabilir. Önce 100.000'in üzerindeki, sonra 50.000'in altındaki maaşlar için bir sorguyla başlayabilir ve aralığı kademeli olarak daraltarak tüm çalışanların yaklaşık maaşlarını ortaya çıkarabilirler. Bu saldırı türüne SQL numaralandırma adı verilir.
where()
yöntemi, anahtarlardaki operatörler ve fonksiyonlar dahil olmak üzere SQL ifadelerini destekler. Bu,
bir saldırgana karmaşık SQL enjeksiyonu gerçekleştirme olanağı verir:
Bu saldırı orijinal koşulu 0)
ile sonlandırır, UNION
kullanarak users
tablosundan
hassas verileri elde etmek için kendi SELECT
adresini ekler ve WHERE (1)
kullanarak sözdizimsel olarak
doğru bir sorgu ile kapatır.
Sütun Beyaz Listesi
Kullanıcıların sütun seçmesine izin vermek istiyorsanız, her zaman bir beyaz liste kullanın:
Girdi Verilerini Doğrulama
En önemli şey parametrelerin doğru veri türüne sahip olmasını sağlamaktır – bu Nette Veritabanının güvenli kullanımı için gerekli bir koşuldur. Veritabanı, tüm girdi verilerinin verilen sütuna karşılık gelen doğru veri türüne sahip olduğunu varsayar.
Örneğin, önceki örneklerde $name
bir dize yerine beklenmedik bir şekilde bir dizi olsaydı, Nette Veritabanı
tüm öğelerini SQL sorgusuna eklemeye çalışacak ve bir hataya neden olacaktı. Bu nedenle, $_GET
,
$_POST
veya $_COOKIE
adreslerindeki doğrulanmamış verileri doğrudan veritabanı sorgularında
asla kullanmayın.
İkinci seviyede, verilerin teknik geçerliliğini kontrol ederiz – örneğin, dizelerin UTF-8 kodlamasında olup olmadığı ve uzunluklarının sütun tanımıyla eşleşip eşleşmediği veya sayısal değerlerin verilen sütun veri türü için izin verilen aralıkta olup olmadığı. Bu doğrulama seviyesi için kısmen veritabanının kendisine güvenebiliriz – birçok veritabanı geçersiz verileri reddedecektir. Ancak, farklı veritabanlarındaki davranışlar farklılık gösterebilir; bazıları uzun dizeleri sessizce kesebilir veya aralık dışındaki sayıları kırpabilir.
Üçüncü seviye uygulamanıza özel mantıksal kontrolleri temsil eder. Örneğin, seçim kutularındaki değerlerin sunulan seçeneklerle eşleştiğini, sayıların beklenen aralıkta olduğunu (örneğin, 0–150 yaş) veya değerler arasındaki karşılıklı bağımlılıkların mantıklı olduğunu doğrulamak.
Doğrulamayı uygulamak için önerilen yollar:
- Tüm girdilerin otomatik olarak kapsamlı bir şekilde doğrulanmasını sağlayan Nette Forms'u kullanın
- Sunucuları kullanma ve
action*()
verender*()
yöntemlerinde parametreler için veri türleri belirtme - Veya aşağıdaki gibi standart PHP araçlarını kullanarak kendi doğrulama katmanınızı
uygulayın
filter_var()
Dinamik Tanımlayıcılar
Dinamik tablo ve sütun adları için ?name
yer tutucusunu kullanın. Bu, tanımlayıcıların verilen veritabanı
sözdizimine göre uygun şekilde kaçmasını sağlar (örneğin, MySQL'de backtick kullanımı):
Önemli: ?name
sembolünü yalnızca uygulama kodunda tanımlanan güvenilir değerler için kullanın.
Kullanıcı değerleri için bunun yerine bir beyaz liste yaklaşımı kullanın.