HG PHP GüvenliğiEl Kitabı
Bölümler 27 / 38

İçindekiler/Altyapı Sertleştirme

Bölüm 27

Apache & Nginx Hardening

15 dk okuma2.945 kelimePHP 8.1+
Ön koşul

Bölüm 7 (CSP), Bölüm 16 (HSTS/çerez), Bölüm 19 (dosya yükleme yürütme), Bölüm 20 (Apache path traversal, openbasedir), Bölüm 26 (php.ini/FPM). İleri referans: Bölüm 28 (izinler).

Bu bölümün kazanımı

Web sunucusunun (Apache/Nginx) güvenlik rolünü; nginx + PHP-FPM'in doğru yapılandırılmasının (özellikle tryfiles/PATHINFO) neden hayati olduğunu; güvenlik başlıklarını, TLS'yi ve bilgi ifşasını (sürüm, .git, dizin listeleme) sertleştirmeyi öğreneceksiniz.

1. Giriş

Web sunucusu, uygulamanızın internete açılan kapısıdır: TLS'yi sonlandırır, statik dosyaları sunar, istekleri PHP-FPM'e (Bölüm 26) yönlendirir ve güvenlik başlıklarını ekler. Bu kapının yanlış yapılandırılması, en güvenli uygulamayı bile savunmasız kılar — çünkü saldırgan uygulama koduna hiç ulaşmadan, doğrudan sunucu yapılandırmasındaki bir boşluktan içeri girebilir.

Bunun ders kitabı örneği, nginx + PHP-FPM yanlış yapılandırmalarıdır. 2011'de Neal Poole, bir web uygulamasının nasıl ele geçirildiğini belgeledi: yanlış yapılandırılmış nginx, PHP-olmayan dosyaların (yüklenen bir görüntünün) PHP olarak çalıştırılmasına izin veriyordu (Bölüm 19 ile birleşince web shell). 2019'da ise Orange Tsai'nin bulduğu CVE-2019-11043 (Bölüm 11), belirli nginx + PHP-FPM yapılandırmalarında (PATH_INFO + try_files eksikliği) uzaktan kod çalıştırmaya yol açtı. Her ikisinin de kökü aynı: web sunucusu, hangi isteklerin PHP olarak çalışacağına dair gevşek/yanlış kurallar taşıyordu.

Bu bölüm, Apache ve Nginx'i sertleştirmeyi ele alır: FastCGI yapılandırması, güvenlik başlıkları, TLS, ve bilgi ifşasının kapatılması. Amaç, kapıyı yalnızca amaçlanan trafiğe açık, geri kalanına kapalı tutmaktır (deny-by-default, Bölüm 3, 14).


2. Temel Teori

Web sunucusunun güvenlik rolleri: - TLS sonlandırma — HTTPS; trafiği şifreler (Bölüm 16 sidejacking). - Statik/dinamik ayrımı — statik dosyaları doğrudan sunar; yalnızca doğru istekleri PHP-FPM'e yönlendirir. - Güvenlik başlıkları — CSP, HSTS, nosniff vb. ekler. - Erişim kontrolü — hassas yolları/dosyaları engeller (deny-by-default). - Kaynak sınırları — istek boyutu, hız (rate limit), zaman aşımı.

Kritik konu — hangi istek PHP olarak çalışır? PHP-FPM'e yönlendirme kuralları tam olmalıdır. İki klasik hata: - cgi.fix_pathinfo=1 + gevşek location: nginx, /uploads/evil.jpg/x.php gibi bir isteği PHP-FPM'e gönderir; PHP, PATH_INFO ile evil.jpg'i bulup PHP olarak çalıştırır. Yüklenen bir görüntüye gömülü PHP (Bölüm 19) böylece çalışır. (Neal Poole vakası.) - try_files eksikliği + PATH_INFO: Var olmayan bir betiğe yönlendirme; CVE-2019-11043'ün tetikleyicisi.

Doğru kural: nginx, yalnızca var olan .php dosyalarını FPM'e göndermeli — try_files $uri =404; ile dosya varlığı kontrol edilmeli; ve security.limit_extensions=.php (Bölüm 26) ikinci katman olmalı.

Güvenlik başlıkları (her biri bir saldırıyı azaltır):

Başlık Ne yapar İlgili
Strict-Transport-Security (HSTS) HTTPS'i zorunlu kılar Sidejacking (Bölüm 16)
Content-Security-Policy (CSP) Script kaynaklarını kısıtlar XSS (Bölüm 7)
X-Content-Type-Options: nosniff MIME-sniffing'i kapatır Yükleme/tür karışıklığı (Bölüm 19)
X-Frame-Options/frame-ancestors Çerçevelemeyi engeller Clickjacking
Referrer-Policy Referer sızıntısını sınırlar Token/URL sızıntısı
Permissions-Policy Tarayıcı özelliklerini kısıtlar Yüzey azaltma

Bilgi ifşası — sürüm ve gizli dosyalar. Sunucu sürümünü (Server: başlığı) gizle (ServerTokens Prod / server_tokens off). server-status/server-info ve dizin listelemeyi (autoindex/Options Indexes) kapat. .git/, .env, .htaccess, yedek dosyalar (*.bak, *~) ve composer.json gibi gizli/hassas dosyalara web erişimini engelle — açıkta kalan bir .git/ dizini tüm kaynak kodu ifşa eder (Bölüm 25).

Deny-by-default. Yalnızca gerekli yolları/dosyaları aç; gerisini reddet (Bölüm 3, 14) — Apache path traversal (Bölüm 20, CVE-2021-41773) Require all denied ile önlenirdi.


3. Mimarisel Bakış

 GÜVENSİZ (gevşek FPM yönlendirme):
   İstek: /uploads/evil.jpg/x.php
        ↓  location ~ \.php$ → FPM (dosya varlığı kontrol YOK)
   PHP-FPM: PATH_INFO ile evil.jpg'i PHP olarak çalıştırır (cgi.fix_pathinfo=1)
   → yüklenen görüntüdeki PHP çalışır → web shell (Bölüm 19)

 GÜVENLİ (sıkı FPM yönlendirme):
   İstek → location ~ \.php$ { try_files $uri =404;  ← dosya VAR MI?
                               fastcgi_pass ...; }
        ↓  yalnızca var olan .php → FPM  (+ security.limit_extensions=.php, Böl.26)
   → yüklenen .jpg ASLA PHP olarak çalışmaz

 SERTLEŞTİRME KATMANLARI:
   TLS + HSTS (Böl.16) · CSP (Böl.7) · nosniff/frame · server_tokens off
   .git/.env engeli · dizin listeleme kapalı · rate limit · deny-by-default

Kritik gözlem: web sunucusunun en tehlikeli hatası, "hangi istek PHP çalışır" kuralının gevşek olmasıdır; bunu try_files+limit_extensions kapatır.


4. Güvensiz Kod

Gerçekçi (güvensiz) nginx ve Apache yapılandırmaları:

# ⚠️ GÜVENSİZ nginx
server {
    listen 80;                              # TLS yok
    server_tokens on;                       # sürüm sızıyor
    root /var/www/app/public;

    location / { autoindex on; }            # dizin listeleme açık

    location ~ \.php$ {                      # dosya varlığı kontrolü YOK
        fastcgi_pass unix:/run/php-fpm.sock; # /uploads/x.jpg/y.php çalışır!
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
    # .git/.env/.htaccess erişimi engellenmemiş
    # güvenlik başlıkları yok
}
# ⚠️ GÜVENSİZ Apache
ServerTokens Full                            # sürüm sızıyor
<Directory /var/www>
    Options Indexes FollowSymLinks           # dizin listeleme
    AllowOverride All
    # Require all denied yok (Bölüm 20 CVE-2021-41773 yüzeyi)
</Directory>

5. Açığın Analizi

location ~ \.php$ (dosya varlığı kontrolü yok) — En tehlikeli hata. nginx, .php ile biten her isteği (ya da cgi.fix_pathinfo=1 ile PATH_INFO içeren yolları) FPM'e gönderir. /uploads/evil.jpg/x.php isteği, PHP'nin PATH_INFO ile evil.jpg'i PHP olarak çalıştırmasına yol açar; yüklenen bir görüntüye gömülü PHP (Bölüm 19) böylece çalışır → web shell. try_files $uri =404; (dosya var mı?) ve security.limit_extensions=.php (Bölüm 26) eksik. Bu ayrıca CVE-2019-11043'ün (PATH_INFO + try_files eksikliği) sınıfıdır.

listen 80 (TLS yok) — Trafik şifresiz; oturum çerezi ve veri ağda açıkta (Bölüm 16 Firesheep). HTTPS + HTTP→HTTPS yönlendirme + HSTS gerekir.

server_tokens on / ServerTokens Full — Sunucu ve sürüm bilgisi sızar; saldırgan sürüme özel açıkları hedefler. off/Prod yapılmalı.

autoindex on / Options Indexes — Dizin listeleme açık; saldırgan dosya yapısını, yedekleri, gizli dosyaları keşfeder. Kapatılmalı.

.git/.env engeli yok — Açıkta kalan .git/ tüm kaynak kodu ve geçmişteki sırları (Bölüm 25) ifşa eder; .env sırları verir. Bu dosyalara web erişimi engellenmeli.

Require all denied yok (Apache) — Deny-by-default olmadığından, taban dizin dışındaki yollar (Bölüm 20 CVE-2021-41773) ifşaya açık.

Güvenlik başlıkları yok — CSP/HSTS/nosniff/frame yok; XSS (Bölüm 7), sidejacking (Bölüm 16), clickjacking için azaltma yok.

Kök sorun: sunucu, "hangi istek PHP çalışır" kuralında gevşek, TLS'siz, bilgi sızdıran ve başlıksız. Çözüm: sıkı FPM yönlendirme + TLS/HSTS + başlıklar + bilgi kapatma + deny-by-default.


6. Hacker Bakış Açısı

Saldırgan web sunucusunu nasıl yoklar?

Sürüm ve teknoloji belirler. Server/X-Powered-By başlıkları, hata sayfaları ve davranışlardan sunucu (Apache/Nginx) ve sürümü çıkarır; sürüme özel açıkları (CVE-2021-41773, CVE-2019-11043) hedefler.

Yürütme kuralını test eder. Yüklediği (Bölüm 19) veya var olan bir dosyayı .jpg/x.php, x.php/, x.php%00, PATH_INFO varyantlarıyla PHP olarak çalıştırmayı dener. try_files/limit_extensions yoksa başarır → web shell.

Gizli dosyaları tarar. .git/, .env, .htaccess, .bak/~ yedekleri, composer.json, phpinfo.php, server-status gibi yolları dener. Açıkta bir .git/ bulursa tüm kaynağı ve geçmiş sırları indirir.

Dizin listelemeyi kullanır. autoindex/Indexes açıksa dizinleri gezip yapıyı ve dosyaları haritalar.

TLS/başlık eksiklerini değerlendirir. HTTPS yoksa sidejacking; HSTS yoksa downgrade; CSP yoksa XSS daha kolay; nosniff yoksa MIME karışıklığı; frame koruması yoksa clickjacking.

Traversal/erişim dener. Deny-by-default yoksa taban dizin dışı yolları (Bölüm 20) dener.

Savunmacı dersi: Saldırgan sunucuyu, uygulamaya ulaşmadan önceki ilk hedef olarak görür. Sıkı FPM kuralı, kapatılmış bilgi ifşası ve güvenlik başlıkları, bu ilk hattı savunur.


7. Exploit Mantığı

Bu bölüm çalıştırılabilir saldırı içermez. Sunucu yapılandırmasının neden kritik olduğu kavramsaldır:

  • Yürütme kuralı = RCE veya güvenlik. "Hangi istek PHP çalışır" kuralı gevşekse, yüklenen bir görüntü (Bölüm 19) veya PATH_INFO manipülasyonu (CVE-2019-11043) RCE'ye döner. Sıkı try_files+limit_extensions bunu kapatır.
  • Bilgi ifşası = saldırı çarpanı. Sürüm, kaynak (.git), dizin yapısı ve yedekler; saldırganın hedefli ve verimli çalışmasını sağlar. Kapatmak, saldırganı "körleştirir".
  • Başlıklar = tarayıcı-taraflı azaltma. CSP/HSTS/nosniff/frame, uygulama açıklarının (XSS, sidejacking, clickjacking) etkisini tarayıcı seviyesinde azaltır — derinlemesine savunma (Bölüm 1, 7, 16).
  • Deny-by-default = yüzey daraltma. Yalnızca gerekli yolları açmak, path traversal ve gizli-dosya ifşasını yapısal olarak önler.

Araştırmacının çerçevesi: (a) yürütme kuralı sıkı mı, (b) TLS/HSTS var mı, (c) bilgi sızıyor mu, (d) güvenlik başlıkları var mı, (e) deny-by-default mi. Savunma hepsini sıkılaştırır.


8. Güvenli Kod

Sertleştirilmiş nginx ve Apache yapılandırmaları:

# ✅ GÜVENLİ nginx
server {
    listen 80;
    server_name app.example.com;
    return 301 https://$host$request_uri;    # HTTP → HTTPS
}
server {
    listen 443 ssl http2;
    server_name app.example.com;
    root /var/www/app/public;
    index index.php;

    server_tokens off;                       # sürüm gizli

    # TLS (modern) + HSTS (Bölüm 16)
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:...';
    ssl_prefer_server_ciphers off;
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;

    # Güvenlik başlıkları
    add_header Content-Security-Policy "default-src 'self'; object-src 'none'" always;  # Böl.7
    add_header X-Content-Type-Options "nosniff" always;                                  # Böl.19
    add_header X-Frame-Options "DENY" always;                                            # clickjacking
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;

    location / { try_files $uri $uri/ /index.php?$query_string; }

    # SIKI PHP yönlendirme: yalnızca VAR OLAN .php → FPM
    location ~ \.php$ {
        try_files $uri =404;                 # dosya varlığı kontrolü (KRİTİK)
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/run/php-fpm/app.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    # Gizli/hassas dosyaları engelle (Bölüm 25)
    location ~ /\.(git|env|htaccess) { deny all; return 404; }
    location ~ ~$ { deny all; }              # yedek dosyalar (*~)

    # İstek sınırları (DoS)
    client_max_body_size 10m;
}
# ✅ GÜVENLİ Apache
ServerTokens Prod
ServerSignature Off
<Directory />
    Require all denied                       # deny-by-default (Bölüm 20)
    Options None
    AllowOverride None
</Directory>
<Directory /var/www/app/public>
    Require all granted
    Options -Indexes +FollowSymLinks         # dizin listeleme kapalı
</Directory>
<FilesMatch "^\.|~$|\.(bak|env)$">           # gizli/yedek dosyalar
    Require all denied
</FilesMatch>
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "DENY"

Öne çıkan modern pratikler: - Sıkı PHP yönlendirme: nginx'te try_files $uri =404; (dosya varlığı) + security.limit_extensions=.php (Bölüm 26). Yüklenen dosyanın PHP olarak çalışmasını (Bölüm 19, CVE-2019-11043) kapatır. - TLS + HSTS + HTTP→HTTPS: Modern TLS (1.2/1.3), güçlü şifreler, HSTS (Bölüm 16). - Güvenlik başlıkları: CSP (Bölüm 7), nosniff (Bölüm 19), frame koruması, Referrer-Policy. - Bilgi ifşasını kapat: server_tokens off/ServerTokens Prod; dizin listeleme kapalı; .git/.env/yedekler engelli (Bölüm 25); server-status/server-info/phpinfo kapalı. - Deny-by-default (Bölüm 3, 14, 20): Yalnızca gerekli yolları aç. - İstek sınırları: client_max_body_size, zaman aşımı, limit_req (rate limit). - Düşük yetkili kullanıcı (Bölüm 28) + güncel sürüm (Bölüm 26).


9. Patch Analizi

Neden işe yarar? try_files $uri =404; + limit_extensions=.php, "yalnızca var olan .php çalışır" kuralını uygulayarak yüklenen dosyanın (Bölüm 19) ve PATH_INFO manipülasyonunun (CVE-2019-11043) PHP olarak çalışmasını imkânsız kılar. TLS/HSTS ağ dinlemeyi (Bölüm 16), güvenlik başlıkları uygulama açıklarının tarayıcı-taraflı etkisini (XSS/clickjacking) azaltır. Bilgi ifşasını kapatmak saldırganı körleştirir; deny-by-default yüzeyi daraltır (Bölüm 20). Bunlar birlikte, uygulamaya ulaşmadan önceki ilk savunma hattını kurar.

Yürütme kuralı karşılaştırması:

Yapılandırma Yüklenen dosya PHP çalışır mı?
location ~ \.php$ (try_files yok) + fix_pathinfo=1 ✗ Evet (RCE)
try_files $uri =404 ✓ Hayır
+ security.limit_extensions=.php (Böl.26) ✓✓ İki katman

Performans: Güvenlik başlıkları ve try_files neredeyse maliyetsizdir. TLS'in modern donanımda etkisi ihmal edilebilir (HTTP/2 ile genelde daha hızlı). Rate limiting hafif bir sayaç.


10. Gerçek Hayat Senaryosu

Kurgu — bir kurumsal portal. Uygulama güvenli yazılmış ama nginx yapılandırması bir tutorial'dan kopyalanmış: location ~ \.php$ var ama try_files yok ve cgi.fix_pathinfo=1. Portalın bir profil-fotoğrafı yükleme özelliği var (Bölüm 19). Saldırgan, geçerli bir JPEG başlığına PHP gömen bir görüntü yükleyip /uploads/pp.jpg/x.php ister; nginx bunu FPM'e gönderir, PHP PATH_INFO ile pp.jpg'i PHP olarak çalıştırır → web shell → RCE. Ayrıca açıkta kalan .git/ dizininden tüm kaynak ve geçmiş sırlar (Bölüm 25) indirilir. Dersler: (1) "hangi istek PHP çalışır" kuralı sıkı olmalı (try_files+limit_extensions); (2) .git/.env web'de engellenmeli; (3) sunucu yapılandırması tutorial'dan körü körüne kopyalanmamalı — Neal Poole'un 2011'deki uyarısı hâlâ geçerli.


11. Gerçek CVE Analizi — nginx + PHP-FPM RCE (CVE-2019-11043) ve fix_pathinfo Sınıfı

Orange Tsai'nin analizi, Detectify, ve nginx/PHP-FPM misconfiguration literatürü (Neal Poole 2011) ile doğrulanmıştır. Silahlaştırılmış payload verilmez.

Özet. Ekim 2019'da, Orange Tsai ve neex'in çalışmasıyla PHP-FPM'de bir arabellek hatası (CVE-2019-11043) açıklandı; belirli nginx + PHP-FPM yapılandırmalarında dışarıdan tetiklenebilen uzaktan kod çalıştırmaya yol açıyordu. Açık, phuip-fpizdam adlı bir exploit aracıyla kitlesel olarak istismar edilebilir hâle geldi.

Teknik neden — PATH_INFO + try_files eksikliği. Açık, aşağıdaki gibi bir nginx yapılandırmasında ortaya çıkıyordu:

location ~ [^/]\.php(/|$) {
    fastcgi_split_path_info ^(.+?\.php)(/.*)$;
    fastcgi_param PATH_INFO $fastcgi_path_info;
    fastcgi_pass php:9000;
    # try_files / dosya varlığı kontrolü YOK
}

Saldırgan, özel hazırlanmış bir URL ile PATH_INFO değerini boşaltacak biçimde bir istek gönderdiğinde, PHP-FPM'deki bir sınır hatası tetikleniyor; saldırgan bunu bir dizi PHP PHP_VALUE INI zinciriyle (ör. auto_prepend_file) kod çalıştırmaya çeviriyordu. Kritik önkoşul, yapılandırmanın var-olmayan betiklere karşı bir kontrol (try_files $uri =404; veya if (-f $uri)) içermemesiydi — yani sunucu, var olmayan bir PHP yoluna dair isteği yine de FPM'e iletiyordu.

Bu, daha eski ve daha yaygın bir sınıfın (Neal Poole'un 2011'de belgelediği cgi.fix_pathinfo=1 + gevşek location sorunu) akrabasıdır: her ikisinde de kök neden, web sunucusunun "hangi istek PHP-FPM'e gitmeli" kararını gevşek vermesidir. 2011 vakasında bu, yüklenen bir görüntünün (Bölüm 19) PHP olarak çalıştırılmasına; 2019 vakasında ise doğrudan PHP-FPM açığının tetiklenmesine yol açıyordu.

Etki. Savunmasız yapılandırmalarda kimlik-doğrulamasız uzaktan kod çalıştırma; www-data/FPM kullanıcısı bağlamında (oradan Bölüm 28'deki yetki yükseltmeye açık).

Düzeltme ve önerilen yapılandırma. PHP-FPM yamalandı; ancak asıl kalıcı savunma yapılandırmadadır: nginx, isteği FPM'e iletmeden önce betiğin var olduğunu kontrol etmelitry_files $uri =404; (veya if (-f $uri)), ve cgi.fix_pathinfo=0 (Bölüm 26) + security.limit_extensions=.php (Bölüm 26) katmanları.

Çıkarılacak dersler: 1. "Hangi istek PHP çalışır" kuralı sıkı olmalı. try_files $uri =404; ile dosya varlığını kontrol et; var olmayan/yüklenen dosyalar FPM'e gitmesin. 2. Katmanla: cgi.fix_pathinfo=0 + security.limit_extensions=.php (Bölüm 26), yapılandırma savunmasını tamamlar. 3. Tutorial'lara güvenme, yapılandırmanı denetle. Neal Poole'un 2011'deki uyarısı ("internetteki nginx/PHP tutorial'larının çoğu savunmasız yapılandırma öneriyor") hâlâ geçerlidir.


12. Detection

Yapılandırma incelemede:

grep -rnE 'location.*\\.php' /etc/nginx | grep -v try_files   # try_files eksik mi?
grep -rn 'server_tokens\|autoindex' /etc/nginx
grep -rin 'ServerTokens\|Options Indexes\|Require all' /etc/apache2 /etc/httpd
curl -sI https://site | grep -iE 'server|strict-transport|content-security|x-content-type|x-frame'
curl -s https://site/.git/config    # .git açıkta mı?

Kontroller: .php location'da try_files var mı? server_tokens off mu? dizin listeleme kapalı mı? .git/.env engelli mi? güvenlik başlıkları var mı? deny-by-default mi?

SAST/yapılandırma tarama: nginx/Apache güvenlik denetimi (Mozilla Observatory, testssl.sh, CIS Benchmark); eksik başlık ve gevşek FPM kuralları için kurallar.

DAST: Güvenlik başlıklarının varlığını, TLS yapılandırmasını, .git/dizin listeleme ifşasını ve yürütme kuralı zayıflığını (yüklenen dosyayı çalıştırma) test eder.

Loglar/SIEM: .php/ PATH_INFO manipülasyonları; .git/.env/yedek dosya erişim denemeleri; dizin listeleme taramaları; ve FPM RCE'de (CVE-2019-11043) web sürecinden beklenmeyen alt süreçler (Bölüm 8). .php isteklerinin dosya-varlığıyla eşleşmediği kalıplar en net izdir.


13. Prevention

  • Sıkı PHP yönlendirme: try_files $uri =404; + security.limit_extensions=.php + cgi.fix_pathinfo=0 (Bölüm 26). Yüklenen/var olmayan dosya FPM'e gitmesin.
  • TLS + HSTS + HTTP→HTTPS: Modern TLS; HSTS (Bölüm 16).
  • Güvenlik başlıkları: CSP (Bölüm 7), nosniff (Bölüm 19), frame koruması, Referrer-Policy.
  • Bilgi ifşasını kapat: server_tokens off; dizin listeleme kapalı; .git/.env/yedekler engelli (Bölüm 25); status/info/phpinfo kapalı.
  • Deny-by-default (Bölüm 3, 14, 20): Yalnızca gerekli yollar.
  • İstek sınırları + rate limit: Boyut, zaman aşımı, limit_req.
  • Düşük yetkili kullanıcı (Bölüm 28) + güncel sürüm (Bölüm 26).

14. Mitigation

  • Acil: .php location'a try_files $uri =404; ekle; .git/.env'i engelle; TLS/HSTS ve güvenlik başlıklarını ekle; dizin listelemeyi kapat.
  • Geçici: Loglardan yürütme-kuralı istismarı/web shell tara (Bölüm 34); açıkta kalmış .git/.env'den sızmış sırları döndür (Bölüm 25).
  • Kalıcı: Sıkı FPM yönlendirme + başlıklar + deny-by-default'u standart şablona al; yapılandırma taramasını (Observatory/CIS) CI'a ekle; sürümleri güncelle.

15. Checklist

  • [ ] .php yönlendirmesi try_files $uri =404; ile dosya varlığını kontrol ediyor mu?
  • [ ] security.limit_extensions=.php (Bölüm 26) + cgi.fix_pathinfo=0 katmanları var mı?
  • [ ] TLS (1.2/1.3) + HSTS + HTTP→HTTPS yönlendirme var mı (Bölüm 16)?
  • [ ] CSP, nosniff, X-Frame-Options, Referrer-Policy başlıkları ekli mi?
  • [ ] server_tokens off/ServerTokens Prod mu (sürüm gizli)?
  • [ ] Dizin listeleme kapalı mı (autoindex off / Options -Indexes)?
  • [ ] .git/.env/.htaccess/yedek dosyalar web'de engelli mi (Bölüm 25)?
  • [ ] server-status/server-info/phpinfo erişilemez mi?
  • [ ] Deny-by-default (Require all denied temel) uygulanıyor mu (Bölüm 20)?
  • [ ] İstek boyutu/zaman aşımı/rate limit sınırları var mı?

16. Laboratuvar

Lab 27.1 — Yürütme kuralı. İzole ortamda try_files olmadan bir .php location kur; bir "görüntü" (içinde test PHP) yükleyip /uploads/x.jpg/y.php ile çalıştır. try_files $uri =404; + limit_extensions ekleyip kapat (Bölüm 19'a bağla).

Lab 27.2 — Güvenlik başlıkları. Başlıksız bir sunucuyu Mozilla Observatory/curl -I ile tara; CSP/HSTS/nosniff/frame ekleyip skoru iyileştir.

Lab 27.3 — .git ifşası. Web köküne bir .git/ bırak; /.git/config ile erişilebildiğini gör. location ~ /\.git { deny all; } ile engelle.

Lab 27.4 — Bilgi ifşası. server_tokens on ve dizin listeleme ile sürüm/yapı sızıntısını gözlemle; off + Options -Indexes ile kapat.


17. Quiz

  1. Web sunucusunun beş güvenlik rolü nedir?
  2. "Hangi istek PHP olarak çalışır" kuralı neden kritiktir? İki klasik hata nedir?
  3. try_files $uri =404; neyi önler ve CVE-2019-11043 ile ilişkisi nedir?
  4. cgi.fix_pathinfo=1 + gevşek location, yüklenen bir görüntüyle nasıl RCE'ye yol açar (Bölüm 19)?
  5. HSTS, CSP, nosniff, X-Frame-Options başlıkları hangi farklı saldırıları azaltır?
  6. server_tokens/ServerTokens neden önemlidir?
  7. Açıkta kalan bir .git/ dizini neyi ifşa eder (Bölüm 25)?
  8. Deny-by-default (Require all denied) Bölüm 20'deki hangi açığı önlerdi?
  9. Neal Poole'un 2011'deki uyarısı neydi ve neden hâlâ geçerlidir?
  10. nginx yürütme savunmasını hangi php.ini/FPM ayarları (Bölüm 26) tamamlar?
  11. Dizin listeleme (autoindex) neden bilgi ifşasıdır?
  12. SIEM'de yürütme-kuralı istismarını gösteren kalıp nedir?

18. Kaynakça

  • OWASP, Secure Headers Project; HTTP Security Response Headers Cheat Sheet; Web Server Hardening.
  • MITRE / NVD, CVE-2019-11043 (PHP-FPM); Orange Tsai, An analysis about recently PHP-FPM RCE; valievkarim, phuip-fpizdam.
  • Neal Poole, Setting up PHP-FastCGI and nginx? Don't trust the tutorials (2011); Invicti/Acunetix, Nginx PHP code execution via FastCGI (cgi.fix_pathinfo).
  • nginx ve Apache HTTP Server resmi güvenlik/yapılandırma dokümantasyonu; Mozilla Observatory ve SSL Configuration Generator.
  • CIS Apache/Nginx Benchmark; MITRE, CWE-16 (Configuration), CWE-538 (File/Directory Information Exposure).