Web sunucularında kullanılan PHP mimarisi, dinamik web uygulamalarının temel direğidir. Ancak kurulum veya geliştirme aşamasında sistem yöneticileri ile yazılımcıların sıklıkla başvurduğu phpinfo() fonksiyonu, canlı (production) ortamda unutulduğunda ciddi bir güvenlik riskine dönüşür. Bu makalede phpinfo() güvenliği ilkelerini inceleyecek, php.ini yapılandırma dosyası üzerinden hassas sunucu bilgilerinin dış dünyaya nasıl kapatılacağını ve PHP ortamının nasıl sertleştirileceğini adım adım ele alacağız.
Saldırganlar bir sistemi hedef aldıklarında ilk olarak keşif (reconnaissance) aşamasını gerçekleştirirler. Sistemdeki yazılım sürümleri, dosya yolları, yapılandırma parametreleri ve aktif modüller ne kadar net görünürse, saldırı vektörü oluşturmak o kadar kolaylaşır. Bu nedenle phpinfo() güvenliği ve doğru php.ini konfigürasyonu, sunucu güvenliği zincirinin ilk ve en kritik halkalarından biridir.
phpinfo() Nedir ve Hangi Hassas Bilgileri Sızdırır?
phpinfo(), PHP'nin mevcut durumu, derleme seçenekleri, uzantıları, sürüm bilgileri, sunucu ortamı ve çalıştırma parametreleri hakkında kapsamlı bir HTML çıktı üreten dahili bir PHP fonksiyonudur. Geliştirme aşamasında phpinfo.php gibi bir dosya oluşturup <?php phpinfo(); ?> kodunu çalıştırmak oldukça pratik görünse de, canlı ortamda bu sayfanın açık kalması bilgi ifşası (Information Disclosure - CWE-200) zafiyetine yol açar.
Bir siber saldırgan veya otomatik tarama botu sunucunuzda çalışan bir phpinfo() çıktısına eriştiğinde şu hassas verilere doğrudan ulaşır:
- Tam PHP Sürümü: Örn. PHP 8.3.2. Saldırgan bu bilgini alarak o sürüme özel bilinen CVE (Common Vulnerabilities and Exposures) açıklarını aratabilir.
- İşletim Sistemi ve Çekirdek Detayları: Sunucunun Ubuntu, AlmaLinux veya Debian olduğunu, Linux çekirdek sürümünü öğrenebilir.
- Açık ve Kapalı Eklentiler (Extensions):
curl,gd,mbstring,imagick,phargibi modüllerin varlığı ve sürümleri. - Tam Dosya Yolları (Absolute File Paths):
DOCUMENT_ROOT,SCRIPT_FILENAMEve yükleme dizinleri. Bu bilgiler Local File Inclusion (LFI) veya Path Traversal saldırılarında hedef dosya yolunu tam olarak tutturmak için kullanılır. - Çevre Değişkenleri (Environment Variables): Eğer sisteminizde
.envdeğişkenleri veya sunucu düzeyinde tanımlanmışAWS_ACCESS_KEY_ID, veritabanı şifreleri, API anahtarları varsa bunlarphpinfo()çıktısınınEnvironmentveyaPHP Variablesbölümünde açık metin (plaintext) olarak görüntülenebilir. - Yüklenen Yapılandırma Dosyaları:
php.inidosyasının sunucudaki tam adresi ve ek konfigürasyon dizinleri (/etc/php/8.3/fpm/conf.d/).
Bu bilgilerin sızması, sisteminize yönelik Web Uygulama Güvenliği (OWASP Top 10) ve Korunma Yolları kapsamında açıklanan karmaşık saldırı zincirlerinin oluşturulmasını kolaylaştırır.
Sunucuda phpinfo() Güvenliği Nasıl Sağlanır?
Canlı bir sunucuda phpinfo() fonksiyonunun oluşturacağı riskleri bertaraf etmek için birden fazla katmanda önlem almalısınız. Sadece dosyayı silmek yetmez; PHP motoru seviyesinde fonksiyonu engellemek ve web sunucusu kurallarıyla erişimi sınırlandırmak gerekir.
1. Yetkisiz ve Unutulmuş phpinfo Dosyalarını Tespit Etme ve Silme
Sisteminizdeki tüm web dizinlerini tarayarak phpinfo() içeren dosyaları tespit edebilirsiniz. SSH üzerinden sunucunuza bağlandıktan sonra aşağıdaki komutları çalıştırarak kök dizindeki potansiyel tehlikeleri listeleyin:
# Www dizinindeki tüm .php dosyalarında phpinfo arama
grep -rnw '/var/www/' -e 'phpinfo()'
# Dosya adında 'info' veya 'test' geçen PHP dosyalarını bulma
find /var/www/ -type f -name "*info*.php" -o -name "*test*.php"
Tespit ettiğiniz info.php, phpinfo.php, test.php gibi gereksiz test dosyalarını vakit kaybetmeden silin:
rm -f /var/www/html/info.php
2. php.ini Dosyasında disable_functions Kullanımı
Yazılımcıların veya sisteme sızan bir zararlı yazılımın kod içerisinden phpinfo() fonksiyonunu tekrar çağırmasını engellemenin en kesin yolu, bu fonksiyonu PHP çekirdeğinde tamamen devre dışı bırakmaktır.
Kullandığınız PHP sürümüne uygun php.ini dosyasını açın (örneğin /etc/php/8.3/fpm/php.ini veya /etc/php/8.3/cli/php.ini):
disable_functions = exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source,phpinfo
Yukarıdaki satıra phpinfo eklediğinizde, herhangi bir PHP dosyası içerisinde phpinfo(); çağrılsa dahi PHP motoru bu fonksiyonu çalıştırmayacak ve bir uyarı (Warning/Error) döndürecektir.
Değişikliklerin geçerli olması için PHP-FPM veya Apache servisini yeniden başlatmalısınız:
systemctl restart php8.3-fpm
# ya da Apache kullanıyorsanız:
systemctl restart apache2
3. Sadece Belirli IP Adreslerine Erişim İzni Verme (Nginx & Apache)
Hata ayıklama veya sistem yönetimi amacıyla sunucu hakkında detaylı bilgiye ihtiyaç duyuyorsanız, bu bilgiyi sunan özel bir betiğe yalnızca kendi IP adresinizden erişilmesini sağlayabilirsiniz.
Nginx Yapılandırma Örneği:
location ~ ^/(sys-info-check\.php)$ {
allow 195.175.X.X; # Sadece sizin sabit IP adresiniz
deny all;
include fastcgi_params;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
Apache (.htaccess) Yapılandırma Örneği:
<Files "sys-info-check.php">
Require ip 195.175.X.X
</Files>
Bu sayede siz belirtilen IP üzerinden sisteme bağlandığınızda konfigürasyon detaylarını inceleyebilir, dış dünyadan gelen tüm istekleri ise 403 Forbidden hatası ile engelleyebilirsiniz.
php.ini Yapılandırması İle Sunucu Bilgilerini Gizleme ve Sertleştirme
phpinfo() fonksiyonunu engellemek tek başına yeterli değildir. PHP varsayılan ayarlarıyla çalıştığında, HTTP yanıt başlıklarında (Headers) ve hata mesajlarında da sunucu detaylarını dışarıya sızdırabilir. Bu durumu önlemek için php.ini dosyasında aşağıdaki kritik parametreleri düzenlemelisiniz.
expose_php Parametresini Kapatma
Varsayılan olarak PHP, gönderdiği her HTTP yanıtına X-Powered-By: PHP/8.3.2 şeklinde bir başlık ekler. Bu başlık, sunucuda PHP çalıştığını ve tam sürüm numarasını saldırganlara ilan eder.
php.ini dosyanızda şu değişikliği yapın:
; Varsayılan: expose_php = On
expose_php = Off
Bu ayarı Off yaptığınızda X-Powered-By başlığı HTTP yanıtlarından tamamen kaldırılır.
Hata Mesajlarını Gizleme (display_errors ve log_errors)
Canlı ortamda bir PHP hatası oluştuğunda bu hatanın ekrana basılması, dosya yollarını, veritabanı sorgularını ve değişken yapılarını açığa çıkarır.
php.ini içerisinde hata yönetimi parametrelerini şu şekilde ayarlayın:
; Hataların ekrana/tarayıcıya basılmasını engeller
display_errors = Off
display_startup_errors = Off
; Hataların sunucu günlüğüne (log) kaydedilmesini sağlar
log_errors = On
error_log = /var/log/php_errors.log
Bu yapılandırma sayesinde kullanıcılar veya saldırganlar hata detaylarını göremezken, siz hataları arka planda log dosyasından takip edebilirsiniz.
Dosya ve Dizin Erişim Sınırlandırması (open_basedir)
open_basedir yönergesi, PHP betiklerinin yalnızca belirtilen dizinler altındaki dosyalara erişmesine izin verir. Saldırgan bir şekilde sunucuda kod çalıştırsa bile /etc/passwd veya diğer sitelerin dizinlerine erişemez.
open_basedir = "/var/www/vhosts/example.com/:/tmp/"
Uzaktan Dosya Çağırma Özelliklerini Kapatma
Remote File Inclusion (RFI) saldırılarını engellemek için dış URL'lerin dosya gibi açılmasını sağlayan fonksiyonları kapatmalısınız:
allow_url_fopen = Off
allow_url_include = Off
Not: Eğer uygulamanızcURLdışındafile_get_contents("https://...")kullanarak dış servislerden veri çekiyorsaallow_url_fopen = Offyapıldığında bu işlem başarısız olabilir. Bu durumda kod yapınızıcURLkütüphanesini kullanacak şekilde güncellemeniz önerilir.
Web Sunucusu Seviyesinde Başlık (Header) ve Versiyon Gizleme
PHP seviyesinde yapılan sertleştirmeleri web sunucusu (Nginx/Apache) seviyesinde desteklemek şarttır. Sunucu mimarinizi incelemek için Shared Hosting, VPS ve Dedicated Sunucu Farkları rehberimizden faydalanabilirsiniz. Eğer kontrolün tamamen sizde olduğu bir VPS veya Dedicated sunucu yönetiyorsanız aşağıdaki adımları uygulayın.
Nginx Versiyon ve Başlık Gizleme
Nginx varsayılan olarak hata sayfalarında ve Server başlığında sürüm bilgisini (örn. Server: nginx/1.24.0) gösterir. Bunu kapatmak için /etc/nginx/nginx.conf dosyasına şu satırı ekleyin:
http {
server_tokens off;
# ...
}
Başlık kontrolü yapmak için terminalden cURL komutu çalıştırabilirsiniz:
curl -I https://example.com
Çıktıda yalnızca Server: nginx görünmeli, PHP veya Nginx sürüm numarası yer almamalıdır.
Apache Versiyon Bilgilerini Gizleme
Apache sunucusunda /etc/apache2/conf-enabled/security.conf veya /etc/httpd/conf/httpd.conf dosyasında şu ayarları güncelleyin:
ServerTokens Prod
ServerSignature Off
Bu işlem, Apache'nin işletim sistemi ve modül detaylarını dışarıya sunmasını engeller. Daha fazla Linux sunucu sıkılaştırma adımı için VPS Sunucu Güvenliği Nasıl Sağlanır? SSH Port Değiştirme ve Firewall Ayarları başlıklı makalemizi inceleyebilirsiniz.
Sık Yapılan phpinfo() ve php.ini Hataları ve Yanılgılar
Sunucu yönetiminde sıklıkla karşılaşılan bazı yanlış alışkanlıklar güvenlik zafiyetlerinin devam etmesine neden olur:
phpinfo() içeren dosyaya php_test_9823.php gibi karmaşık isimler vermek güvenlik sağlamaz. Saldırganlar FFuF, Gobuster veya Dirbuster gibi araçlarla saniyede binlerce sözlük tabanlı dizin/dosya taraması yaparak bu dosyaları kolayca tespit ederler.test.domain.com veya staging.domain.com altında bırakmak büyük bir hatadır. Arama motoru botları bu alt alan adlarını indeksleyebilir veya saldırganlar subdomain brute-force ile bu ortamlara ulaşabilir.php.ini dosyasına erişiminiz olmasa da cPanel/cPanel altındaki cPanel MultiPHP INI Editor üzerinden veya kök dizine ekleyeceğiniz .user.ini dosyası ile expose_php = Off veya display_errors = Off parametrelerini tanımlayabilirsiniz./etc/php/8.3/cli/php.ini) ve web sunucusu (/etc/php/8.3/fpm/php.ini) için ayrıdır. Güvenlik ayarlarını sadece CLI için yapıp FPM için unutmak sunucuyu korumasız bırakır.Gerçek Senaryo: Bir Sızma Testinde phpinfo() Açığı Nasıl İstismar Edilir?
Bir sızma testi (penetration test) uzmanının veya kötü niyetli bir korsanın açık kalmış bir phpinfo() sayfasından nasıl yararlandığını adım adım inceleyelim:
https://example.com/info.php adresine ulaşır. Sayfada PHP sürümünün PHP 8.1.0 ve OPcache eklentisinin aktif olduğunu görür.DOCUMENT_ROOT bilgisinden uygulamanın /var/www/vhosts/site/public dizininde çalıştığını tespit eder. Dosya yükleme (upload) işlevinde bir LFI zafiyeti ararken geçici yükleme dizininin /tmp olduğunu öğrenir.Environment bölümünü inceleyen saldırgan, yazılımcının .env dosyasını okumak yerine sistem ortam değişkenine tanımladığı DATABASE_URL=postgres://admin:SecretPass123@10.0.0.5:5432/production bilgisini görür.Sadece basit bir info.php dosyasının unutulması, tüm veritabanının ve iç ağ yapısının ele geçirilmesine zemin hazırlayabilir.
Özet Yapılandırma Kontrol Listesi (Checklist)
Sunucunuzda phpinfo() güvenliği ve php.ini sertleştirmesi yaparken şu adımları tamamladığınızdan emin olun:
phpinfo() içeren test dosyaları silindi.php.ini dosyasına disable_functions = ...,phpinfo eklendi.expose_php = Off yapıldı.display_errors = Off ve log_errors = On ayarlandı.allow_url_include = Off yapıldı.Nginx / Apache) versiyon gizleme parametreleri aktif edildi.Sonuç
Sunucu güvenliği tek bir yazılım veya araçla değil, bütüncül bir yaklaşım ve doğru yapılandırma adımlarıyla sağlanır. Geliştirme sürecinde hayatı kolaylaştıran phpinfo() gibi araçlar, canlı sistemlerde bilgi ifşası riskine dönüştürülmemelidir. php.ini dosyanızda gerçekleştireceğiniz birkaç dakikalık parametre değişikliği, sunucunuzu otomatik saldırı botlarına ve hedefli siber tehditlere karşı çok daha dirençli hale getirecektir.
Sonraki Adım: Zaman kaybetmeden SSH terminalinizi açın, makalede verilen find komutuyla sunucunuzdaki test dosyalarını tarayın ve php.ini dosyanızda expose_php = Off ile disable_functions güncellemesini uygulayarak servislerinizi yeniden başlatın.
Yorumlar (0)
Henüz yorum yapılmamış. İlk yorumu siz yapın!
Yorum Yazın