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
└─ SchemeHer Bileşendeki Riskler
- Scheme: Protocol downgrade saldırıları
- Host: DNS rebinding, SSRF
- Path: Path traversal, injection
- Query: XSS, SQL injection
- Fragment: DOM-based XSS
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üvenliContent 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 atlayabilirGü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 NoneHTTPS 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; preloadInput 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
- Tüm kullanıcı girdilerini validate edin
- Output encoding uygulayın
- Prepared statements kullanın
- CSP header'ı ekleyin
- HTTPS zorunlu tutun
- Rate limiting uygulayın
- Güvenlik logları tutun
- Düzenli güvenlik taraması yapın
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.