You need to enable JavaScript to run this app.

Ana içeriğe geç

Junior Member
SQL Injection ve Çözümü
SQL Injection ve Çözümü

Kod yazarken sadece işlevselliğe değil, güvenliğe de dikkat etmek gerekir. Özellikle veritabanı ile çalışan uygulamalarda, kullanıcıdan gelen verilerin doğrudan işlenmesi çok ciddi güvenlik açıklarına neden olabilir. Bu yazıda en yaygın güvenlik açıklarından biri olan SQL Injection'ı inceleyecek ve güvenli kodlama yöntemlerini örneklerle göstermeye çalışacağım.

- Sorun: SQL Injection Nedir?
SQL Injection (SQL Enjeksiyonu), kötü niyetli kullanıcıların, SQL sorgularına müdahale ederek veritabanı üzerinde yetkisiz işlemler yapabilmesini sağlayan bir güvenlik açığıdır.

- Örnek: Güvensiz Kod
Aşağıdaki örnek, kullanıcıdan alınan "kullanici_adi" ve "sifre" ile giriş yapılmaya çalışılan bir Python (SQLite) kod parçasıdır:

Kod:
import sqlite3

conn = sqlite3.connect('veritabani.db')
cursor = conn.cursor()

kullanici_adi = input("Kullanıcı adınızı girin: ")
sifre = input("Şifrenizi girin: ")

query = f"SELECT * FROM kullanicilar WHERE kullanici_adi = '{kullanici_adi}' AND sifre = '{sifre}'"
cursor.execute(query)

sonuc = cursor.fetchone()

if sonuc:
    print("Giriş başarılı!")
else:
    print("Hatalı kullanıcı adı veya şifre.")
- Sorun Nerede?
Bu kodda kullanıcıdan alınan veriler doğrudan SQL sorgusunun içine yerleştirilmiş. Bu durum kötü niyetli biri tarafından şu şekilde kullanılabilir:

Kod:
Kullanıcı adı: ' OR '1'='1
Şifre: ' OR '1'='1
Oluşan sorgu şöyle olur:

Kod:
SELECT * FROM kullanicilar WHERE kullanici_adi = '' OR '1'='1' AND sifre = '' OR '1'='1'
Bu sorgu daima doğru döner ve sisteme giriş yapılır. Bu, veri sızıntısına, yetkisiz erişime ve sistemin ele geçirilmesine neden olabilir.

- Çözüm: Parametreli Sorgular Kullanın
SQL Injection’a karşı en etkili yöntem parametreli sorgular kullanmaktır. Böylece kullanıcıdan gelen veri, doğrudan SQL’e yerleştirilmeden işlenir ve zararlı kod olarak algılanmaz.

Güvenli Kod Örneği
Kod:
import sqlite3

conn = sqlite3.connect('veritabani.db')
cursor = conn.cursor()

kullanici_adi = input("Kullanıcı adınızı girin: ")
sifre = input("Şifrenizi girin: ")

query = "SELECT * FROM kullanicilar WHERE kullanici_adi = ? AND sifre = ?"
cursor.execute(query, (kullanici_adi, sifre))

sonuc = cursor.fetchone()

if sonuc:
    print("Giriş başarılı!")
else:
    print("Hatalı kullanıcı adı veya şifre.")
- Neden Güvenli?
Bu yöntemde,

karakterleri yer tutucudur ve kullanıcıdan gelen veri bu yer tutuculara bağlanarak (binding) eklenir. Bu da verilerin yalnızca değer olarak algılanmasını sağlar, komut olarak değil.

Ekstra Önlemler
  1. Veritabanı kullanıcılarına minimum yetki verin.
    Uygulamanız sadece gerekli izinlerle çalışmalı (örneğin sadece SELECT/INSERT).
  2. Şifreleri veritabanında düz metin olarak saklamayın.
    SHA-256, bcrypt gibi şifreleme algoritmaları kullanın.
  3. Giriş denemelerine sınırlama koyun.
    Brute-force saldırılarına karşı korunmak için başarısız girişlerde süre limiti uygulayın.
  4. Kapsamlı loglama ve saldırı tespiti uygulayın.