URL Güvenliği: XSS, Injection ve Saldırılardan Korunma Rehberi

URL tabanlı güvenlik açıklarını ve saldırı vektörlerini öğrenin. XSS, SQL Injection, SSRF ve diğer tehditlere karşı koruma yöntemleri.

URL'ler web uygulamalarının temel yapı taşlarıdır, ancak aynı zamanda en yaygın saldırı vektörlerinden biridir. Bu rehberde URL tabanlı güvenlik tehditlerini ve korunma yöntemlerini inceliyoruz.

URL Yapısı ve Güvenlik Riskleri

URL Anatomisi

https://user:pass@example.com:443/path/page?param=value#fragment
  │      │    │       │        │     │         │          │
  │      │    │       │        │     │         │          └─ Fragment
  │      │    │       │        │     │         └─ Query String
  │      │    │       │        │     └─ Path
  │      │    │       │        └─ Port
  │      │    │       └─ Host
  │      │    └─ Password
  │      └─ Username
  └─ Scheme

Her Bileşendeki Riskler

Cross-Site Scripting (XSS)

URL Tabanlı XSS Türleri

1. Reflected XSS

# Saldırı URL'i
https://example.com/search?q=<script>alert('XSS')</script>

# Savunmasız kod
<p>Arama sonuçları: <?= $_GET['q'] ?></p>

2. DOM-Based XSS

# Saldırı URL'i
https://example.com/page#<img src=x onerror=alert('XSS')>

# Savunmasız JavaScript
document.getElementById('content').innerHTML = location.hash.slice(1);

XSS Korunma Yöntemleri

Output Encoding

// PHP
<?= htmlspecialchars($_GET['q'], ENT_QUOTES, 'UTF-8') ?>

// JavaScript
function escapeHtml(text) {
  const div = document.createElement('div');
  div.textContent = text;
  return div.innerHTML;
}

// React (otomatik escape)
<p>{searchQuery}</p>  // Güvenli

Content Security Policy

# HTTP Header
Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-abc123'

# Meta tag
<meta http-equiv="Content-Security-Policy" content="default-src 'self'">

SQL Injection

URL'den SQL Injection

# Saldırı URL'i
https://example.com/user?id=1' OR '1'='1
https://example.com/user?id=1; DROP TABLE users;--

# Savunmasız kod
$query = "SELECT * FROM users WHERE id = " . $_GET['id'];

SQL Injection Korunma

Prepared Statements

// PHP PDO
$stmt = $pdo->prepare('SELECT * FROM users WHERE id = ?');
$stmt->execute([$_GET['id']]);

// Node.js
const result = await db.query(
  'SELECT * FROM users WHERE id = $1',
  [req.query.id]
);

ORM Kullanımı

// Laravel Eloquent
$user = User::find($request->id);

// Prisma
const user = await prisma.user.findUnique({
  where: { id: parseInt(req.query.id) }
});

Server-Side Request Forgery (SSRF)

SSRF Saldırısı

# Saldırı URL'i
https://example.com/fetch?url=http://localhost:8080/admin
https://example.com/fetch?url=http://169.254.169.254/metadata

# Savunmasız kod
$data = file_get_contents($_GET['url']);

SSRF Korunma

function isUrlSafe($url) {
    $parsed = parse_url($url);
    
    // Sadece HTTP/HTTPS izin ver
    if (!in_array($parsed['scheme'], ['http', 'https'])) {
        return false;
    }
    
    // Localhost ve private IP'leri engelle
    $host = $parsed['host'];
    $ip = gethostbyname($host);
    
    $privateRanges = [
        '127.0.0.0/8',
        '10.0.0.0/8',
        '172.16.0.0/12',
        '192.168.0.0/16',
        '169.254.0.0/16'
    ];
    
    foreach ($privateRanges as $range) {
        if (ipInRange($ip, $range)) {
            return false;
        }
    }
    
    return true;
}

Path Traversal

Directory Traversal Saldırısı

# Saldırı URL'i
https://example.com/file?name=../../../etc/passwd
https://example.com/download?path=....//....//etc/passwd

# Savunmasız kod
$file = '/var/www/files/' . $_GET['name'];
readfile($file);

Path Traversal Korunma

function getSafeFilePath($filename, $baseDir) {
    // Tehlikeli karakterleri temizle
    $filename = basename($filename);
    
    // Tam yolu oluştur ve normalize et
    $fullPath = realpath($baseDir . '/' . $filename);
    
    // Base directory dışına çıkılmadığını kontrol et
    if ($fullPath === false || strpos($fullPath, realpath($baseDir)) !== 0) {
        throw new Exception('Invalid file path');
    }
    
    return $fullPath;
}

Open Redirect

Open Redirect Saldırısı

# Saldırı URL'i
https://example.com/login?redirect=https://evil.com/phishing
https://example.com/goto?url=//evil.com

# Savunmasız kod
header('Location: ' . $_GET['redirect']);

Open Redirect Korunma

function safeRedirect($url, $allowedDomains = []) {
    $parsed = parse_url($url);
    
    // Relative URL'leri izin ver
    if (!isset($parsed['host'])) {
        return $url;
    }
    
    // Sadece izin verilen domainlere yönlendir
    if (!in_array($parsed['host'], $allowedDomains)) {
        return '/';
    }
    
    return $url;
}

// Kullanım
$redirect = safeRedirect($_GET['redirect'], ['example.com', 'app.example.com']);

URL Encoding ve Güvenlik

Double Encoding Saldırıları

# Normal encoding
../  →  %2e%2e%2f

# Double encoding
../  →  %252e%252e%252f

# Bazı sunucular decode ederken atlayabilir

Güvenli URL Parsing

// JavaScript
function parseUrlSafely(urlString) {
    try {
        const url = new URL(urlString);
        return {
            protocol: url.protocol,
            host: url.host,
            pathname: url.pathname,
            searchParams: Object.fromEntries(url.searchParams)
        };
    } catch (e) {
        return null;
    }
}

// Python
from urllib.parse import urlparse, parse_qs

def parse_url_safely(url_string):
    try:
        parsed = urlparse(url_string)
        return {
            'scheme': parsed.scheme,
            'netloc': parsed.netloc,
            'path': parsed.path,
            'params': parse_qs(parsed.query)
        }
    except:
        return None

HTTPS ve Güvenli Bağlantı

HTTPS Zorunluluğu

# Nginx
server {
    listen 80;
    return 301 https://$host$request_uri;
}

# Apache
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

# HSTS Header
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

Input Validation Best Practices

// URL parametresi validasyonu
function validateUrlParam($param, $type) {
    switch ($type) {
        case 'id':
            return filter_var($param, FILTER_VALIDATE_INT) !== false;
        case 'email':
            return filter_var($param, FILTER_VALIDATE_EMAIL) !== false;
        case 'url':
            return filter_var($param, FILTER_VALIDATE_URL) !== false;
        case 'slug':
            return preg_match('/^[a-z0-9-]+$/', $param);
        default:
            return false;
    }
}

Güvenlik Kontrol Listesi

Sonuç

URL güvenliği, web uygulaması güvenliğinin kritik bir parçasıdır. Her URL parametresini potansiyel bir saldırı vektörü olarak değerlendirin ve uygun koruma önlemlerini alın. SlugURL ile oluşturduğunuz URL'leri güvenlik best practice'leriyle destekleyerek hem SEO hem de güvenlik açısından optimize edilmiş yapılar oluşturun.