OWASP Top 10: En Kritik Web Uygulama Güvenlik Açıkları
Güvenlik testlerinde yıllarca çalıştıktan sonra şunu fark ettim: çoğu kuruluş OWASP Top 10’u bir “compliance belgesi” gibi görüyor. Bir kutu işaretleniyor, rapor sunuluyor, dosya kapatılıyor. Oysa bu liste, gerçek saldırıların gerçek kodlardaki izlerinden damıtılmış bir bilgi birikimi. Her madde arkasında yüzlerce gerçek ihlal hikayesi var. Bu yazıda OWASP Top 10’u soyut bir liste olarak değil, Linux tabanlı ortamlarda nasıl test edeceğinizi ve nasıl önlem alacağınızı göstererek ele alacağım.
OWASP Top 10 Nedir ve Neden Önemlidir
OWASP (Open Web Application Security Project), dünya genelinde web uygulama güvenliğini standartlaştırmaya çalışan kar amacı gütmeyen bir organizasyon. Top 10 listesi, gerçek dünyadan toplanan veri ihlali raporları ve güvenlik araştırmalarından derleniyor. Her birkaç yılda bir güncelleniyor; en güncel versiyon 2021 yılında yayınlandı.
Bu listeyi özellikle sysadmin perspektifinden değerli kılan şey şu: uygulamaları biz yazmıyoruz olabilir, ama ihlal gerçekleştiğinde sistemi ayağa kaldırmak, log’ları incelemek ve hasarı sınırlamak bizim işimiz oluyor. Dolayısıyla bu açıkların nasıl çalıştığını anlamak, hem proaktif savunma hem de incident response açısından kritik.
A01: Broken Access Control (Kırık Erişim Denetimi)
2021 listesinin zirvesine oturan bu kategori, boş yere birinci değil. Kullanıcıların yetkisiz kaynaklara erişebildiği her durum bu kapsamda.
Basit bir senaryo: /admin sayfasına yalnızca admin rolündeki kullanıcılar erişebilmeli. Ama uygulama bu kontrolü sadece client-side JavaScript ile yapıyorsa, direkt URL’e gidince kontrol bypass ediliyor.
Test için curl ile basit bir deneme:
# Normal kullanıcı token'ı ile admin endpoint'e erişim denemesi
curl -H "Authorization: Bearer <normal_user_token>"
https://hedef-uygulama.com/api/v1/admin/users
-v 2>&1 | grep -E "HTTP|{|}"
# IDOR testi - başka kullanıcının kaydına erişim
curl -H "Authorization: Bearer <kendi_token>"
https://hedef-uygulama.com/api/v1/users/12345/profile
Burada 12345 yerine kendi user ID’niz dışında bir değer deniyorsunuz. Eğer başka kullanıcının verisini görüyorsanız, klasik IDOR (Insecure Direct Object Reference) açığı var demektir.
Linux tarafında savunma için nginx üzerinde rate limiting ve erişim kısıtlaması:
# /etc/nginx/conf.d/security.conf
# Admin paneline IP bazlı kısıtlama
location /admin {
allow 10.0.0.0/8;
allow 192.168.1.50;
deny all;
# Rate limiting
limit_req zone=admin_zone burst=5 nodelay;
limit_req_status 429;
}
A02: Cryptographic Failures (Kriptografik Hatalar)
Eskiden “Sensitive Data Exposure” olarak bilinen bu kategori yeniden adlandırıldı çünkü asıl sorun veriyi açıkta bırakmak değil, kriptografik uygulamanın kendisindeki hatalar.
Karşılaştığım en yaygın sorun: eski MD5 veya SHA1 ile hashlenmiş parolalar. Bir veritabanı dump’ı eline geçen saldırgan bu hash’leri saatler içinde kırabiliyor.
# Sistemde zayıf hash algoritmalarını kullanan dosyaları ara
# /etc/shadow dosyasındaki hash tiplerini kontrol et
sudo awk -F: '$2 ~ /^$1$/ {print $1, "MD5 kullaniyor - ZAYIF!"}
$2 ~ /^$5$/ {print $1, "SHA-256 kullaniyor"}
$2 ~ /^$6$/ {print $1, "SHA-512 kullaniyor - OK"}' /etc/shadow
# SSL/TLS konfigürasyonu test et
nmap --script ssl-enum-ciphers -p 443 hedef-uygulama.com |
grep -E "WEAK|ERROR|TLSv1.[01]"
TLS konfigürasyonu için nginx’te güvenli bir başlangıç noktası:
# /etc/nginx/snippets/ssl-params.conf
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
A03: Injection (Enjeksiyon Saldırıları)
SQL Injection artık tek başına değil, OS command injection, LDAP injection, NoSQL injection gibi kardeşleriyle birlikte bu kategoride. Yine de SQL Injection hala en sık rastlanan ve en yıkıcı olanı.
Pratik bir test senaryosu: bir web uygulamasında arama parametresi var. Bu parametreyi sqlmap ile test etmek:
# Temel sqlmap taraması
sqlmap -u "https://hedef.com/search?q=test"
--level=3
--risk=2
--batch
--random-agent
-p q
# Cookie tabanlı oturum gerektiren sayfa için
sqlmap -u "https://hedef.com/profile"
--cookie="session=abc123; PHPSESSID=xyz789"
--forms
--batch
--dbs
OS command injection tespiti için Burp Suite veya manuel test:
# Uygulama parametresinde command injection testi
# Bu testleri SADECE izin aldığınız sistemlerde yapın
curl "https://hedef.com/ping?host=127.0.0.1;id" -v
curl "https://hedef.com/ping?host=127.0.0.1|whoami" -v
curl "https://hedef.com/ping?host=`id`" -v
Linux’ta uygulama sunucusu seviyesinde ek savunma katmanı olarak AppArmor profili oluşturmak iyi bir pratik:
# Web uygulaması process'i için AppArmor profili oluşturma
sudo aa-genprof /usr/bin/php-fpm8.1
# Mevcut profili kontrol et
sudo aa-status | grep php
# Profili enforce moduna al
sudo aa-enforce /etc/apparmor.d/usr.bin.php-fpm8.1
A04: Insecure Design (Güvensiz Tasarım)
Bu kategori 2021’de yeni eklendi ve bence en az anlaşılan madde. Güvenlik açığı kodda değil, mimaride. Uygulama tam olarak tasarlandığı gibi çalışıyor ama tasarımın kendisi güvensiz.
Örnek: bir e-ticaret uygulamasında sipariş tamamlama adımları client-side’da tutuluyorsa, fiyat manipülasyonu yapılabilir. Sunucu her adımda fiyatı veritabanından teyit etmiyorsa sorun var.
Bu madde için sysadmin olarak yapabileceğimiz en önemli şey: threat modeling süreçlerine dahil olmak ve altyapı seviyesinde segmentasyon uygulamak.
# Uygulama sunucuları arası ağ segmentasyonu için iptables
# Sadece web sunucusunun uygulama sunucusuna erişmesine izin ver
iptables -A INPUT -s 10.0.1.10 -p tcp --dport 8080 -j ACCEPT
iptables -A INPUT -p tcp --dport 8080 -j DROP
# Mevcut kuralları kaydet
iptables-save > /etc/iptables/rules.v4
A05: Security Misconfiguration (Güvenlik Yanlış Konfigürasyonu)
Benim en çok karşılaştığım kategori bu. Default credentials, gereksiz açık portlar, hata mesajlarında stack trace gösterimi, dizin listeleme. Bunlar hep misconfiguration.
Nikto ile web sunucusu misconfiguration taraması:
# Temel nikto taraması
nikto -h https://hedef.com -ssl -output nikto_rapor.txt
# Belirli plugin'lerle detaylı tarama
nikto -h https://hedef.com
-Plugins "headers,cookies,apacheusers,shellshock"
-Format htm
-output nikto_detayli.html
Linux sunucuda gereksiz servisleri kapatmak ve sistemin saldırı yüzeyini azaltmak:
# Çalışan servisleri listele ve gereksizleri devre dışı bırak
systemctl list-units --type=service --state=running
# Örnek: gereksiz servisler
sudo systemctl disable --now cups bluetooth avahi-daemon
# Açık portları kontrol et
ss -tlnp | grep -v "127.0.0.1|::1"
# Sadece gerekli portları açık bırak
# Gereksiz portları kapat
sudo ufw deny 8080
sudo ufw deny 3306 # MySQL dışarıya kapalı olmalı
A06: Vulnerable and Outdated Components (Savunmasız ve Eski Bileşenler)
Bu madde için bir anım var: bir müşteri sisteminde WordPress kuruluydu, 2 yıl güncellenmemiş. Eklentilerden biri kritik bir güvenlik açığı içeriyordu. Saldırgan bu açığı kullanarak web shell yüklemiş, oradan lateral movement yapmış ve veritabanı sunucusuna ulaşmıştı. Tüm bu süreç 4 günde gerçekleşmiş.
Sistem bileşenlerini ve uygulamaları düzenli taramak için:
# Debian/Ubuntu sistemlerde güvenlik güncellemelerini kontrol et
sudo apt list --upgradable 2>/dev/null | grep -i security
# Sadece güvenlik yamalarını uygula
sudo unattended-upgrade --dry-run -v
# Yüklü paket versiyonlarını CVE veritabanıyla karşılaştır
# Trivy ile Docker image taraması
trivy image --severity HIGH,CRITICAL nginx:latest
# OWASP Dependency Check ile Java/Node.js projelerinde bağımlılık taraması
dependency-check.sh --project "UygulamaAdi"
--scan /var/www/html
--format HTML
--out /tmp/dep-check-rapor
A07: Identification and Authentication Failures (Kimlik Doğrulama Hataları)
Brute force saldırıları, zayıf parola politikaları, session token’larının güvensiz yönetimi bu kategoride. fail2ban burada en temel savunma aracımız.
# fail2ban konfigürasyonu - web uygulaması için özel jail
# /etc/fail2ban/jail.local
[web-app-auth]
enabled = true
filter = web-app-auth
logpath = /var/log/nginx/access.log
maxretry = 5
findtime = 300
bantime = 3600
action = iptables-multiport[name=web-app, port="80,443", protocol=tcp]
sendmail-whois[name=web-app, [email protected]]
# /etc/fail2ban/filter.d/web-app-auth.conf
[Definition]
failregex = ^<HOST> .* "POST /login HTTP.*" 401
^<HOST> .* "POST /api/auth HTTP.*" 401
ignoreregex =
Aktif ban listesini ve istatistikleri görmek için:
# Aktif banları listele
sudo fail2ban-client status web-app-auth
# Belirli bir IP'yi manuel ban'la
sudo fail2ban-client set web-app-auth banip 1.2.3.4
# Log'lardan brute force girişimlerini analiz et
sudo grep "POST /login" /var/log/nginx/access.log |
awk '{print $1}' | sort | uniq -c | sort -rn | head -20
A08: Software and Data Integrity Failures (Yazılım ve Veri Bütünlüğü Hataları)
Bu kategori CI/CD pipeline’larını da kapsıyor. Güvenilmeyen kaynaklardan indirilen kod veya güncellemeler, imzasız paketler, güvensiz deserialization.
Örnek senaryo: bir uygulama deployment script’i internet üzerinden bir tar.gz dosyası indirip doğrulama yapmadan çalıştırıyorsa, MITM saldırısıyla zararlı kod çalıştırılabilir.
# İndirilen dosyaların imzasını doğrula
# GPG ile imza doğrulama
wget https://kaynak.com/uygulama-v2.1.tar.gz
wget https://kaynak.com/uygulama-v2.1.tar.gz.sig
gpg --verify uygulama-v2.1.tar.gz.sig uygulama-v2.1.tar.gz
# SHA256 checksum doğrulama
echo "beklenen_sha256_hash uygulama-v2.1.tar.gz" | sha256sum -c
# AIDE ile kritik dosyaların bütünlüğünü izle
sudo aide --init
sudo mv /var/lib/aide/aide.db.new /var/lib/aide/aide.db
# Günlük bütünlük kontrolü için cron
echo "0 3 * * * root /usr/bin/aide --check | mail -s 'AIDE Raporu' [email protected]"
>> /etc/cron.d/aide-check
A09: Security Logging and Monitoring Failures (Güvenlik Log’lama ve İzleme Hataları)
Bir ihlal yaşandığında sahip olduğunuz log kalitesi, olayı anlayıp anlayamayacağınızı belirliyor. Log’lar yoksa, ihlalin ne zaman başladığını, ne kadar sürdüğünü ve hangi verilere erişildiğini öğrenemiyorsunuz.
Kapsamlı web uygulama log’lama için nginx konfigürasyonu:
# /etc/nginx/nginx.conf - genişletilmiş log formatı
log_format security_log '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$request_time $upstream_response_time '
'"$http_x_forwarded_for" "$request_id"';
access_log /var/log/nginx/access.log security_log;
error_log /var/log/nginx/error.log warn;
# Log rotasyonu konfigürasyonu
# /etc/logrotate.d/nginx
# daily, 90 gün, sıkıştırma
Gerçek zamanlı anormallik tespiti için basit bir bash script:
#!/bin/bash
# /usr/local/bin/web-anomaly-check.sh
# Dakika başına anormal istek sayısını tespit et
THRESHOLD=100
LOG_FILE="/var/log/nginx/access.log"
ALERT_EMAIL="[email protected]"
CURRENT_MINUTE=$(date "+%d/%b/%Y:%H:%M")
HIGH_RATE_IPS=$(grep "$CURRENT_MINUTE" "$LOG_FILE" |
awk '{print $1}' | sort | uniq -c | sort -rn |
awk -v threshold="$THRESHOLD" '$1 > threshold {print $2, $1}')
if [ -n "$HIGH_RATE_IPS" ]; then
echo "UYARI: Yuksek istek oranlari tespit edildi:" |
mail -s "[GUVENLIK] Anormal Web Trafigi" "$ALERT_EMAIL" <<<
"Dakikada $THRESHOLD ustu istek yapan IP'ler:n$HIGH_RATE_IPS"
fi
A10: Server-Side Request Forgery (SSRF)
SSRF son yıllarda bulut ortamlarında kritik hale geldi. Saldırgan, uygulamayı kendi adına istek yapması için yönlendiriyor. AWS’de bu, metadata endpoint’ine (169.254.169.254) erişim anlamına gelebiliyor ki bu endpoint IAM credentials içeriyor.
SSRF test senaryosu:
# SSRF tespiti için payloads
# Uygulama bir URL parametresi alıyorsa test et
curl "https://hedef.com/fetch?url=http://169.254.169.254/latest/meta-data/"
curl "https://hedef.com/fetch?url=http://localhost:8080/admin"
curl "https://hedef.com/fetch?url=file:///etc/passwd"
# SSRF engelleme için iptables - web app'in erişmemesi gereken yerler
# Cloud metadata endpoint'ini engelle
iptables -I OUTPUT -m owner --uid-owner www-data
-d 169.254.169.254 -j DROP
# Internal network'e çıkışı kısıtla
iptables -I OUTPUT -m owner --uid-owner www-data
-d 10.0.0.0/8 -j DROP
Tüm Bunları Bir Araya Getirmek: Periyodik Güvenlik Tarama Rutini
Aşağıdaki script’i cron’a ekleyerek haftalık temel güvenlik taraması yapabilirsiniz:
#!/bin/bash
# /usr/local/bin/weekly-security-scan.sh
REPORT_DIR="/var/reports/security/$(date +%Y%m%d)"
mkdir -p "$REPORT_DIR"
echo "=== Guclendirilmis Guvenlik Taramasi Basladi ===" |
tee "$REPORT_DIR/summary.txt"
# 1. Açık portlar
echo "[*] Port taraması..." >> "$REPORT_DIR/summary.txt"
nmap -sV --script vulners localhost -oN "$REPORT_DIR/port_scan.txt" 2>/dev/null
# 2. Web sunucu başlıkları kontrolü
echo "[*] HTTP header analizi..." >> "$REPORT_DIR/summary.txt"
curl -sI https://localhost | grep -E "Server:|X-Powered-By:|X-Frame-Options:|Content-Security-Policy:"
> "$REPORT_DIR/http_headers.txt"
# 3. SSL/TLS kontrolü
echo "[*] SSL konfigürasyon kontrolü..." >> "$REPORT_DIR/summary.txt"
testssl.sh --severity HIGH localhost > "$REPORT_DIR/ssl_check.txt" 2>/dev/null
# 4. Sistem güvenlik güncellemeleri
echo "[*] Bekleyen güvenlik güncellemeleri..." >> "$REPORT_DIR/summary.txt"
apt list --upgradable 2>/dev/null | grep -i security > "$REPORT_DIR/pending_updates.txt"
# Raporu gönder
tar -czf "/tmp/security_report_$(date +%Y%m%d).tar.gz" "$REPORT_DIR"
echo "Haftalık güvenlik raporu ekte." |
mail -s "[GÜVENLİK] Haftalık Tarama Raporu" -A "/tmp/security_report_$(date +%Y%m%d).tar.gz"
[email protected]
echo "=== Tarama Tamamlandi ===" | tee -a "$REPORT_DIR/summary.txt"
Sonuç
OWASP Top 10’u okuyup geçmek kolay. Ama her maddenin arkında gerçek bir senaryo, gerçek bir ihlal hikayesi var. Sysadmin ve DevOps olarak bu listeyi üç farklı perspektiften kullanın:
- Proaktif savunma: Yukarıdaki kontrolleri düzenli çalıştırın, misconfiguration’ları erken yakalayın.
- Katmanlı güvenlik: Hiçbir tek önlem yeterli değil. WAF + fail2ban + AppArmor + log izleme bir arada çalışmalı.
- Incident response: Bir ihlal olduğunda log’larınız olsun ki ne olduğunu anlayabilesiniz.
Güvenlik bir ürün değil, süreç. Bu listedeki maddelerin tamamını bir gecede kapatmaya çalışmayın. Risk bazlı yaklaşın: önce en kritik olanları, önce en yüksek olasılıklı olanları. Ve her değişiklikten sonra tekrar test edin. “Biz güvendeyiz” diyenlerle değil, “Sürekli test ediyoruz” diyenlerle aynı tarafta olmak isteyebilirsiniz.
