CodeBlanks Logo Icon CodeBlanks

SQL injection ve korunma

PHP kursu · İleri seviye · Ders 12/92

SQL injection saldırısını ve prepared statement ile nasıl korunacağını öğrenirsin.

SQL injection nedir?

SQL injection, saldırganın kullanıcı girdisine zararlı SQL parçaları gizleyerek sorgunun yapısını değiştirdiği bir güvenlik açığıdır. Amaç, yetkisiz veriye ulaşmak veya veriyi değiştirmektir.

Örneğin, bir giriş formuna ' OR '1'='1 yazıldığında, sorgu tüm satırları döndürecek şekilde bozulabilir. Saldırgan böylece parola bilmeden sisteme girebilir.

Bu tür saldırılar veri sızıntısı, yetki yükseltme ve veri kaybına yol açar; kullanıcı girdisi her zaman güvenli kabul edilmelidir.

prepare() enjeksiyonu nasıl engeller?

Hazırlanmış sorguda SQL şablonu ve veri ayrıdır. PDO, şablonu önce derler; sonra execute() değerleri parametre olarak verir. Değerler hiçbir zaman SQL metniyle birleşmez.

Bu yüzden ' OR '1'='1 gibi bir girdi, SQL komutu olarak değil, sıradan bir metin değeri olarak değerlendirilir. Sorgu yapısı değişmez; sadece o değere eşit satırlar aranır.

Sonuç olarak enjeksiyon girişimi etkisiz kalır; güvenlik otomatik olarak sağlanır.

Uygulama Enjeksiyon girişimini engelle

$userInput değişkenine "' OR '1'='1" değerini ata (bu kötü niyetli bir giriştir). prepare() ile 'SELECT name FROM users WHERE name = ?' şablonu hazırla. execute([$userInput]) ile çalıştır, fetchAll(PDO::FETCH_ASSOC) ile satırları al ve count($rows) sonucunu yazdır.

Örnek çözümü göster
:FETCH_ASSOC) ile al. echo count($rows) . "\n" yazdır.
Örnek çözüm:
<?php
// prepare ile SQL injection saldırısını engelle

$pdo = new PDO('sqlite::memory:');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->exec("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)");
$pdo->exec("INSERT INTO users (name) VALUES ('Ayşe')");
$pdo->exec("INSERT INTO users (name) VALUES ('Mehmet')");

$userInput = "' OR '1'='1";
$stmt = $pdo->prepare("SELECT name FROM users WHERE name = ?");
$stmt->execute([$userInput]);
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo count($rows) . "\n";

Kendini test et

  1. SQL injection'a karşı en güvenli yöntem hangisidir?

    • prepare() ile prepared statement kullanmak
    • Kullanıcı girdisini tek tırnakla sarmak
    • query() ile girdiyi doğrudan birleştirmek
    • Girdiyi htmlspecialchars ile süzmek
    Cevabı göster

    prepare() ile prepared statement kullanmak — Doğru! prepare() SQL ile veriyi ayırır; enjeksiyon girişimi veri olarak kabul edilir.

  2. SQL injection kavramlarını eşleştir

    SQL injection
    Güvenlik açığı
    prepare()
    Korunma yöntemi
    ' OR '1'='1
    Kötü niyetli girdi
    fetchAll()
    Tüm satırları döndürür
  3. Güvenli sorguyu tamamla

    $stmt = $pdo->____("SELECT * FROM users WHERE id = ?");
    $stmt->execute([$input]);
    Cevabı göster
    $stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
    $stmt->execute([$input]);

İleri seviye bölümündeki tüm dersler