PHP2Shell er to kritiske sårbarheder i selve PHP, CVE-2026-109618 og CVE-2026-109619, som kan lade en uautentificeret webforespørgsel køre kode på enhver PHP-installation, der håndterer webforespørgsler: PHP-FPM, Apache med mod_php, php-cgi, FrankenPHP og LiteSpeed. Begge bliver udnyttet i praksis og står i CISA's KEV-katalog. Rettelsen er PHP 8.5.12, 8.4.27, 8.3.36 eller 8.2.35; PHP 8.1 og ældre får ingen udgivelse fra upstream. Opgradér, og genbyg og deploy derefter hvert container-image, der indeholder PHP, inklusive gamle tags, der stadig kører, og images, du har leveret til kunder.
At patche den server, du kender til, er den nemme del. Den eksponering, der bliver hængende, er den PHP, du har glemt: en runtime kompileret ind i et base-image, et image-tag fra sidste år, der stadig kører i produktion, et CI-image eller et produkt leveret til kunder med en PHP, der har nået end of life. Denne side får dig patchet først og viser derefter, hvordan du finder resten.
Hvad der skete
| Dato (2026) | Hændelse | Kilde |
|---|---|---|
| 11. og 21. august | Calif rapporterer de to fejl til PHP-projektet | Calif |
| 17. oktober | Det første udnyttelsesforsøg, Amazon så i sine honeypots, før offentliggørelsen | Amazon Threat Intelligence |
| 20. oktober | PHP varsler en sikkerhedsudgivelse den 21. oktober kl. 14.00 UTC, der retter to sårbarheder vurderet til CVSS 4.0 9,2 | php.net |
| 21. oktober | PHP udgiver 8.5.12, 8.4.27, 8.3.36 og 8.2.35 og offentliggør sin advisory; CVE-posterne bliver offentlige; NCSC-NL åbner sit repository php2shell | PHP's advisory, NCSC-NL |
| 21. oktober | De officielle Docker-images php bliver opdateret til de rettede versioner | docker-library/php |
| 21. oktober | watchTowr rapporterer, at begge CVE'er bliver udnyttet i praksis; CISA udsender en advarsel | watchTowr, CISA |
| 22. oktober | Searchlight Cyber udgiver php2shell-scanner | GitHub |
| 23. oktober | PHP anbefaler at sætte session.upload_progress.enabled=0 mod en separat, usandsynlig RCE-vej, CVE-2026-115560 | php.net |
| 26. oktober | CISA føjer begge CVE'er til KEV-kataloget med 29. oktober som frist for amerikanske føderale myndigheder | CISA KEV |
Navnet PHP2Shell stammer fra Califs gennemgang og bruges bredt i branchens dækning; PHP's egne advisories bruger det ikke. CVE-posterne krediterer Calif, Wiz og OpenAI.
Hvem er berørt
Al PHP, der håndterer webforespørgsler. PHP's advisory nævner PHP-FPM, Apache med mod_php, php-cgi, FrankenPHP og LiteSpeed og vurderer risikoen som størst for mod_php, "med en demonstreret exploit, hvor en uautentificeret forespørgsel kan udløse angrebet, før nogen applikationskode kører." Fordi fejlene sidder i selve PHP, er applikationer bygget på Laravel, Symfony eller WordPress eksponeret, når PHP under dem er det.
| Branch | Berørt | Rettet i | Support fra upstream |
|---|---|---|---|
| 8.5 | før 8.5.12 | 8.5.12 | Aktiv |
| 8.4 | før 8.4.27 | 8.4.27 | Aktiv |
| 8.3 | før 8.3.36 | 8.3.36 | Kun sikkerhedsrettelser, til og med 31. december 2027 |
| 8.2 | før 8.2.35 | 8.2.35 | Kun sikkerhedsrettelser, til og med 31. december 2026 |
| 8.1, 8.0, 7.4 | alle versioner, ifølge Calif og watchTowr | ingen udgivelse; minimale backports i kildekode i php-src | End of life |
| 7.3 og ældre, inklusive PHP 5 | alle versioner, ifølge Calif og watchTowr | ingen rettelse fra upstream | End of life |
PHP's advisories nævner kun de understøttede branches. For ældre rapporterer Calif, at "den tidligste berørte kodesti, vi fandt, går tilbage til PHP 5.4.0", og watchTowr angiver PHP 7 og PHP 5 som berørt uden rettelse. PHP siger, at branches 8.1 og ældre "ikke længere modtager opdateringer fra PHP-projektet", men offentliggjorde minimale backports i kildekode til 7.4, 8.0 og 8.1 til dem, der bygger fra kildekode. Nogle distributioner og kommercielle leverandører af langtidssupport leverer backportede rettelser til branches, der har nået end of life; spørg din. Hvis du tester den næste hovedversion, indeholder PHP 8.6.0 RC4, der blev udgivet samme dag, også rettelserne.
Sådan virker det
Begge CVE'er er hukommelsessikkerhedsfejl i den måde, PHP sætter en forespørgsel op og river den ned på, under al applikationskode. CVE-posterne klassificerer begge som use after free (CWE-416) sammen med forkert håndtering af undtagelsestilstande, adgang via en uinitialiseret pointer, ukontrolleret hukommelsesallokering og forkert initialisering (CWE-755, CWE-824, CWE-1325, CWE-1419). Med PHP's egne ord:
- CVE-2026-109618, RCE via OOM-korruption: "håndteringen af manglende hukommelse kan afbryde PHP, mens interne forespørgselsdata kun er delvist initialiseret. Oprydningen efter forespørgslen kan så behandle de ugyldige data som gyldige." En forespørgselskrop, der er lavet til at opbruge hukommelsen, mens PHP parser den, kan udløse den afbrydelse. Apache med mod_php kører oprydningen, selv når opstarten af forespørgslen mislykkedes, og derfor virker angrebet der, før nogen applikationskode kører. For PHP-FPM siger PHP's advisory, at analyse af kildekoden taler for, at den er sårbar, selvom ingen komplet exploit mod FPM er blevet demonstreret.
- CVE-2026-109619, RCE via forældet global tilstand: "intern tilstand, der ejes af en forespørgsel, kan overleve, efter at hukommelsen bag den er frigivet. En senere forespørgsel, der håndteres af den samme worker, kan bruge den forældede tilstand, før den normale initialisering nulstiller den." Det kræver to forespørgsler, der når den samme worker: en, der efterlader tilstanden, for eksempel gennem en fatal fejl, og en, der bruger den. PHP's advisory bekræfter vejen via session upload progress mod mod_php og FPM og vejen via backtraces ved fatale fejl i PHP 8.5 mod mod_php.
Derfor er PHP's midlertidige indstillinger rettet mod hukommelsesgrænser, størrelsen på forespørgselskroppen, session upload progress og backtraces ved fatale fejl: Hver af dem lukker én vej til fejlene, ikke fejlene selv. PHP vurderer som CNA begge til 9,2 efter CVSS 4.0. NVD's egne vurderinger efter CVSS 3.1 er 9,8 for CVE-2026-109618 og 8,1 for CVE-2026-109619.
Sådan tjekker du, om du er berørt
Start med de hosts, du kender, og led derefter efter PHP i alt, hvad du bygger og leverer.
På en host eller VM tjekker du den version, PHP rapporterer. Tjek også web-SAPI'en, da php-fpm eller Apache-modulet kan komme fra en anden pakke end kommandolinjen:
php -v
php-fpm -v
Distributionspakker (Debian, Ubuntu, Alpine, RHEL) får ofte rettelsen som en backport uden en ny upstream-version: Ubuntu 24.04 leverer for eksempel rettelsen som 8.3.6-0ubuntu0.24.04.13. Her vildleder et versionstjek alene. List den installerede pakke, og sammenlign den med den rettede pakkeversion i din distributions security tracker:
dpkg -l 'php*' | grep '^ii' # Debian, Ubuntu
apk info -v | grep '^php' # Alpine
rpm -qa 'php*' # RHEL, Fedora, Rocky, Alma
I container-images. Officielle php:-images kompilerer PHP fra kildekode, så versionen ligger i selve imaget, ikke i en pakkeliste fra distributionen. Spørg imaget direkte:
docker run --rm --entrypoint php php:8.3-fpm -v
For at tjekke hvert image, du faktisk kører, lister du dem og spørger hvert enkelt. For Kubernetes:
kubectl get pods -A \
-o jsonpath='{range .items[*]}{range .spec.containers[*]}{.image}{"\n"}{end}{end}' \
| sort -u \
| while read -r image; do
version=$(docker run --rm --entrypoint php "$image" -r 'echo PHP_VERSION;' 2>/dev/null)
printf '%s\t%s\n' "${version:-no php}" "$image"
done
Images bygget FROM debian eller FROM alpine med PHP installeret via pakkehåndteringen kræver pakketjekket ovenfor, kørt inde i imaget.
I dine repositories søger du efter hvert sted, hvor PHP bliver valgt:
git grep -nE '^FROM[[:space:]]+(.*/)?php:' -- '*Dockerfile*' '*.dockerfile'
git grep -nE 'php-version|image:.*php' -- .github/workflows '*.yml' '*.yaml'
Fastlåste tags som php:8.3.30-fpm forbliver sårbare, indtil nogen ændrer dem. Flydende tags som php:8.3-fpm blev genbygget med de rettede versioner fra den 21. oktober, men et image, der blev bygget før da, beholder den gamle PHP, indtil du genbygger det. php-kravet i composer.json siger, hvilke versioner din kode accepterer, ikke hvilken der kører.
I CI. Build- og testjobs bruger ofte deres egen PHP: en php:-servicecontainer, en setup-action med inputtet php-version eller et runner-image. De håndterer ikke produktionstrafik, men de viser, hvilke images og versioner din pipeline producerer.
Eksponerede hosts. Searchlight Cybers php2shell-scanner tester en URL med store multipart-forespørgsler, omkring 29 MiB pr. sti. Kør den kun mod hosts, du har tilladelse til at teste. Dens README advarer om falske positiver på patchet PHP med en lav memory_limit, og når PHP ikke oplyser sin version, kan scanneren ikke skelne en patchet server fra en sårbar. Brug den som et fingerpeg, ikke som bevis. NCSC-NL's repository samler detektionsregler og en liste over produkter, der leveres med PHP, med deres status.
Hvad dagens scanning ikke kan fortælle dig. En scanning af images i dit registry i dag dækker det, du ville deploye i dag. Den dækker ikke en tidligere release, du har leveret til en kunde, det gamle tag, en kunde stadig kører, eller hvilke af dine builds der producerede images med en sårbar PHP. Til det har du brug for en registrering af, hvad hvert build tog ind, pr. release. Se er vi berørt? sådan vurderer du en ny CVE på tværs af dine builds.
Sådan retter du det, og hvad du gør, hvis du ikke kan patche endnu
- Opgradér til 8.5.12, 8.4.27, 8.3.36 eller 8.2.35 eller til din distributions rettede pakke. På 8.1 eller ældre flytter du til en understøttet branch; PHP's backports og leverandørernes builds er nødløsninger.
- Genbyg hvert image fra en rettet base (hent base-imaget igen, eller byg uden cache), og deploy igen. Images, der allerede kører, beholder deres gamle PHP, indtil de bliver erstattet, så genstart også workloads.
- Verificér med tjeklisten nedenfor, mod de kørende containere, ikke kun mod det nye image.
Hvis du ikke kan opgradere endnu, nævner PHP's advisory tiltag, der "mindsker eksponeringen for bestemte angrebsveje, men ikke gør en installation sikker." For CVE-2026-109618:
- "Sæt
memory_limit=-1, helst på en måde, som applikationer ikke kan tilsidesætte, for eksempelphp_admin_valuei FPM-poolen eller Apache-konfigurationen, og tjek, at ingen pool-, mappe- eller applikationsindstilling sætter en endelig grænse igen." - "For applikationer, der ikke kræver filuploads, sæt
post_max_size = 8M. Hvis filuploads er nødvendige, sætpost_max_size = 32M. Holdupload_max_filesizeunderpost_max_size." - Brug en hukommelsesgrænse for containeren eller cgroup'en som tilgængelighedsgrænse, og erstat den ikke med
RLIMIT_ASellerRLIMIT_DATA, "da de kan udløse den sårbare allokeringsfejl."
For CVE-2026-109619:
- "Sæt
session.upload_progress.enabled=0, og genstart hver worker. Brugphp.ini, en FPM-pool eller serverkonfiguration, der gælder før parsingen af forespørgslen. Stol ikke påini_set()eller FPM's.user.ini." - "På PHP 8.5, sæt
fatal_error_backtraces=0, og genstart hver worker."
Tjek, hvad hver worker faktisk kører med:
php-fpm -i | grep -E 'memory_limit|post_max_size|session.upload_progress.enabled'
CISA's advarsel går længere: Organisationer, der ikke kan opdatere med det samme, eller som stadig kører PHP 8.1 eller ældre, "bør tage PHP-baserede systemer offline, indtil de kan patches eller opdateres." Den anbefaler også at holde øje med PHP-workerprocesser, der starter shells eller downloader værktøjer.
Verificér rettelsen
- Spørg den PHP, der kører, ikke det image, du havde tænkt dig at deploye. Kør
php-fpm -v(ellerphp -v) i hver kørende container og på hver host, og bekræft 8.5.12, 8.4.27, 8.3.36, 8.2.35 eller nyere. - Stol ikke på versionsstrengen alene for distributionspakker. Debian, Ubuntu, RHEL og andre distributioner backporter rettelsen til den version, de allerede leverer, så en patchet PHP kan stadig rapportere 8.3.6: Ubuntu 24.04's rettelse er
8.3.6-0ubuntu0.24.04.13. Sammenlign den fulde pakkeversion med din distributions security tracker, eller kig efter CVE'en i pakkens changelog, som som regel nævner den. Fælden virker også den anden vej: En scanner, der kun sammenligner versionsnumre fra upstream, kan markere en backportet pakke som sårbar. - Tjek, at hver workload kører det genbyggede image. Et tag, der nu peger på et rettet image, ændrer ikke en pod, der hentede det gamle. Sammenlign det image-digest, hver container kører, med det digest, du byggede:
kubectl get pods -A \
-o jsonpath='{range .items[*]}{range .status.containerStatuses[*]}{.image}{"\t"}{.imageID}{"\n"}{end}{end}'
- Tjek, at hver worker er genstartet. PHP-FPM og Apache har den gamle kode indlæst, indtil de genstarter; procestjekket under "Tjek for kompromittering" viser dem, der stadig kører den.
- Hvis du stadig er afhængig af de midlertidige indstillinger, så tjek hver pool med kommandoen
php-fpm -iovenfor, og behold dem, indtil opgraderingen er gennemført overalt. - Kør inventeringen igen fra tjekafsnittet på tværs af dit registry, dine CI-images og de releases, kunder kører, ikke kun produktion.
Tjek for kompromittering
PHP2Shell bliver udnyttet i praksis, og Amazon så det første forsøg den 17. oktober 2026, fire dage før rettelsen. Hvis en internetvendt PHP på noget tidspunkt siden da kørte en berørt version uden de midlertidige indstillinger, så tjek den.
Hvor stor eksponeringen er. Optællinger af Shodan-bannere, som Mallory offentliggjorde den 20. oktober, og som CybelAngel rapporterede om, fandt 2,24 millioner internetvendte hosts, der annoncerer PHP; af de cirka 1,5 millioner, der viser en version, kører 883.717 (59 %) en branch uden officiel rettelse. Det er optællinger af hosts, ikke af bekræftet sårbare systemer: Backportede pakker kan se gamle ud og alligevel være patchet, og omkring 740.000 hosts skjuler deres version.
Appliances og produkter, der leveres med PHP. PHP kører også i appliances, netværksudstyr, administrationsgrænseflader og leverandørprodukter, hvor du måske ikke selv kan opdatere den. NCSC-NL's oversigt fulgte 968 sådanne produkter den 9. november 2026: 205 rettet, 215 sårbare, 93 under undersøgelse, 240 afhængige af runtime og 214 ikke berørt. Tjek de produkter separat, og installér leverandørernes opdateringer, så snart de er tilgængelige.
Sørg for, at rettelsen faktisk kører. På hosts og VM'er kører en PHP-FPM-, php-cgi- eller Apache-proces, der startede før opgraderingen, stadig den gamle kode. Dens memory map viser så den erstattede binærfil eller libphp som slettet. Sammenlign også processernes starttidspunkter med tidspunktet for opgraderingen:
for pid in $(pgrep -f 'php-fpm|php-cgi|apache2|httpd|frankenphp'); do
grep -qE '(php|libphp)[^/]*\(deleted\)' "/proc/$pid/maps" 2>/dev/null \
&& echo "PID $pid still runs a replaced PHP"
done
ps -o pid,lstart,args -p "$(pgrep -d, -f 'php-fpm|php-cgi|apache2|httpd|frankenphp')"
Indikatorer fra primære kilder:
- Forespørgsler: POST-forespørgsler med formular-uploads, der indeholder strengen
PHP_SESSION_UPLOAD_PROGRESS, som Amazon Threat Intelligence så i udnyttelsesforsøg. Amazon angiver også kildeadresser (103.216.220.92,31.223.184.166,37.19.200.5,134.209.159.64,103.114.163.188,95.217.98.37), men bemærker, at de tilhører delt anonymiseringsinfrastruktur: Undersøg et match, men behandl det ikke som bevis. - Processer og filer: PHP-workerprocesser, der starter shells eller downloader værktøjer (CISA, der tilføjede en Sigma-detektionsregel den 23. oktober), og uventet procesafvikling eller uventede filændringer på webservere (Amazon).
- Logs: i logs fra Apache, PHP-FPM, reverse proxy og tjenester: advarsler eller core-fejl, der gentages, før scripts kører, fatale fejl og parse-fejl samt
Maximum execution time exceeded. PHP's advisory tilføjer, at "fravær af fejl i logs ikke er et bevis på sikkerhed."
Hvornår du skal gå ud fra, at der er sket en kompromittering. Hvis du finder nogen af disse indikatorer, eller hvis en eksponeret server kørte en berørt PHP uden afhjælpninger, og dine logs ikke kan udelukke udnyttelse, så behandl den som kompromitteret. PHP beskriver konsekvensen som fjernkørsel af kode som web-workerens konto, og den konto kan som regel læse applikationens konfiguration og secrets.
Rotér det, workeren kunne læse. Databaseadgangskoder, API-nøgler og tokens i miljøvariabler og konfigurationsfiler, nøgler, der signerer sessioner eller cookies (og de sessioner, der er signeret med dem), og alle cloud-legitimationsoplysninger, som hosten har adgang til. Rotér, efter at hosten er genbygget, så de nye secrets aldrig ligger på en kompromitteret maskine.
Genbyg i stedet for at rydde op. Erstat en kompromitteret host eller container fra et kendt rent image, og flyt ikke filer over, som workeren kunne skrive, såsom upload-mapper, caches eller genereret kode. Genbrug ikke images, build-caches eller artefakter, der er produceret på en kompromitteret host.
Hvad du skal sige til dine kunder
Hvis du leverer software, der kører på PHP, vil dine kunder spørge. Svar med versioner og handlinger, også før du har alle svarene. Et svar, du kan tilpasse:
PHP2Shell (CVE-2026-109618, CVE-2026-109619) berører PHP-versioner før 8.5.12, 8.4.27, 8.3.36 og 8.2.35 samt alle ældre PHP-branches. [Produkt] version [x til y] leveres med PHP [version] og er berørt; version [z], udgivet [dato], leveres med PHP [rettet version]. Opgradér venligst til [z]. Hvis du ikke kan opgradere med det samme, så anvend PHP-indstillingerne i vores advisory [link], og begræns netværksadgangen til applikationen. [Produkt] version [a til b] er ikke berørt. Vi opdaterer denne meddelelse senest [dato].
Hvis du stadig er ved at tjekke, så sig det, og sig, hvornår du svarer. En første udtalelse og skabeloner til hvert udfald finder du i sådan svarer du kunder efter et forsyningskædeangreb.
Sådan hjælper CRACI
CRACI kører dine GitHub Actions-jobs og registrerer, hvad hvert job trækker ind, mens det bygger, inklusive container-images, apt- og apk-pakker og Composer-pakker, og gemmer hvert tidligere build med dets SBOM. Når en CVE offentliggøres, markerer den løbende genvurdering de tidligere builds, der indeholdt den berørte pakke, så du ser, hvilke releases der var eksponeret og hvor længe, ikke kun hvad dagens scanning finder. Policy gates kan blokere builds, der indeholder en bestemt CVE.
Én begrænsning ved denne hændelse: PHP, der er kompileret ind i et officielt php:-image, kommer ind som en del af imaget, ikke som en pakkedownload. CRACI registrerer den image-reference, hvert build hentede, så søg i dine builds efter php:-tags og ikke kun efter PHP-pakker.
Find hvert build, der leverede en sårbar PHP
Mere om registrering af builds: SBOM'er fra buildet, SBOM'er af Docker-images, hvad container-scanning overser, CISA KEV-kataloget og tendenser i CVE-udgivelser. Andre hændelser: alle sårbarheder.
For PHP-sikkerhed ud over denne hændelse, se vores guide til PHP-sikkerhed.
Kilder og opdateringer
Primære kilder:
- PHP: security advisory af 21. oktober 2026, informationsmeddelelse af 23. oktober 2026, GHSA-w8hw-w9fx-j79w, GHSA-6wmf-4rv5-p3rp, understøttede versioner
- CVE-poster: CVE-2026-109618, CVE-2026-109619
- CISA: advarsel af 21. oktober 2026, KEV-kataloget
- NCSC-NL: php2shell-repositoriet
- NVD: CVE-2026-109618, CVE-2026-109619
- FIRST: EPSS-scorer
Research og analyse:
- Calif: PHP2Shell, a tale of two PHP remote vulnerabilities
- Amazon Threat Intelligence
- watchTowr
- Akamai
- CybelAngel
- Searchlight Cyber php2shell-scanner
Opdateringer:
- 2026-11-11: Tilføjet NVD's scorer, EPSS, CWE-klasser, krediteringer, seneste sikre versioner og end of life-datoer i boksen, PHP 8.6.0 RC4 samt afsnit om, hvordan fejlene virker, hvordan du verificerer rettelsen, og hvordan du tjekker for kompromittering.
- 2026-11-11: Første udgivelse.