PHP, sunucu tarafında çalışan ve web uygulamalarının büyük bölümünde kullanılan bir betik dilidir. Ancak PHP kaynaklı güvenlik sorunlarının çoğu, uygulama kodundan değil yanlış veya eksik sunucu yapılandırmalarından kaynaklanır.
Varsayılan ayarlarla çalışan bir PHP kurulumu, özellikle çoklu site barındırılan sistemlerde tüm sunucuyu riske açık hale getirebilir. Bu nedenle PHP’yi yalnızca kurup çalıştırmak yeterli değildir.
PHP Tarafında Sık Görülen Saldırı Türleri
PHP sistemlerine yönelik saldırılar genellikle aynı birkaç temel noktayı hedef alır. Aşağıdaki saldırı türleri, sahada en sık karşılaşılan ve etkisi en ağır olanlardır.
Remote Code Execution RCE
PHP üzerinden sunucuda komut çalıştırılmasıdır. Genellikle exec, system, shell_exec gibi fonksiyonlar açıksa mümkündür. Sonuç çoğu zaman sunucunun tamamen ele geçirilmesidir.
disable_functions = exec,system,shell_exec,passthru,proc_open,popen
Dosya Yükleme Üzerinden Web Shell
Yanlış yapılandırılmış upload alanları hedef alınır. Saldırgan PHP dosyası yükleyip çalıştırır.
location /uploads {
php_admin_flag engine off;
}Local File Inclusion LFI
Kullanıcı girdisiyle dosya include edilmesi sonucu oluşur. Saldırgan sistem dosyalarını ve logları okuyabilir. Log poisoning ile birleşirse RCE’ye dönüşür.
open_basedir = "/var/www/site:/tmp"SQL Injection
Kullanıcı girdisi filtrelenmeden sorguya girerse ortaya çıkar. Veritabanı içeriği ele geçirilir veya admin hesapları düşer.
SELECT * FROM users WHERE id = ?Bu saldırıların tamamı tek bir noktada birleşir. PHP’nin sınırları doğru çizilmemiştir. Aşağıdaki yapılandırmalar ile bu sınırları güvenli tutabiliriz.
PHP’yi Her Zaman Güncel Tutalım
Eski PHP sürümleri bilinen güvenlik açıklarının doğrudan hedefidir. EOL olmuş PHP 7.x serisini üretimde çalıştırmak saldırganlara hazır zemin sunar.
Dağıtıma uygun paket yöneticisiyle (apt, dnf, yum, zypper) güvenlik güncellemeleri geciktirilmeden uygulayalım.
PHP 7.4.3 sürümünden PHP 8.x serisine geçiş sürecini adım adım anlatan rehberi inceleyerek yükseltme işlemini kontrollü şekilde planlayabilirsin.
🟠 Komut Satırıyla PHP 7.4.3 Sürümünü PHP 8.x’e Yükseltme
Dosya Sistemi Erişimini Sınırlama
PHP doğrudan dosya sistemiyle çalıştığı için yanlış yapılandırma risktir. İlk adım, PHP’nin hangi dizinlere erişebileceğini netleştirmektir.
open_basedir = "/var/www/site:/tmp"PHP İşlemlerinin Yetkisi
Root yetkisiyle çalışan PHP süreci, tek bir açıkta tüm sunucuyu kaybettirir. Bu nedenle PHP-FPM veya CGI süreçleri düşük yetkili kullanıcılarla çalışmalıdır.
ps aux | grep phpHer uygulama için ayrı PHP-FPM havuzu ve ayrı kullanıcı tanımlanmalıdır.
Plesk kullanılan ortamlarda domain bazlı PHP-FPM havuzu ve kaynak limitlerinin nasıl yapılandırılacağını detaylı şekilde anlatan rehbere buradan ulaşabilirsiniz.
PHP Fonksiyonlarını Devre Dışı Bırak
PHP varsayılan olarak sistem komutu çalıştırabilen fonksiyonlarla gelir. Uygulama kullanmıyorsa açık kalmamalıdır.
disable_functions = exec,system,shell_exec,passthru,popen,proc_openPHP’nin İletişimini Sınırla
Uzak dosya erişimi çoğu zaman zincirleme açıkların başlangıcıdır. Varsayılan olarak kapalı olmalıdır.
allow_url_fopen = Off
allow_url_include = OffPHP Loglarını Ayır ve İzle
PHP error log’ları sadece debug değil, saldırı tespiti içindir. Her PHP-FPM havuzu için ayrı log dosyaları tanımlanmalıdır. Loglar merkezi sistemlere aktarılmalı ve izlenmelidir.
PHP Modüllerini Ters Mantıkla Yönet
Önce neye ihtiyaç olduğunu belirle, sonra modülleri aç. Kullanılmayan her modül ek saldırı yüzeyidir.
php -m
mv /etc/php.d/xmlrpc.ini /etc/php.d/xmlrpc.off
systemctl restart php-fpmDosya Yükleme Mekanizmalarını Daralt
Dosya yükleme mümkünse kapatılmalıdır. Zorunluysa sınırlandırılmalıdır.
file_uploads = On
upload_max_filesize = 2M
upload_tmp_dir = /var/lib/php/tmpPHP Hata Mesajlarını Kullanıcıdan Gizle
Hata mesajları saldırgan için ipucu olabilir. Ekran kapalı, log açık olmalıdır.
display_errors = Off
log_errors = On
error_log = /var/log/php/runtime-error.logScript Süresi ve Bellek Sınırları Koy
Sonsuz veya ağır script’ler saldırı olmasa bile sorundur. Temel sınırlar mutlaka tanımlanmalıdır.
max_execution_time = 30
max_input_time = 30
memory_limit = 256MDosya ve Dizin İzinlerini En Sona Al
En doğru zaman en sondur. Artık uygulamanın nereye yazdığını biliyorsundur.
find /var/www/site -type f -exec chmod 0444 {} \;
find /var/www/site -type d -exec chmod 0555 {} \;SELinux ve WAF ile İkinci Savunma Katmanını Kur
PHP ayarları ilk savunma hattıdır. SELinux ve WAF ikinci katmandır.
getsebool -a | grep httpdSık Sorulan Sorular
PHP-FPM kullanıyorsam yine de PHP güvenlik ayarları gerekli mi?
PHP-FPM izolasyon sağlar ancak tek başına güvenlik çözümü değildir. Yanlış yapılandırılmış bir FPM havuzu, uygulama seviyesindeki bir açığın sistem geneline yayılmasına neden olabilir.
Bir PHP uygulaması sistemde neye erişmeye çalıştığını nasıl öğrenebilirim?
PHP-FPM prosesini sistem çağrıları üzerinden izleyerek anlayabilirsin. Özellikle dosya erişimi ve ağ denemeleri bu şekilde netleşir.
strace -f -p $(pgrep -n php-fpm)Bir PHP sitesi dışarıya veri sızdırıyor mu nasıl anlarım?
Koddan önce ağ davranışına bakılır. PHP proseslerinin beklenmeyen outbound bağlantı kurup kurmadığı kontrol edilir.
ss -tpn | grep phpProd ortamda çalışan PHP kodu staging’de çalışıyor ama prod’da hata veriyor?
Prod ve staging php.ini dosyalarını birebir karşılaştırılmalı. Özellikle disable_functions, open_basedir ve allow_url_* farklarına bakılmalı. Sorunlu ayarı prod’da geçici olarak izole edip, kodu ona göre düzeltelim.
