Son güncelleme: 24 Ekim 2026
Kısa cevap: PHP geliştirici ekibi 21 Ekim 2026'da iki kritik açığı kapatan PHP 8.5.12, 8.4.27, 8.3.36 ve 8.2.35 sürümlerini yayımladı. CVE-2026-109618 ve CVE-2026-109619 numaralı açıklar, oturum açmamış bir saldırganın hazırlanmış HTTP istekleriyle sunucuda kod çalıştırmasına imkân verebiliyor. İki açığın CVSS puanı da 9.2. Web isteği işleyen bütün PHP kurulumları risk altında. Kalıcı çözüm yalnızca güncellemek. Ayar değişiklikleri bazı saldırı yollarını daraltır ama sunucuyu güvenli hale getirmez.
PHP'deki açıklar genellikle bir CMS eklentisinden ya da kötü yazılmış bir formdan çıkar. Bu kez durum farklı. Sorun PHP motorunun kendisinde. Uygulama kodunuz ne kadar temiz olursa olsun, PHP sürümünüz eskiyse risk sizi de kapsıyor. Bu yazıda açığın nereden çıktığını, neleri etkilediğini, sitenizde PHP yoksa bile sunucuda neye bakmanız gerektiğini ve kontrol için kullanabileceğiniz komutları anlatıyorum.
Ne oldu, açık nereden çıktı?
PHP güvenlik ekibi 20 Ekim 2026'da kritik bir güvenlik sürümünün yolda olduğunu önceden duyurdu. Yamalar ertesi gün 13.30 UTC'de yayımlandı. Aynı gün ABD'de CISA ve NSA, Avrupa'da CERT-EU uyarı yayımladı. Hollanda Ulusal Siber Güvenlik Merkezi (NCSC-NL) açıklar için "php2shell" adıyla bir bilgi deposu açtı. Bu depoda PHP içeren üçüncü taraf yazılımların listesi tutuluyor. Türkiye'de de Siber Güvenlik Başkanlığı aynı gün ulusal ölçekte tarama başlattı. Türkiye'ye ait rakamlar için ayrı yazıya bakabilirsiniz.
CERT-EU'nun notuna göre teknik ayrıntılar herkese açık şekilde konuşuluyor ve ilk kavram kanıtı kodları dolaşmaya başladı. Yani konu teorik değil. Saldırganların bu açıkları şimdiden denediğini varsaymak gerekiyor.
İki açık da PHP'nin belleği yönetme biçimiyle ilgili.
CVE-2026-109618: Bellek yetmediğinde yarım kalan istek
PHP, bir istek memory_limit sınırını aştığında işlemi anında keser. Bunun için içeride longjmp() adlı bir mekanizma kullanır. Sorun, bu kesintinin istek verisi henüz tam hazırlanmamışken gelmesiyle başlıyor. Form üzerinden gelen bir dosya yükleme isteği ayrıştırılırken bellek biterse istek yarım kalır. Ardından çalışan temizlik aşaması bu yarım veriyi geçerli sanır ve hiç hazırlanmamış belleği serbest bırakmaya çalışır. O bellek alanında saldırganın önceki adımlarda yerleştirdiği veri bulunabilir. Bu da bellek bozulmasına ve sonunda kod çalıştırmaya kadar gidebilir.
Danışma notu bu durumun nasıl tetiklenebildiğini de açıklıyor. Çok parçalı (multipart) isteklerin ayrıştırılmasındaki bazı davranışlar, bir isteğin post_max_size sınırının altında kalırken memory_limit değerini tüketmesine izin veriyor. Örneğin geçerli bir uzunluk bilgisi taşımayan istekler, tek bir parçaya sınırsız sayıda başlık eklenmesi ya da max_file_uploads sayımına girmeyen boş dosya alanları bu etkiyi yaratabiliyor.
CVE-2026-109619: Bir önceki istekten kalan durum
PHP-FPM ya da Apache mod_php gibi kurulumlarda tek bir işçi süreç art arda birçok isteğe hizmet eder. Hata, oturum ve nesne bilgisi gibi bazı genel değişkenler o anki isteğin belleğini gösterir ve istek bitince sıfırlanmaları gerekir. Ölümcül bir hata ya da kapanış sırasında üretilen bir uyarı bu sıfırlamanın atlanmasına yol açabiliyor. İsteğin belleği serbest kalıyor ama genel değişken hâlâ o adresi gösteriyor. Aynı işçinin aldığı sonraki istek, normal başlatma adımları çalışmadan bu eski bilgiyi kullanırsa serbest bırakılmış bellek yeniden kullanılmış oluyor. Bu hata türüne "use after free" deniyor. Bellek düzeni dikkatle hazırlandığında sonuç tam yetkili kod çalıştırma olabiliyor.
23 Ekim'de duyurulan üçüncü açık: CVE-2026-115560
PHP ekibi 23 Ekim'de ek bir bilgilendirme yaptı. Yeni açık yalnızca alışılmadık bir yapılandırmada ortaya çıkıyor. Uygulamanın session.serialize_handler değerini yapılandırmada php_binary ya da php_serialize olarak tanımlaması, sonra çalışma anında ini_set() ile php değerine çevirmesi ve bunu session_start() öncesinde yapması gerekiyor. Oturum yükleme ilerlemesi özelliğinin de açık olması şart. PHP ekibi bu açık için ayrı bir acil sürüm çıkarmayacak. Bir sonraki düzenli sürüme kadar session.upload_progress.enabled=0 ayarının kullanılmasını öneriyor. Bu ayar zaten CVE-2026-109619 için önerilen geçici önlemler arasında. 21 Ekim'de uyguladıysanız yerinde bırakmanız yeterli.
Hangi sürümler ve kurulumlar etkileniyor?
| PHP dalı | Etkilenen sürümler | Yamalı sürüm |
|---|---|---|
| 8.5 | 8.5.12 öncesi | 8.5.12 |
| 8.4 | 8.4.27 öncesi | 8.4.27 |
| 8.3 | 8.3.36 öncesi | 8.3.36 |
| 8.2 | 8.2.35 öncesi | 8.2.35 |
| 8.1 ve daha eski | Hepsi | Resmi yama yok |
PHP 8.1 ve öncesi artık PHP projesinden güncelleme almıyor. Açıklar çok ciddi olduğu için güvenlik ekibi PHP 7.4, 8.0 ve 8.1 için kaynak kodu düzeyinde asgari yamalar yayımladı. Bu yamalar kendi derlemesini yapanlar ve uzun süreli destek sağlayıcısı olmayanlar için düşünüldü. Linux dağıtımları ve LTS sağlayıcıları da kendi paketlerine düzeltme ekliyor. PHP 8.2 için bir not daha var: Bu dal 31 Aralık 2026'da destek dışı kalıyor ve 8.2.35 onun son güvenlik sürümü. Yükseltme planı yapmak için iyi bir zaman.
Etkilenen çalışma biçimleri şunlar: PHP-FPM, Apache mod_php, php-cgi, FrankenPHP ve LiteSpeed. PHP ekibi en yüksek riski mod_php'de görüyor. Gösterilen istismarda kimlik doğrulaması olmayan tek bir istek, uygulama kodu daha hiç çalışmadan saldırıyı başlatabiliyor.
Uygulamalar ve ürünler
WordPress, Laravel, Drupal, Magento, Joomla ya da kendi yazdığınız bir PHP uygulaması fark etmez. Açık motorda olduğu için tema, eklenti veya çekirdek güncellemesi sorunu çözmez. Yalnızca PHP'nin kendisini güncellemek çözer.
Siteniz PHP kullanmasa bile sunucuda PHP ile çalışan başka araçlar olabilir. cPanel ve Plesk gibi barındırma panelleri, phpMyAdmin, Roundcube gibi webmail arayüzleri, Nextcloud, bazı ağ cihazları ve NAS yönetim ekranları bunlara örnek. NCSC-NL'in php2shell deposundaki yazılım listesi bu konuda işe yarar.
Saldırgan içeri girerse ne olur?
Başarılı bir saldırıda kod, PHP sürecinin çalıştığı kullanıcı yetkisiyle çalışır. Linux'ta bu genellikle www-data, apache ya da nginx kullanıcısıdır. Bu yetkiyle web kök dizinindeki dosyalar okunabilir ve değiştirilebilir. .env ve wp-config.php gibi dosyalardaki veritabanı parolaları ile API anahtarları ele geçirilebilir. Kalıcı bir arka kapı bırakılabilir. Paylaşımlı barındırmada yan sitelere geçilebilir ve iç ağdaki diğer sistemlere ilerlenebilir. PHP yüksek yetkiyle çalışıyorsa, örneğin Windows'ta SYSTEM hesabıyla, sunucunun tamamı tehlikeye girer.
Sitemde PHP uygulaması yok ama sunucuda PHP kurulu. Risk var mı?
Bu sorunun cevabı tek bir şeye bağlı: Sunucudaki PHP dışarıdan gelen bir web isteğini işleyebiliyor mu?
Sadece komut satırı varsa: PHP yalnızca CLI olarak kuruluysa ve web sunucusuna bağlı değilse, bu iki açık için doğrudan uzaktan saldırı yolu görünmüyor. Açıklar HTTP isteklerinin ayrıştırılması ve işçi süreçlerin istekler arasında taşıdığı durum üzerinden çalışıyor. Yine de bu kurulumu güncelleyin ya da kaldırın. Biri ileride PHP'yi web sunucusuna bağlarsa risk aynı gün geri gelir. Güncel olmayan bir PHP başka açıklar da taşır.
Web sunucusuna bağlıysa ama site kullanmıyorsa: Asıl tehlikeli senaryo bu. Apache'de PHP modülü yüklü kalmış, Nginx'te location ~ \.php$ bloğu duruyor ya da IIS'te *.php işleyici eşlemesi silinmemiş olabilir. Bu durumda sunucunun bir köşesinde unutulmuş tek bir dosya saldırganın PHP'ye istek ulaştırması için yeterli. Bu dosya eski bir phpinfo.php, kurulumdan kalan bir index.php, bir test dosyası ya da taşınmış ama silinmemiş bir WordPress klasörü olabilir. İşleyici dosyanın var olup olmadığına bakmadan PHP'yi çağırıyorsa dosyaya bile gerek kalmayabilir. IIS'te işleyici ayarlarındaki "Request Restrictions" bölümü bu yüzden önemli.
Yönetim araçları: Siteniz .NET ya da Node.js ile çalışsa bile aynı sunucudaki barındırma paneli, phpMyAdmin veya webmail PHP ile çalışıyor olabilir. Bunlar internete açıksa saldırı yüzeyinin parçasıdır.
Unutulmuş geliştirme ortamları: php -S 0.0.0.0:8000 komutuyla açılıp kapatılmamış bir geliştirme sunucusu ya da eski bir PHP imajıyla çalışmaya devam eden bir Docker konteyneri de web isteği işler. Duyuruda geliştirme sunucusu ayrıca anılmıyor ama web isteği işlediği için aynı şekilde ele almak gerekir.
Paylaşımlı barındırma: PHP sağlayıcının sunucusunda çalışır. Panelinizdeki PHP sürüm seçicisinden sürüme bakın ve sağlayıcınıza yamaların uygulanıp uygulanmadığını sorun.
Bu senaryonun ne kadar gerçek olduğunu gösteren yakın bir örnek var. Haziran 2024'te yayımlanan CVE-2024-4577, Windows'ta php-cgi kullanan kurulumları etkiliyordu. XAMPP gibi paketlerin varsayılan ayarlarında da sorun çıkıyordu. Sahipleri tarafından unutulmuş çok sayıda kurulum kısa sürede fidye yazılım gruplarının hedefi oldu. Bu sunucuların önemli bir kısmında aktif bir PHP uygulaması bile yoktu.
Özetle PHP kullanmıyorsanız en güvenli seçenek, web sunucusuyla bağlantısını kesmek ve paketleri kaldırmaktır.
Sunucunuzu nasıl kontrol edersiniz?
Aşağıdaki komutlar yalnızca sürüm, yapılandırma ve iz bilgisi okur. Sadece kendi yönettiğiniz sistemlerde çalıştırın.
1. PHP nerede ve hangi sürüm? (Linux)
# Yüklü PHP ikili dosyaları
ls -l /usr/bin/php* /usr/sbin/php-fpm* /usr/local/bin/php* 2>/dev/null
# Komut satırı sürümü
php -v
# Debian ve Ubuntu paketleri
dpkg -l | grep -E '^ii\s+php'
# RHEL, AlmaLinux ve Rocky paketleri
rpm -qa | grep -i '^php'
# Çalışan PHP süreçleri ve dinlenen portlar
ps -eo user,pid,cmd | grep -E '[p]hp'
sudo ss -ltnp | grep -i php
2. Dağıtım paketlerinde sürüm numarasına aldanmayın
Ubuntu, Debian ve RHEL gibi dağıtımlar güvenlik düzeltmelerini çoğu zaman eski sürüm numarasının üzerine uygular. Bu yönteme "backport" deniyor. Bu yüzden php -v çıktısı 8.3.36'nın altında görünse bile paket yamalanmış olabilir. Emin olmak için paketin değişiklik kaydında CVE numarasını arayın:
# Debian ve Ubuntu (paket adını kendi kurulumunuza göre değiştirin)
apt changelog php8.3-fpm 2>/dev/null | grep -m3 -E 'CVE-2026-10961[89]'
# RHEL tabanlı sistemler
rpm -q --changelog php-fpm | grep -m3 -E 'CVE-2026-10961[89]'
Çıktıda iki CVE numarası da görünüyorsa paketiniz yamalı demektir. Hiç çıktı gelmiyorsa güncelleme henüz kurulmamıştır.
3. Toplu sürüm kontrol betiği (Linux)
Sunucuda birden fazla PHP sürümü olabilir. Panel kullanan sunucularda bu çok yaygındır. Aşağıdaki betik bilinen dizinlerdeki bütün PHP ikili dosyalarını tarar ve her birini yamalı sürümle karşılaştırır:
#!/usr/bin/env bash
# php-yama-kontrol.sh
# PHP ikili dosyalarını 21 Ekim 2026 yamalı sürümleriyle karşılaştırır.
shopt -s nullglob
minimum_for() {
case "$1" in
8.5) echo "8.5.12" ;;
8.4) echo "8.4.27" ;;
8.3) echo "8.3.36" ;;
8.2) echo "8.2.35" ;;
*) echo "" ;;
esac
}
for bin in /usr/bin/php* /usr/sbin/php-fpm* /usr/local/bin/php* /usr/local/sbin/php-fpm* \
/opt/cpanel/ea-php*/root/usr/bin/php* /opt/alt/php*/usr/bin/php*; do
name=$(basename "$bin")
[[ "$name" =~ ^php(-fpm|-cgi)?[0-9.]*$ ]] || continue
[ -x "$bin" ] || continue
full=$("$bin" -v 2>/dev/null | head -n1 | awk '{print $2}')
[ -n "$full" ] || continue
ver=${full%%[-+~]*}
branch=${ver%.*}
min=$(minimum_for "$branch")
if [ -z "$min" ]; then
printf '%-45s %-10s destek dışı dal, yükseltin veya kaldırın
' "$bin" "$ver"
elif [ "$(printf '%s
%s
' "$min" "$ver" | sort -V | head -n1)" = "$min" ]; then
printf '%-45s %-10s yamalı sürüm
' "$bin" "$ver"
else
printf '%-45s %-10s güncel değil, en az %s gerekli (paket kaydına da bakın)
' "$bin" "$ver" "$min"
fi
done
Kullanmak için dosyayı kaydedin, chmod +x php-yama-kontrol.sh ile çalıştırma izni verin ve sudo ./php-yama-kontrol.sh komutunu çalıştırın. "Güncel değil" görünen bir dağıtım paketi için 2. adımdaki değişiklik kaydı kontrolünü de yapın.
4. Web sunucusu PHP'ye bağlı mı?
# Apache: PHP modülü yüklü mü?
apache2ctl -M 2>/dev/null | grep -i php # Debian ve Ubuntu
httpd -M 2>/dev/null | grep -i php # RHEL tabanlı
# Nginx: PHP istekleri bir yere aktarılıyor mu?
sudo nginx -T 2>/dev/null | grep -nE 'fastcgi_pass|\.php'
# Web kök dizinlerinde unutulmuş PHP dosyaları
sudo find /var/www /srv /home -type f -name '*.php' 2>/dev/null | head -n 50
Apache çıktısında php_module görüyorsanız mod_php kullanıyorsunuz demektir. Bu en yüksek riskli kurulum. Nginx çıktısında fastcgi_pass satırı varsa istekler PHP-FPM'e aktarılıyor.
5. Windows ve IIS
Windows sunucularda PHP genellikle C:\PHP altında ya da XAMPP, WAMP gibi paketlerin içinde bulunur. Aşağıdaki PowerShell betiği bütün diskleri tarar. Disk büyükse birkaç dakika sürebilir.
# Diskteki PHP kopyaları ve yama durumu
$minimum = @{ '8.5' = '8.5.12'; '8.4' = '8.4.27'; '8.3' = '8.3.36'; '8.2' = '8.2.35' }
Get-PSDrive -PSProvider FileSystem | ForEach-Object {
Get-ChildItem -Path $_.Root -Recurse -File -Include php.exe, php-cgi.exe -ErrorAction SilentlyContinue
} | ForEach-Object {
$line = & $_.FullName -v 2>$null | Select-Object -First 1
if (-not $line) { return }
$text = ($line -split ' ')[1] -replace '[^0-9.].*$', ''
$ver = [version]$text
$branch = "$($ver.Major).$($ver.Minor)"
$status = if (-not $minimum.ContainsKey($branch)) { 'destek dışı dal' }
elseif ($ver -ge [version]$minimum[$branch]) { 'yamalı' }
else { "güncel değil, en az $($minimum[$branch])" }
[pscustomobject]@{ Dosya = $_.FullName; Surum = $text; Durum = $status }
} | Format-Table -AutoSize
PHP'nin IIS'e bağlı olup olmadığını görmek için işleyici eşlemelerine ve FastCGI kayıtlarına bakın:
Import-Module WebAdministration
# Sunucu düzeyindeki PHP işleyicileri
Get-WebConfiguration -Filter 'system.webServer/handlers/add' -PSPath 'MACHINE/WEBROOT/APPHOST' |
Where-Object { $_.path -like '*.php*' -or $_.scriptProcessor -like '*php*' } |
Select-Object name, path, scriptProcessor, resourceType
# Site düzeyindeki PHP işleyicileri
Get-Website | ForEach-Object {
$site = $_.Name
Get-WebConfiguration -Filter 'system.webServer/handlers/add' -PSPath "IIS:\Sites\$site" |
Where-Object { $_.scriptProcessor -like '*php*' } |
Select-Object @{ n = 'Site'; e = { $site } }, name, path, resourceType
}
# Kayıtlı FastCGI uygulamaları
Get-WebConfiguration -Filter 'system.webServer/fastCgi/application' -PSPath 'MACHINE/WEBROOT/APPHOST' |
Select-Object fullPath, arguments
resourceType değeri Unspecified ise IIS, istenen dosya diskte olmasa bile isteği PHP'ye gönderir. Değer File ise yalnızca gerçekten var olan dosyalar için PHP çağrılır. PHP kullanmayan bir sunucuda bu listelerin boş olması gerekir.
6. Dışarıdan hızlı bakış
curl -sI https://alanadiniz.com | grep -iE '^(server|x-powered-by):'
curl -s https://alanadiniz.com/kontrol-8f3a1c.php | head -c 300; echo
İlk komut sunucunun kendini tanıttığı başlıkları gösterir. X-Powered-By: PHP/8.x.y görüyorsanız sürüm bilgisi dışarıya açık demektir. Bu başlığın görünmemesi güvende olduğunuz anlamına gelmez, çünkü çoğu kurulum onu gizler. İkinci komut var olmayan bir PHP dosyası ister. Yanıt olarak "No input file specified" ya da "File not found." gibi kısa bir metin dönüyorsa istek büyük olasılıkla PHP'ye ulaşıyordur. Web sunucusunun standart 404 sayfası dönüyorsa yönlendirme yok gibi görünür. Bu test kesin sonuç vermez ama ilk bakış için yeterlidir.
7. Çalışan PHP'nin gerçek ayarları
Komut satırındaki PHP ile web isteklerini karşılayan PHP-FPM farklı yapılandırma dosyaları okur. Bu yüzden php -i çıktısı web tarafındaki değerleri yansıtmayabilir.
php --ini
php -i | grep -E '^(memory_limit|post_max_size|upload_max_filesize|session.upload_progress.enabled) '
sudo grep -RnE 'memory_limit|post_max_size|upload_progress|fatal_error_backtraces' /etc/php/*/fpm/ 2>/dev/null
Web tarafındaki gerçek değerleri görmek isterseniz aşağıdaki dosyayı kısa süreliğine web kök dizinine koyabilirsiniz. Bu dosyayı yalnızca zaten PHP çalıştıran bir sitede kullanın ve kontrol bitince hemen silin. PHP kullanmayan bir sunucuya yeni bir PHP dosyası eklemeyin.
<?php
// Kontrol bitince bu dosyayı silin.
$token = 'BURAYA-UZUN-VE-RASTGELE-BIR-DEGER-YAZIN';
if (!hash_equals($token, (string)($_GET['t'] ?? ''))) {
http_response_code(404);
exit;
}
header('Content-Type: text/plain; charset=utf-8');
echo 'PHP ', PHP_VERSION, ' / ', PHP_SAPI, "
";
$keys = ['memory_limit', 'post_max_size', 'upload_max_filesize',
'max_input_vars', 'session.upload_progress.enabled'];
if (PHP_VERSION_ID >= 80500) {
$keys[] = 'fatal_error_backtraces';
}
foreach ($keys as $key) {
echo str_pad($key, 34), var_export(ini_get($key), true), "
";
}
8. Docker konteynerleri
docker ps --format '{{.Names}}' | while read -r c; do
printf '%-30s ' "$c"
docker exec "$c" sh -c 'command -v php >/dev/null && php -v | head -n1 || echo "PHP yok"'
done
Resmi php imajlarını kullanan konteynerler, imaj yeniden çekilip yeniden derlenmeden güncellenmez.
Çözüm: PHP'yi güncelleyin
Kalıcı tek çözüm yamalı sürüme geçmek. Güncellemeden sonra bütün PHP işçi süreçlerini yeniden başlatın. Yalnızca yapılandırmayı yeniden yüklemek bazı durumlarda eski süreçleri ayakta bırakabilir.
Debian ve Ubuntu:
sudo apt update
sudo apt install --only-upgrade 'php*'
sudo systemctl restart php8.3-fpm # sürüm numarasını kendi kurulumunuza göre değiştirin
sudo systemctl restart apache2 # mod_php kullanıyorsanız
RHEL, AlmaLinux ve Rocky:
sudo dnf upgrade 'php*'
sudo systemctl restart php-fpm httpd
Remi deposundan PHP kuranlar dikkatli olmalı. CERT-EU'nun notuna göre bu gönüllü depo duyuru günü güncellenmedi. PHP ekibi de bu kullanıcılara dağıtımın kendi paketlerine geçmelerini ya da kaynaktan derlemelerini önerdi.
Windows ve IIS: Yamalı sürümü php.net indirme sayfasından alın. Eski klasörü yedekleyin, yeni dosyaları yerine koyun ve php.ini dosyanızı koruyun. Ardından uygulama havuzlarını geri dönüştürün ya da iisreset komutunu çalıştırın.
Docker:
docker pull php:8.3-fpm
docker compose build --pull
docker compose up -d
Sabit bir alt sürüm etiketi kullanıyorsanız, örneğin php:8.3.30-fpm, etiketi yamalı sürümle değiştirmeniz gerekir.
Barındırma panelleri: cPanel, Plesk veya CloudLinux kullanıyorsanız panel güncellemelerini çalıştırın. Ardından PHP sürüm seçicisinde yamalı sürümlerin göründüğünü doğrulayın.
Güncellemeden sonra 3. adımdaki betiği tekrar çalıştırarak sonucu kontrol edin.
Hemen güncelleyemiyorsanız geçici önlemler
PHP ekibi bu önlemlerin sunucuyu güvenli hale getirmediğini açıkça belirtiyor. Bunlar yalnızca bilinen saldırı yollarını daraltır ve güncellemeye kadar zaman kazandırır. Mümkünse internete açık PHP servislerini güncelleme yapılana kadar VPN ya da IP kısıtlaması arkasına alın.
PHP-FPM havuzu için örnek ayarlar:
; /etc/php/8.3/fpm/pool.d/www.conf
php_admin_value[memory_limit] = -1
php_admin_value[post_max_size] = 8M
php_admin_value[upload_max_filesize] = 6M
php_admin_flag[session.upload_progress.enabled] = off
; Yalnızca PHP 8.5 için:
; php_admin_flag[fatal_error_backtraces] = off
Burada php_admin_value ve php_admin_flag kullanılmasının nedeni, uygulamaların bu değerleri ini_set() ile geri değiştirememesi. Dosya yükleme gerektiren uygulamalarda post_max_size için 32M önerilir. upload_max_filesize her zaman bu değerin altında kalmalı. session.upload_progress.enabled ayarını .user.ini ya da ini_set() ile değiştirmek işe yaramaz, çünkü istek ayrıştırılmadan önce geçerli olması gerekir.
Apache mod_php için aynı ayarlar:
<VirtualHost *:443>
php_admin_value memory_limit -1
php_admin_value post_max_size 8M
php_admin_value upload_max_filesize 6M
php_admin_flag session.upload_progress.enabled off
LimitRequestBody 8388608
LimitRequestFields 50
</VirtualHost>
mod_php en riskli kurulum olduğu için uzun vadede PHP-FPM'e geçmeyi değerlendirin.
memory_limit=-1 tek başına bırakılmamalı. Bu ayar PHP'nin kendi bellek sınırını kaldırır ve saldırganın kontrol edebildiği bellek tükenmesini engeller. Ama sınırsız bellek, sunucunun tamamının çökmesine yol açabilir. Bu yüzden servis düzeyinde bir sınır koyun:
# sudo systemctl edit php8.3-fpm
[Service]
MemoryMax=2G
OOMPolicy=continue
OOMPolicy=continue ayarı, bellek sınırı aşıldığında servisin tamamı yerine yalnızca ilgili sürecin sonlandırılmasını sağlar. RLIMIT_AS veya RLIMIT_DATA ile bellek sınırlamayın. Danışma notuna göre bu yöntemler açığı tetikleyen bellek ayırma hatasına yol açabiliyor.
Web sunucusu düzeyinde sınırlar:
client_max_body_size 8m;
large_client_header_buffers 4 8k;
Nginx ve Apache ham istek boyutunu ve başlık sayısını sınırlayabilir. Çok parçalı isteklerdeki parça sayısı ya da iç içe alan derinliği gibi kontroller için bir WAF kuralı gerekir. Bu sınırlar Content-Length taşımayan istekleri de kapsamalı.
Son olarak, saldırganın tetikleyebildiği ölümcül hataları ve zaman aşımlarını giderin. Kapanış sırasında uyarı üreten geçersiz ya da kullanımdan kaldırılmış ayarları temizleyin. Hataları error_reporting, display_errors ya da @ ile gizlemek bu açığa karşı koruma sağlamaz.
PHP'ye ihtiyacınız yoksa kaldırın
Kullanılmayan yazılım, güncellenmesi unutulan yazılımdır.
Debian ve Ubuntu:
sudo systemctl disable --now php8.3-fpm
sudo a2dismod php8.3 && sudo systemctl restart apache2
sudo apt purge 'php8.3*' # silinecek paketler listesini onaylamadan önce okuyun
sudo apt autoremove
RHEL tabanlı sistemler:
sudo dnf remove 'php*'
IIS: Önce 5. adımdaki listeden işleyicinin adını bulun, sonra işleyiciyi ve FastCGI kaydını silin:
Remove-WebHandler -Name 'PHP_via_FastCGI' -PSPath 'IIS:'
Clear-WebConfiguration "/system.webServer/fastCgi/application[@fullPath='C:\PHP\php-cgi.exe']" -PSPath 'MACHINE/WEBROOT/APPHOST'
Ardından PHP klasörünü ve web kök dizinlerinde kalmış .php dosyalarını kaldırın.
Saldırıya uğradım mı? İz arama
Güncelleme yeni saldırıları durdurur ama içeri yerleşmiş bir saldırganı çıkarmaz. Sunucunuz yamadan önce internete açıksa aşağıdaki kontrolleri yapın. Örneklerde www-data kullanıcısı var. RHEL tabanlı sistemlerde bunu apache ya da nginx ile değiştirin.
# Bellek bozulması denemeleri çoğu zaman çökme kaydı bırakır
sudo journalctl --since '2026-10-20' | grep -iE 'php.*(segfault|SIGSEGV|exited on signal)'
sudo dmesg -T | grep -iE 'php.*segfault'
# Web sunucusu kullanıcısının başlattığı beklenmedik süreçler
ps -u www-data -o pid,ppid,etime,cmd --forest
# 20 Ekim'den sonra değişen PHP dosyaları
sudo find /var/www -type f -name '*.php' -newermt '2026-10-20' -ls
# PHP süreçlerinin dışarıya açtığı bağlantılar
sudo ss -tnp | grep -i php
PHP-FPM kayıtlarında art arda gelen exited on signal 11 (SIGSEGV) satırları, PHP sürecinin altında çalışan sh, bash, curl veya wget gibi süreçler ve sizin yüklemediğiniz yeni PHP dosyaları ciddi işaretlerdir. Böyle bir iz bulursanız sunucuyu ağdan ayırın ve kayıtları silmeden saklayın. Veritabanı parolalarını, API anahtarlarını ve panel şifrelerini değiştirin. Mümkünse sistemi temiz bir kurulumdan yeniden ayağa kaldırın.
Sık sorulan sorular
PHP sürümümü nasıl öğrenirim?
Sunucuda php -v komutu komut satırı sürümünü gösterir. Web tarafında çalışan sürüm farklı olabilir. Bunun için php-fpm8.3 -v gibi FPM ikili dosyasına bakın ya da panelinizdeki PHP sürüm ekranını kontrol edin.
WordPress'i ve eklentilerini güncellemem yeterli mi?
Hayır. Açık PHP motorunda. WordPress güncel olsa bile PHP 8.3.36 öncesindeyse risk devam eder.
X-Powered-By başlığı görünmüyorsa güvende miyim?
Hayır. Bu başlık yalnızca bilgi verir ve çoğu kurulumda gizlenir. Saldırganlar sürüm bilgisine bakmadan da deneme yapabilir.
Cloudflare ya da bir WAF kullanmak yeterli mi?
WAF bazı bilinen istek kalıplarını engelleyebilir ve zaman kazandırır. Yamanın yerini tutmaz.
PHP 7.4 kullanıyorum, ne yapmalıyım?
7.4, 8.0 ve 8.1 için resmi sürüm yok. Dağıtımınızın ya da LTS sağlayıcınızın yamalı paketini kurun. Bu mümkün değilse desteklenen bir sürüme geçin. 8.2'nin de yıl sonunda destek dışı kalacağını hesaba katarak 8.4 veya 8.5'i hedefleyin.
Barındırma firmam güncelledi mi, nasıl anlarım?
Paneldeki PHP sürüm seçicisinde sürüm numarasına bakın. Numara eski görünüyorsa firmaya CVE-2026-109618 ve CVE-2026-109619 için yama uygulanıp uygulanmadığını yazılı olarak sorun.
memory_limit=-1 kalıcı olarak kullanılabilir mi?
Hayır. Bu yalnızca güncellemeye kadar kullanılacak bir önlem ve servis düzeyinde bir bellek sınırıyla birlikte uygulanmalı. Güncellemeden sonra uygulamanıza uygun bir değere dönün.
Kaynaklar
- PHP haber arşivi, Ekim 2026 güvenlik duyuruları
- GHSA-w8hw-w9fx-j79w: RCE via OOM corruption (CVE-2026-109618)
- GHSA-6wmf-4rv5-p3rp: RCE via stale global state (CVE-2026-109619)
- CERT/CC VU#763488
- CERT-EU Security Advisory 2026-018
- CISA: Critical Vulnerabilities in PHP Require Immediate Patching
- NCSC-NL php2shell bilgi deposu
- The PHP Foundation duyurusu