Pe 21 octombrie 2026, echipa PHP a publicat patch-uri de urgență pentru două vulnerabilități critice, CVE-2026-109618 și CVE-2026-109619, numite împreună „PHP2Shell”. Ambele permit execuție de cod de la distanță (RCE) fără autentificare. Atacul are loc înainte să ruleze codul aplicației, deci nu contează dacă site-ul tău e scris corect. Contează doar versiunea de PHP de pe server.
Ce este PHP2Shell, pe scurt
- CVE-2026-109618: RCE prin coruperea memoriei la out-of-memory. Un request multipart forțează PHP să rămână fără memorie în timpul parsării, iar curățarea request-ului folosește apoi date inițializate doar parțial.
- CVE-2026-109619: RCE prin stare globală rămasă de la un request anterior (use-after-free). Un request ulterior, servit de același worker, folosește memorie deja eliberată. Calea confirmată trece prin session.upload_progress.
Codul rulează cu drepturile utilizatorului serverului web (www-data, apache, nobody sau userul contului pe serverele cu PHP-FPM per cont). Vulnerabilitățile au fost descoperite de cercetători de la Calif, OpenAI și Wiz. watchTowr spune că a observat deja exploatare în rețeaua sa de honeypot-uri. CISA a emis o alertă pe 21 octombrie și cere patch imediat.
Cine este afectat
Orice instalare PHP care servește request-uri web: Apache mod_php, PHP-FPM, php-cgi, LiteSpeed (LSAPI) și FrankenPHP. Riscul cel mai mare este la mod_php.
| Ramură | Vulnerabil | Versiune reparată |
|---|---|---|
| 8.5 | < 8.5.12 | 8.5.12 |
| 8.4 | < 8.4.27 | 8.4.27 |
| 8.3 | < 8.3.36 | 8.3.36 |
| 8.2 | < 8.2.35 | 8.2.35 |
| 7.4, 8.0, 8.1 | toate | fără release oficial; doar backport-uri de la distribuție/vendor LTS sau patch-uri minime din sursă |
| 7.3 și mai vechi (inclusiv PHP 5) | toate | nicio reparație, trebuie migrat |
Atenție la PHP-ul ascuns în produse: panouri de administrare, appliance-uri, imagini Docker, routere cu interfață web.
Cum verifici serverul
Versiunea din linia de comandă și ce rulează efectiv pe site pot fi diferite. Verifică ambele.
Versiunea CLI implicită:
php -v
Toate binarele PHP de pe server (inclusiv cele alternative):
find / -xdev -type f -name php -perm -u+x 2>/dev/null \ | while read p; do \ echo "$p: $($p -r 'echo PHP_VERSION;')"; done
Procese PHP care rulează acum:
ps -eo user,cmd \ | grep -E 'php-fpm|php-cgi|lsphp|httpd|apache2'
Ce versiune anunță site-ul (dacă X-Powered-By nu e ascuns):
curl -sI https://domeniul-tau.ro \ | grep -iE 'x-powered-by|server'
Build reparat? Fix-ul adaugă setarea memory_hard_limit_percent:
php -r 'var_dump(ini_get( "memory_hard_limit_percent"));'
Dacă rezultatul e false, build-ul e vechi. Orice altă valoare înseamnă build cu patch (util la backport-urile care păstrează un număr de versiune „vechi”).
OpenAI a publicat pe GitHub un verificator de versiune, nu o reparație: openai/php2shell-checker. Citește headerele site-ului sau instalarea locală și îți spune dacă versiunea anunțată e în zona afectată:
git clone https://github.com/openai/php2shell-checker cd php2shell-checker node phpcheck.js "https://domeniul-tau.ro"
Rezultatul „OK” se bazează doar pe versiunea anunțată în headere. Nu confirmă că serverul are patch-ul. Dacă headerul e ascuns, primești „UNKNOWN”. Reparația propriu-zisă e update-ul de PHP.
Ce trebuie să facă adminii: reparația
1. Update PHP și restart la toate workerele
Debian / Ubuntu (repo-ul distribuției sau ppa:ondrej/php / packages.sury.org):
apt update apt list --upgradable | grep php apt install --only-upgrade 'php*' systemctl restart php*-fpm apache2
RHEL / AlmaLinux / Rocky (Remi sau AppStream):
dnf upgrade 'php*' systemctl restart php-fpm httpd
Fără restart, workerele vechi rămân încărcate în memorie cu codul vulnerabil.
2. Servere CentOS / AlmaLinux cu CWP sau CloudLinux (PHP alternativ în /opt/alt)
Pe aceste servere fiecare site poate rula altă versiune de PHP, instalată separat de PHP-ul sistemului. Fă inventarul complet:
ls -d /opt/alt/php* 2>/dev/null for p in /opt/alt/php*/usr/bin/php; do \ echo "$p: $($p -r 'echo PHP_VERSION;')"; done
- CloudLinux (alt-php): yum update 'alt-php*', apoi restart la LSAPI/PHP-FPM sau la webserver. Verifică în changelog-ul CloudLinux că pachetul include backport-ul pentru cele două CVE-uri.
- CWP: recompilează versiunile de PHP-FPM din PHP Version Switcher / PHP-FPM Selector cu ultimele versiuni minore (8.2.35, 8.3.36, 8.4.27, 8.5.12), apoi repornește serviciile php-fpm*.
- Conturile pe PHP 5.x, 7.0–7.3 nu au reparație. Mută-le pe 8.2+ sau izolează-le până la migrare.
3. Măsuri temporare dacă nu poți face update azi
Echipa PHP spune clar că nicio setare nu elimină complet riscul. Măsurile de mai jos doar reduc expunerea până la update:
Se pun în php.ini, în pool-ul FPM sau în config-ul Apache (nu în .user.ini și nu cu ini_set):
session.upload_progress.enabled = 0 display_errors = Off
Doar pe PHP 8.5:
fatal_error_backtraces = 0
Fără upload-uri pune post_max_size = 8M, cu upload-uri 32M:
post_max_size = 8M upload_max_filesize = 6M
În pool-ul FPM, folosește php_admin_value ca aplicațiile să nu poată suprascrie valorile:
php_admin_value[session.upload_progress.enabled] = 0 php_admin_value[memory_limit] = -1
memory_limit = -1 este recomandarea oficială pentru CVE-2026-109618, dar pune limita de memorie la nivel de container/cgroup ca să nu cadă serverul. Nu folosi RLIMIT_AS/RLIMIT_DATA (ulimit -v), pentru că declanșează exact calea vulnerabilă. După orice schimbare, repornește toate workerele.
4. WAF / ModSecurity și limite la nivel de webserver
CISA spune că un WAF poate oferi o protecție parțială până la update. Limitează request-urile multipart înainte să ajungă la PHP:
Apache:
LimitRequestBody 33554432
ModSecurity:
SecRequestBodyLimit 33554432 SecArgumentsLimit 500 SecRule &ARGS "@gt 500" \ "id:1009618,phase:2,deny,status:413,\ log,msg:'Prea multe campuri'"
Nginx:
client_max_body_size 32m;
Pe CWP, ModSecurity cu regulile OWASP CRS se activează din panoul de administrare. Ține regulile actualizate.
5. Hardening general (bun oricum, nu repară CVE-urile)
disable_functions = exec,passthru, shell_exec,system,proc_open, popen,pcntl_exec open_basedir = /home/USER/public_html:/tmp expose_php = Off allow_url_include = Off
- Fiecare site pe userul lui (PHP-FPM per cont), nu totul sub www-data.
- Fără execuție PHP în folderele de upload (php_admin_flag engine off sau location ~ ^/uploads/.*\.php$ { deny all; }).
- Document root fără drept de scriere pentru userul PHP acolo unde se poate.
Verifică dacă ai fost deja atacat
Caută semne începând cu câteva zile înainte de 21 octombrie:
Erori tipice de exploatare în logurile PHP / Apache / FPM:
grep -rE "zend_mm_heap corrupted|\ in Unknown on line 0|exited on signal" \ /var/log/httpd /var/log/apache2 \ /var/log/php*-fpm* \ /usr/local/apache/logs 2>/dev/null \ | tail -50
POST-uri foarte mari / multe răspunsuri 500 din același IP:
awk '$6=="\"POST" && $9==500 {print $1}' \
/var/log/apache2/access.log \
| sort | uniq -c | sort -rn | head
Procese shell pornite de userul webserverului:
ps -ef --forest \ | grep -E 'www-data|apache|nobody' \ | grep -E 'sh|bash|curl|wget|nc '
Fișiere PHP modificate recent în webroot și uploads:
find /var/www /home/*/public_html \ -name '*.php' -mtime -7 -type f
Webshell-uri: funcții tipice:
grep -rlE \ -e 'eval\(base64_decode|gzinflate\(base64' \ -e 'assert\(\$_(POST|GET|REQUEST)|system\(\$_' \ /var/www /home/*/public_html
Fișiere .php în folderele de upload:
find / -xdev -path '*uploads*' -name '*.php'
Crontab-uri și conexiuni suspecte:
for u in www-data apache nobody; do \ crontab -l -u $u; done ss -tnp | grep -E 'php|sh'
Pentru scanare automată poți folosi Linux Malware Detect (maldet) cu ClamAV. Dacă găsești ceva: izolează contul, schimbă parolele de bază de date, cheile API și sesiunile, pentru că bug-ul de citire a memoriei poate scurge date din procesul PHP. Reinstalează din backup curat, nu „curăța” fișier cu fișier.
Surse
- CISA: Critical Vulnerabilities in PHP Require Immediate Patching (21.10.2026)
- BleepingComputer: PHP ships emergency patches for critical PHP2Shell flaws
- watchTowr: PHP2Shell FAQ
- VulnCheck: măsuri temporare din advisory-ul PHP
- NCSC-NL: informații operaționale și lista de software afectat
- OpenAI: php2shell-checker (verificator de versiune)
Ai un server sau un site pe PHP și nu ești sigur dacă e reparat? Scrie-mi și îl verific, fac update-ul și securizez configurarea.
