Altbilgi içeriğine atla
Iron Academy Logo
C# Veritabanı Entegrasyonu

C#'ta SQL Enjeksiyonu Nedir ve Nasıl Önlenir?

Tim Corey
34m 33s

SQL enjeksiyonu, saldırganların kullanıcı girdileri yoluyla veritabanı sunucunuza zararlı SQL kodu göndermesine olanak tanıyan bir kod enjeksiyon tekniğidir. "SQL Enjeksiyonu Nedir ve C# ile Nasıl Önlerim?" başlıklı videosunda, Tim Corey, SQL enjeksiyonu zafiyetlerinin gerçekte kodda nasıl meydana geldiğini gösteriyor, birkaç başarılı SQL enjeksiyonu saldırı örneği gösteriyor (birleşik tabanlı ve yıkıcı saldırılar dahil) ve C#'da uygulayabileceğiniz pratik SQL enjeksiyonu önleme tekniklerini adım adım anlatıyor. Bu makale, Tim'in adım adım anlatımını izleyerek gösterdiği sorunları ve çözümleri görebilmenizi sağlar.

Demo uygulaması ve neden önemlidir

Tim, yerel bir InjectableDB (Kişiler ve Sırlar tabloları) ile bağlı küçük bir WPF demo uygulaması ile başlıyor. Uygulamanın web formu benzeri arama kutusu, kullanıcı girişi (soyad) alır ve kimlik, isim ve soyad döndürmek için bir SQL sorgusu oluşturur. "Çalışıyor" — Corey yazın ve Tim Corey bulun — fakat Tim temel noktayı vurgular: "Bir uygulamanın çalışıyor olması, güvenli olduğu anlamına gelmez." Çalışan bir web uygulaması, kullanıcıdan gelen girdiler SQL ifadelerine doğrudan dize birleştirme veya dinamik SQL yoluyla aktarılırsa hâlâ SQL enjeksiyonu zafiyetlerine sahip olabilir.

Güvensiz kod — dize birleştirme ve dinamik SQL

Tim, birçok geliştiricinin kullandığı kesin güvensiz deseni gösteriyor:

var sql = $"SELECT * FROM People WHERE LastName = '{searchText}'";
var results = connection.Query<Person>(sql);
var sql = $"SELECT * FROM People WHERE LastName = '{searchText}'";
var results = connection.Query<Person>(sql);

Bu orijinal sorgu, dize birleştirme kullanarak bir SQL ifadeleri oluşturur. Tim, eğer kullanıcı girdilerini doğrudan SQL sorgularına enjekte eden kod görüyorsanız durmanızı uyarıyor — bu, bir SQL enjeksiyonu zafiyetidir. Saldırganlar, SQL komutlarınızın yapısını değiştiren veya ek zararlı SQL ifadeleri çalıştıran zararlı girdiler oluşturabilir.

Bir saldırgan nasıl eder — UNION ve DROP

Bir SQL enjeksiyonu saldırısının nasıl çalıştığını göstermek için, Tim bu sorguları SQL Server'da yeniden oluşturur ve ardından SQL yorumlarını (--) kullanarak son karakterleri gizlemek için UNION ALL ve SQL enjeksiyonları hazırladı. Tim'in gösterdiği örnek zararlı yükler:

  • Diğer tabloları okumak için birleşim tabanlı SQL enjeksiyonu:

    UNION ALL SELECT ID, KullanıcıAdı AS İsim, Şifre AS Soyad FROM Sırlar;

    Bu, Sırlar tablosunun sonuçlarını orijinal SELECT sonucu kümeleriyle karıştırarak kullanıcı adı ve şifreler gibi hassas verileri açığa çıkarır.

  • Yıkıcı enjeksiyonla tabloları düşürme:

    DROP TABLE DemoTable;

    Bu, ilk deyimi noktalı virgülle sonlandırarak ve ardından yıkıcı komutu ekleyerek ikinci bir SQL deyimi (DROP TABLE) çalıştırır. Tim, tablonun kaybolduğunu gösteriyor — veritabanı kötü amaçlı SQL tarafından değiştirildi.

Tim'in noktası: saldırganların tablo veya sütun adlarını önceden bilmeleri gerekmiyor — veritabanı sunucularından tablo veya sütun adlarını listeleyebilir veya basitçe kör veya zamanlama tabanlı tekniklerle davranışı keşfedebilirler.

Düzeltme 1 — Parametreli sorgular

Tim'in birinci ve ana savunması, kullanıcı verileriyle SQL dizeleri oluşturmaya son vermektir. Dinamik SQL'i parametreli sorgularla değiştirin:

string sql = "SELECT * FROM People WHERE LastName = @LastName";
var results = connection.Query<Person>(sql, new { LastName = searchText });
string sql = "SELECT * FROM People WHERE LastName = @LastName";
var results = connection.Query<Person>(sql, new { LastName = searchText });

Tim, parametrizasyonun (hazır ifade tarzı kullanımı) kullanıcının sağladığı girdinin veritabanı tarafından kesinlikle veri olarak ele alındığını açıklar — kötü niyetli SQL sadece bir dizi değeri haline gelir ve SQL yapısını değiştiremez. Bu, birleştirme tabanlı yükler ve eklenen ; dahil olmak üzere birçok yaygın SQL enjeksiyon saldırısını önler DROP TABLE komutları.

Ayrıca, parametreleştirmenin asgari giriş doğrulaması ile eşleştirilmesini öneriyor: bir soyadında muhtemel olmayan karakterleri (örneğin, noktalı virgüller veya -- yorum işaretleyicileri) temizleyin veya engelleyin, ancak konuyla ilgisi olan apostrof gibi karakterlere izin verin (örn. O'Reilly). Parametreli sorgular ve girdi temizleme, SQL enjeksiyon saldırılarına karşı önemli derecede koruma sağlar.

Çözüm 2 — Saklı prosedürler

Tim, sırasıyla SQL'i içeride birleştirip sonra çalıştıran güvensiz bir saklı yordam ve parametreleri doğrudan kullanan güvenli bir saklı yordam olmak üzere iki saklı yordam gösteriyor.

  • Güvensiz saklı yordam, parametreden bir @sql dizesi oluşturur ve EXEC ile çalıştırır — hala enjeksiyona karşı savunmasızdır.

  • Güvenli saklı yordam SELECT işlemini gerçekleştirir ... WHERE LastName = @LastName ve güvenli bir şekilde parametre ile çalışır.

Tim şunu açıklıyor: depolanmış prosedürler içinde dinamik SQL oluşturmanız durumunda otomatik bir çözüm değildir. Ancak düzgün kullanıldığında (dinamik SQL olmadan), saklı yordamlar SQL ifadelerini merkezileştirmeye yardımcı olur, bu da sorguları parametrelendirmeyi ve denetlemeyi kolaylaştırır. Saklı yordamlar, uygulamanızdaki SQL enjeksiyonunu önlemeyi de basitleştirmeye yardımcı olabilir.

Hiçbir veriye güvenmeyin — veritabanı verisi dahil

Tim'in sıklıkla gözden kaçan önemli bir noktası: Kendi SQL veritabanınızdan alınan verilere körü körüne güvenmemelisiniz. Saldırganlar bazen kolonlara zararlı yükler yerleştirir (bir "zaman ayarlı bomba") ve bu yükler daha sonra başka bir süreç tarafından dinamik SQL'e birleştirilir. Tim ısrar ediyor: her zaman parametreler kullanın ve veri kaynağı bir web formu, dosya yüklemesi veya kendi veritabanınız olsa bile verileri her adımda temizleyin - böylece kötü niyetli girdi daha sonra enjeksiyon için bir yol haline gelemez.

Bonus ipucu — en az ayrıcalık ve veritabanı ayrıcalıklarının sınırlandırılması

Kod düzeltmelerinin ötesinde, Tim savunmacı yapılandırma önerir: uygulama hesaplarınız için veritabanı ayrıcalıklarını sınırlayın. Demo sırasında bağlantı, entegre güvenlik aracılığıyla bir yönetici hesabı kullanıyor — tehlikeli. Bunun yerine, en az ayrıcalık ilkesini kullanın:

Uygulama için sadece ihtiyaç duyduğu haklara sahip bir veritabanı hesabı oluşturun.

  • Eğer saklı yordamlar kullanırsanız, o hesaba sadece belirli saklı yordamlar için EXECUTE izni verin ve başka bir izni vermeyin.

  • Uygulama hesaplarına, DROP TABLE yapmak, tüm tabloları listelemek veya diğer veritabanlarını okumak gibi geniş yönetici ayrıcalıkları vermeyin.

Bu, başarılı bir SQL enjeksiyon saldırısının etkisini azaltır — enjeksiyon mümkün olsa bile, saldırgan hesabın izin verdiğinden fazlasını yapamaz.

Tim, Entity Framework'ün bunu karmaşıklaştırdığını da belirtir: EF genellikle yükseltilmiş izinler gerektirir (geçişler, şema değişiklikleri). EF'yi üretimde kullanıyorsanız, izinlerini ve dağıtımını dikkatlice planlayın.

Özet — durdur, parametrize et, temizle, sınırla

Tim, videosunu C# uygulamalarında SQL enjeksiyonunu önlemek için net bir kontrol listesi ile tamamlar:

  1. Kullanıcı girdisi içeren string birleştirme veya dinamik SQL ile SQL ifadeleri oluşturmayı bırakın.

  2. Kullanıcı verileri her zaman veri olarak değerlendirilsin diye parametreli sorgular / hazırlanmış ifade şablonları kullanın.

  3. Uygun olan yerlerde girişi temizleyin (noktalı virgülleri, SQL yorumlarını ve beklenmeyen karakterleri engelleyin).

  4. Sorgu mantığını merkezileştirmek için güvenli saklı yordamları (içlerinde dinamik SQL olmadan) tercih edin.

  5. Veritabanı hesaplarına en az ayrıcalık uygulayın — uygulamanın veritabanı kullanıcısının yapabileceklerini sınırlayın.

  6. Kodu gözden geçirin (özellikle SQL'i dinamik olarak oluşturan yerleri) ve SQL enjeksiyonu açıkları için test edin.

Tim'in son uyarısı: kullanıcı girdilerinin özensiz işlenmesi, dinamik SQL kullanımı ve aşırı veritabanı ayrıcalıkları ciddi güvenlik ihlallerine yol açabilir — hassas verilerin sızdırılması, tabloların yok edilmesi veya uzun süre tespit edilemeyen veri sızıntıları. SQL enjeksiyon önlemesini, bir temel güvenlik gereksinimi olarak değerlendirin, opsiyonel bir ek değil.

Hero Worlddot related to C#'ta SQL Enjeksiyonu Nedir ve Nasıl Önlenir?
Hero Affiliate related to C#'ta SQL Enjeksiyonu Nedir ve Nasıl Önlenir?

Sevdiğiniz Şeyleri Paylaşarak Daha Fazla Kazanın

.NET, C#, Java, Python veya Node.js üzerinde çalışan geliştiriciler için içerik oluşturuyor musunuz? Uzmanlığınızı ek gelire dönüştürün!

Iron Destek Ekibi

Haftanın 5 günü, 24 saat çevrimiçiyiz.
Sohbet
E-posta
Beni Ara