Server-Side Request Forgery (Sunucu Tarafı İstek Sahteciliği)
Genel Bakış
Bu güvenlik açığı, saldırganların sunucuyu kullanarak iç ağ kaynaklarına erişmesine olanak tanır. Yani, sunucunun yaptığı isteklerin yeterince kontrol edilmemesi durumunda ortaya çıkar.
Yaygın Örnekler
1. URL Validation (URL Doğrulama)
Örnek: Kullanıcı tarafından sağlanan URL'lerin yeterince doğrulanmaması.
// Kötü örnek
async function fetchImage(url) {
const response = await fetch(url);
return response.buffer();
}
// İyi örnek
class URLValidator {
constructor() {
this.allowedDomains = ['example.com', 'images.example.com'];
this.blockedIPs = ['127.0.0.1', '192.168.0.0/16'];
}
async validateURL(url) {
const parsedURL = new URL(url);
// Domain kontrolü
if (!this.allowedDomains.includes(parsedURL.hostname)) {
throw new Error('İzin verilmeyen domain');
}
// IP kontrolü
const ip = await this.resolveIP(parsedURL.hostname);
if (this.isIPBlocked(ip)) {
throw new Error('İzin verilmeyen IP adresi');
}
return true;
}
}
2. Internal Network Access (İç Ağ Erişimi)
Örnek: Sunucunun iç ağ kaynaklarına erişiminin kısıtlanmaması.
// Kötü örnek
async function proxyRequest(url) {
const response = await fetch(url);
return response.json();
}
// İyi örnek
class RequestProxy {
constructor() {
this.allowedEndpoints = [
'/api/public',
'/api/products'
];
}
async proxyRequest(url, method) {
// URL doğrulama
await this.validateURL(url);
// Endpoint kontrolü
if (!this.isAllowedEndpoint(url)) {
throw new Error('İzin verilmeyen endpoint');
}
// İstek yapılandırması
const config = {
method,
headers: this.getSecureHeaders(),
timeout: 5000
};
// İsteği gönder
const response = await fetch(url, config);
return this.processResponse(response);
}
}
Korunma Yöntemleri
- URL doğrulama yapın
- İzin verilen domainleri beyaz listeye alın
- İç ağ erişimini kısıtlayın
- İstek zaman aşımı belirleyin
- Güvenlik duvarı kuralları uygulayın
Örnek Kod
Secure Request Handling (Güvenli İstek İşleme)
class SecureRequestHandler {
constructor() {
this.validator = new URLValidator();
this.proxy = new RequestProxy();
this.rateLimiter = new RateLimiter();
}
async handleRequest(req) {
try {
// Rate limiting
await this.rateLimiter.checkLimit(req.ip);
// URL doğrulama
const url = req.query.url;
await this.validator.validateURL(url);
// İstek proxy'leme
const response = await this.proxy.proxyRequest(url, req.method);
// Yanıt işleme
return this.processResponse(response);
} catch (error) {
// Hata loglama
await this.logError(error);
// Güvenli hata yanıtı
return this.getErrorResponse(error);
}
}
async processResponse(response) {
// Yanıt doğrulama
if (!this.isValidResponse(response)) {
throw new Error('Geçersiz yanıt');
}
// Yanıt dönüştürme
return this.transformResponse(response);
}
}