Server-Side Request Forgery (SSRF) Güvenlik Önlemleri
Merhaba değerli okuyucular! Bugün, web uygulamalarının güvenliğinde önemli bir tehdit olan Server-Side Request Forgery (SSRF) saldırılarını ve bunlara karşı alınabilecek güvenlik önlemlerini detaylıca inceleyeceğiz. SSRF saldırılarının nasıl gerçekleştiğini anlamak ve etkili koruma yöntemlerini uygulamak, uygulamalarınızın güvenliğini önemli ölçüde artıracaktır. Hadi başlayalım!
SSRF Nedir?
Server-Side Request Forgery (SSRF), bir saldırganın sunucu tarafında yapılan istekleri manipüle ederek, normalde erişemeyeceği kaynaklara erişmesine olanak tanıyan bir güvenlik açığıdır. Bu saldırı türünde, saldırgan genellikle uygulamanın URL girdi alanlarını kullanarak, sunucuyu istenmeyen istekler yapmaya zorlar.
SSRF Saldırısı Örneği:
// Güvensiz kod örneği const url = req.query.url; fetch(url) .then(response => response.json()) .then(data => res.json(data)) .catch(error => res.status(500).json({ error: 'Bir hata oluştu' }));
Bu örnekte, kullanıcının sağladığı URL doğrudan kullanılıyor, bu da SSRF saldırılarına açık bir durum yaratıyor.
SSRF Saldırılarının Potansiyel Etkileri
- İç ağ kaynaklarına erişim
- Hassas verilerin sızdırılması
- Uzaktan Kod Çalıştırma (RCE)
- Port tarama ve servis keşfi
- Diğer güvenlik önlemlerinin bypass edilmesi
SSRF Saldırılarını Önleme Yöntemleri
1. URL Doğrulama ve Filtreleme
Gelen URL'leri sıkı bir şekilde doğrulayın ve filtreleyerek sadece izin verilen kaynakları kabul edin.
const url = require('url'); function isValidUrl(inputUrl) { try { const parsedUrl = new URL(inputUrl); const allowedDomains = ['api.example.com', 'cdn.example.com']; return allowedDomains.includes(parsedUrl.hostname); } catch (error) { return false; } } // Kullanım const userProvidedUrl = req.query.url; if (isValidUrl(userProvidedUrl)) { // URL'yi kullan } else { res.status(400).json({ error: 'Geçersiz URL' }); }
2. IP Adreslerini ve Özel Ağları Engelleme
İç ağ adreslerine ve özel IP aralıklarına yapılan istekleri engelleyin.
const ipRangeCheck = require('ip-range-check'); function isAllowedIp(ip) { const disallowedRanges = [ '10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16', '127.0.0.0/8' ]; return !ipRangeCheck(ip, disallowedRanges); } // Kullanım const urlObj = new URL(userProvidedUrl); const ip = await dns.promises.resolve(urlObj.hostname); if (isAllowedIp(ip[0])) { // İsteği yap } else { res.status(403).json({ error: 'Bu IP adresine erişim engellendi' }); }
3. Protokol Kısıtlaması
Sadece güvenli protokollere (örn. HTTPS) izin verin.
function isAllowedProtocol(inputUrl) { const parsedUrl = new URL(inputUrl); return parsedUrl.protocol === 'https:'; } // Kullanım if (isAllowedProtocol(userProvidedUrl)) { // İsteği yap } else { res.status(400).json({ error: 'Sadece HTTPS protokolüne izin verilmektedir' }); }
4. Çıktı Kodlama
Sunucudan dönen yanıtları kodlayarak, hassas bilgilerin sızmasını engelleyin.
const sanitizeHtml = require('sanitize-html'); function sanitizeResponse(response) { return sanitizeHtml(response, { allowedTags: [], allowedAttributes: {} }); } // Kullanım fetch(validatedUrl) .then(response => response.text()) .then(data => { const sanitizedData = sanitizeResponse(data); res.send(sanitizedData); });
5. Proxy Kullanımı
Tüm istekleri bir proxy üzerinden yönlendirerek ek bir güvenlik katmanı ekleyin.
const httpProxy = require('http-proxy'); const proxy = httpProxy.createProxyServer({}); app.use('/api', (req, res) => { const targetUrl = validateAndGetUrl(req.url); if (targetUrl) { proxy.web(req, res, { target: targetUrl }); } else { res.status(400).send('Geçersiz URL'); } });
6. DNS Çözümleme ve Doğrulama
DNS çözümlemesi yaparak, istenen alan adının gerçekten beklenen IP adresine sahip olduğunu doğrulayın.
const dns = require('dns'); async function validateDomain(domain) { try { const addresses = await dns.promises.resolve(domain); const allowedIps = ['203.0.113.0', '203.0.113.1']; // Örnek IP'ler return addresses.some(ip => allowedIps.includes(ip)); } catch (error) { return false; } } // Kullanım const urlObj = new URL(userProvidedUrl); if (await validateDomain(urlObj.hostname)) { // İsteği yap } else { res.status(403).json({ error: 'Geçersiz domain' }); }
7. Rate Limiting
İstek sayısını sınırlayarak, potansiyel SSRF saldırılarının etkisini azaltın.
const rateLimit = require("express-rate-limit"); const limiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 dakika max: 100 // Her IP için 15 dakikada maksimum 100 istek }); app.use(limiter);
SSRF Güvenlik Kontrol Listesi
Uygulamanızın SSRF saldırılarına karşı güvenliğini sağlamak için bu kontrol listesini kullanabilirsiniz:
class SSRFSecurityChecker { constructor() { this.checks = { urlValidation: false, ipBlocking: false, protocolRestriction: false, outputEncoding: false, proxyUsage: false, dnsValidation: false, rateLimiting: false }; } performUrlValidation() { // URL doğrulama implementasyonu this.checks.urlValidation = true; } implementIpBlocking() { // IP engelleme implementasyonu this.checks.ipBlocking = true; } restrictProtocols() { // Protokol kısıtlama implementasyonu this.checks.protocolRestriction = true; } enableOutputEncoding() { // Çıktı kodlama implementasyonu this.checks.outputEncoding = true; } setupProxy() { // Proxy kurulum implementasyonu this.checks.proxyUsage = true; } implementDnsValidation() { // DNS doğrulama implementasyonu this.checks.dnsValidation = true; } setupRateLimiting() { // Rate limiting implementasyonu this.checks.rateLimiting = true; } isSecure() { return Object.values(this.checks).every(check => check === true); } printSecurityStatus() { console.log("SSRF Security Status:"); for (const [check, status] of Object.entries(this.checks)) { console.log(`${check}: ${status ? 'Implemented' : 'Not Implemented'}`); } console.log(`Overall Security: ${this.isSecure() ? 'Secure' : 'Not Secure'}`); } } // Kullanım örneği const ssrfChecker = new SSRFSecurityChecker(); ssrfChecker.performUrlValidation(); ssrfChecker.implementIpBlocking(); ssrfChecker.restrictProtocols(); ssrfChecker.enableOutputEncoding(); ssrfChecker.setupProxy(); ssrfChecker.implementDnsValidation(); ssrfChecker.setupRateLimiting(); ssrfChecker.printSecurityStatus();
SSRF saldırıları, web uygulamaları için ciddi bir güvenlik tehdidi oluşturur. Ancak, doğru önlemler alındığında bu saldırıları etkili bir şekilde önlemek mümkündür. URL doğrulama, IP filtreleme, protokol kısıtlaması, çıktı kodlama ve diğer güvenlik önlemleri, SSRF saldırılarına karşı güçlü bir savunma hattı oluşturur.
Unutmayın ki, güvenlik sürekli bir süreçtir. Uygulamanızı düzenli olarak güvenlik açıklarına karşı test edin ve güncel güvenlik pratiklerini takip edin.
Siz SSRF saldırılarına karşı hangi önlemleri alıyorsunuz? Uygulamalarınızda karşılaştığınız zorluklar neler? Deneyimlerinizi ve düşüncelerinizi yorumlarda paylaşın!
Güvenli kodlamalar ve SSRF'siz bir dünya dilerim!