PHP2Shell är två kritiska sårbarheter i själva PHP, CVE-2026-109618 och CVE-2026-109619, som kan låta en oautentiserad webbförfrågan köra kod på varje PHP-installation som hanterar webbförfrågningar: PHP-FPM, Apache med mod_php, php-cgi, FrankenPHP och LiteSpeed. Båda utnyttjas aktivt och finns i CISA:s KEV-katalog. Rättningen är PHP 8.5.12, 8.4.27, 8.3.36 eller 8.2.35; PHP 8.1 och äldre får ingen version från upstream. Uppgradera, och bygg sedan om och driftsätt på nytt varje containeravbild som innehåller PHP, inklusive gamla taggar som fortfarande körs och avbilder du har levererat till kunder.
Att patcha servern du känner till är den lätta delen. Exponeringen som dröjer sig kvar är den PHP du glömt: en körmiljö kompilerad in i en basavbild, en avbildstagg från förra året som fortfarande körs i produktion, en CI-avbild eller en produkt levererad till kunder med en PHP som nått slutet av sin livscykel. Den här sidan hjälper dig att patcha först och visar sedan hur du hittar resten.
Vad som hände
| Datum (2026) | Händelse | Källa |
|---|---|---|
| 11 och 21 augusti | Calif rapporterar de två buggarna till PHP-projektet | Calif |
| 17 oktober | Det första utnyttjandeförsöket Amazon såg i sina honeypots, före offentliggörandet | Amazon Threat Intelligence |
| 20 oktober | PHP aviserar en säkerhetsrelease den 21 oktober kl. 14.00 UTC som rättar två sårbarheter med CVSS 4.0 9,2 | php.net |
| 21 oktober | PHP släpper 8.5.12, 8.4.27, 8.3.36 och 8.2.35 och publicerar sitt säkerhetsmeddelande; CVE-posterna blir offentliga; NCSC-NL öppnar sitt repo php2shell | PHP:s säkerhetsmeddelande, NCSC-NL |
| 21 oktober | De officiella Docker-avbilderna php uppdateras till de rättade versionerna | docker-library/php |
| 21 oktober | watchTowr rapporterar att båda CVE:erna utnyttjas aktivt; CISA publicerar en varning | watchTowr, CISA |
| 22 oktober | Searchlight Cyber publicerar php2shell-scanner | GitHub |
| 23 oktober | PHP rekommenderar att sätta session.upload_progress.enabled=0 för en separat, osannolik RCE-väg, CVE-2026-115560 | php.net |
| 26 oktober | CISA lägger till båda CVE:erna i KEV-katalogen, med 29 oktober som sista dag för amerikanska federala myndigheter | CISA KEV |
Namnet PHP2Shell kommer från Califs genomgång och används brett i branschens rapportering; PHP:s egna säkerhetsmeddelanden använder det inte. CVE-posterna krediterar Calif, Wiz och OpenAI.
Vem som berörs
All PHP som hanterar webbförfrågningar. PHP:s säkerhetsmeddelande nämner PHP-FPM, Apache med mod_php, php-cgi, FrankenPHP och LiteSpeed, och bedömer att risken är störst för mod_php, ”med en demonstrerad exploit där en oautentiserad förfrågan kan utlösa attacken innan någon applikationskod körs.” Eftersom buggarna finns i själva PHP är applikationer byggda på Laravel, Symfony eller WordPress exponerade så snart PHP under dem är det.
| Gren | Berörda | Rättat i | Support från upstream |
|---|---|---|---|
| 8.5 | före 8.5.12 | 8.5.12 | Aktiv |
| 8.4 | före 8.4.27 | 8.4.27 | Aktiv |
| 8.3 | före 8.3.36 | 8.3.36 | Endast säkerhetsrättningar, till och med 31 december 2027 |
| 8.2 | före 8.2.35 | 8.2.35 | Endast säkerhetsrättningar, till och med 31 december 2026 |
| 8.1, 8.0, 7.4 | alla versioner, enligt Calif och watchTowr | ingen release; minimala bakåtporteringar i källkod i php-src | Slut på support |
| 7.3 och äldre, inklusive PHP 5 | alla versioner, enligt Calif och watchTowr | ingen rättning från upstream | Slut på support |
PHP:s säkerhetsmeddelanden listar bara de grenar som stöds. För äldre grenar rapporterar Calif att ”den tidigaste berörda kodvägen vi hittade går tillbaka till PHP 5.4.0”, och watchTowr listar PHP 7 och PHP 5 som berörda utan rättning. PHP säger att grenarna 8.1 och äldre ”inte längre får uppdateringar från PHP-projektet”, men publicerade minimala bakåtporteringar i källkod för 7.4, 8.0 och 8.1 för den som bygger från källkod. Vissa distributioner och kommersiella leverantörer av långtidssupport levererar bakåtporterade rättningar för grenar som nått slutet av sin livscykel; fråga din. Om du testar nästa huvudversion innehåller även PHP 8.6.0 RC4, som släpptes samma dag, rättningarna.
Så fungerar det
Båda CVE:erna är minnessäkerhetsbuggar i hur PHP sätter upp och river ner en förfrågan, under all applikationskod. CVE-posterna klassar båda som use after free (CWE-416), tillsammans med felaktig hantering av exceptionella tillstånd, åtkomst via en oinitierad pekare, okontrollerad minnesallokering och felaktig initiering (CWE-755, CWE-824, CWE-1325, CWE-1419). Med PHP:s ord:
- CVE-2026-109618, RCE via OOM-korruption: ”hanteringen av minnesbrist kan avbryta PHP medan intern förfrågningsdata bara är delvis initierad. Upprensningen efter förfrågan kan då behandla ogiltig data som giltig.” En förfrågningskropp som är konstruerad för att uttömma minnet medan PHP tolkar den kan utlösa det avbrottet. Apache med mod_php kör upprensningen även när starten av förfrågan misslyckades, och därför fungerar attacken där innan någon applikationskod körs. För PHP-FPM säger PHP:s säkerhetsmeddelande att källkodsanalys talar för att den är mottaglig, även om ingen fullständig exploit mot FPM har demonstrerats.
- CVE-2026-109619, RCE via inaktuellt globalt tillstånd: ”internt tillstånd som ägs av en förfrågan kan överleva efter att minnet bakom det har frigjorts. En senare förfrågan som hanteras av samma worker kan använda det inaktuella tillståndet innan den normala initieringen återställer det.” Det krävs två förfrågningar som når samma worker: en som lämnar tillståndet kvar, till exempel genom ett fatalt fel, och en som använder det. PHP:s säkerhetsmeddelande bekräftar vägen via session upload progress mot mod_php och FPM, och vägen via backtraces vid fatala fel i PHP 8.5 mot mod_php.
Därför riktar sig PHP:s tillfälliga inställningar mot minnesgränser, förfrågningskroppens storlek, session upload progress och backtraces vid fatala fel: var och en stänger en väg till buggarna, inte buggarna själva. PHP ger, som CNA, båda 9,2 enligt CVSS 4.0. NVD:s egna bedömningar enligt CVSS 3.1 är 9,8 för CVE-2026-109618 och 8,1 för CVE-2026-109619.
Så kontrollerar du om du berörs
Börja med de värdar du känner till och leta sedan efter PHP i allt du bygger och levererar.
På en värd eller virtuell maskin, kontrollera vilken version PHP rapporterar. Kontrollera även webb-SAPI:t, eftersom php-fpm eller Apache-modulen kan komma från ett annat paket än kommandoraden:
php -v
php-fpm -v
Distributionspaket (Debian, Ubuntu, Alpine, RHEL) får ofta rättningen som en bakåtportering utan ny upstream-version: Ubuntu 24.04 levererar till exempel rättningen som 8.3.6-0ubuntu0.24.04.13. Här vilseleder en versionskontroll ensam. Lista det installerade paketet och jämför det med den rättade paketversionen i din distributions säkerhetsspårare:
dpkg -l 'php*' | grep '^ii' # Debian, Ubuntu
apk info -v | grep '^php' # Alpine
rpm -qa 'php*' # RHEL, Fedora, Rocky, Alma
I containeravbilder. Officiella php:-avbilder kompilerar PHP från källkod, så versionen finns i själva avbilden, inte i en paketlista från distributionen. Fråga avbilden direkt:
docker run --rm --entrypoint php php:8.3-fpm -v
För att kontrollera varje avbild du faktiskt kör listar du dem och frågar var och en. För 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
Avbilder byggda FROM debian eller FROM alpine med PHP installerat via pakethanteraren behöver paketkontrollen ovan, körd inne i avbilden.
I dina repon söker du efter varje ställe där PHP väljs:
git grep -nE '^FROM[[:space:]]+(.*/)?php:' -- '*Dockerfile*' '*.dockerfile'
git grep -nE 'php-version|image:.*php' -- .github/workflows '*.yml' '*.yaml'
Låsta taggar som php:8.3.30-fpm förblir sårbara tills någon ändrar dem. Flytande taggar som php:8.3-fpm byggdes om med de rättade versionerna från den 21 oktober, men en avbild som byggdes före dess behåller den gamla PHP-versionen tills du bygger om den. php-villkoret i composer.json säger vilka versioner din kod accepterar, inte vilken som körs.
I CI. Bygg- och testjobb använder ofta en egen PHP: en php:-tjänstecontainer, en setup-action med indata php-version eller en runner-avbild. De hanterar ingen produktionstrafik, men de visar vilka avbilder och versioner din pipeline producerar.
Exponerade värdar. Searchlight Cybers php2shell-scanner testar en URL med stora multipart-förfrågningar, cirka 29 MiB per sökväg. Kör den bara mot värdar du har behörighet att testa. Dess README varnar för falska positiva på patchad PHP med lågt memory_limit, och när PHP inte avslöjar sin version kan skannern inte skilja en patchad server från en sårbar. Se den som en ledtråd, inte ett bevis. NCSC-NL:s repo samlar detekteringsregler och en lista över produkter som paketerar PHP, med deras status.
Vad dagens skanning inte kan säga dig. En skanning av avbilderna i ditt register i dag täcker det du skulle driftsätta i dag. Den täcker inte en tidigare release du levererade till en kund, den gamla taggen en kund fortfarande kör eller vilka av dina byggen som producerade avbilder med en sårbar PHP. För det behöver du en registrering av vad varje bygge tog in, per release. Se är vi drabbade? så bedömer du en ny CVE över alla dina byggen.
Så åtgärdar du det, och vad du gör om du inte kan patcha än
- Uppgradera till 8.5.12, 8.4.27, 8.3.36 eller 8.2.35, eller till din distributions rättade paket. På 8.1 eller äldre flyttar du till en gren som stöds; PHP:s bakåtporteringar och leverantörers byggen är nödlösningar.
- Bygg om varje avbild från en rättad bas (hämta basavbilden på nytt eller bygg utan cache) och driftsätt på nytt. Avbilder som redan körs behåller sin gamla PHP tills de ersätts, så starta om arbetslasterna också.
- Verifiera med checklistan nedan, mot de containrar som körs, inte bara mot den nya avbilden.
Om du inte kan uppgradera än listar PHP:s säkerhetsmeddelande åtgärder som ”minskar exponeringen för specifika attackvägar men inte gör en installation säker.” För CVE-2026-109618:
- ”Sätt
memory_limit=-1, helst på ett sätt som applikationer inte kan åsidosätta, till exempelphp_admin_valuei FPM-poolen eller Apache-konfigurationen, och kontrollera att ingen pool-, katalog- eller applikationsinställning återinför en ändlig gräns.” - ”För applikationer som inte kräver filuppladdningar, sätt
post_max_size = 8M. Om filuppladdningar behövs, sättpost_max_size = 32M. Hållupload_max_filesizeunderpost_max_size.” - Använd en minnesgräns för containern eller cgroup som tillgänglighetsgräns, och ersätt den inte med
RLIMIT_ASellerRLIMIT_DATA, ”eftersom dessa kan orsaka det sårbara allokeringsfelet.”
För CVE-2026-109619:
- ”Sätt
session.upload_progress.enabled=0och starta om varje worker. Användphp.ini, en FPM-pool eller serverkonfiguration som gäller före tolkningen av förfrågan. Förlita dig inte påini_set()eller FPM:s.user.ini.” - ”På PHP 8.5, sätt
fatal_error_backtraces=0och starta om varje worker.”
Kontrollera vad varje worker faktiskt körs med:
php-fpm -i | grep -E 'memory_limit|post_max_size|session.upload_progress.enabled'
CISA:s varning går längre: organisationer som inte kan uppdatera omedelbart, eller som fortfarande kör PHP 8.1 eller äldre, ”bör ta PHP-baserade system offline tills de kan patchas eller uppdateras.” Den rekommenderar också att hålla utkik efter PHP-workerprocesser som startar skal eller laddar ner verktyg.
Verifiera rättningen
- Fråga den PHP som körs, inte avbilden du tänkte driftsätta. Kör
php-fpm -v(ellerphp -v) i varje container som körs och på varje värd, och bekräfta 8.5.12, 8.4.27, 8.3.36, 8.2.35 eller senare. - Lita inte enbart på versionssträngen för distributionspaket. Debian, Ubuntu, RHEL och andra distributioner bakåtporterar rättningen till den version de redan levererar, så en patchad PHP kan fortfarande rapportera 8.3.6: Ubuntu 24.04:s rättning är
8.3.6-0ubuntu0.24.04.13. Jämför hela paketversionen med din distributions säkerhetsspårare, eller leta efter CVE:n i paketets ändringslogg, som oftast nämner den. Fällan fungerar åt andra hållet också: en skanner som bara jämför versionsnummer från upstream kan flagga ett bakåtporterat paket som sårbart. - Kontrollera att varje arbetslast kör den ombyggda avbilden. En tagg som nu pekar på en rättad avbild ändrar inte en pod som hämtade den gamla. Jämför avbildsdigesten som varje container kör med digesten du byggde:
kubectl get pods -A \
-o jsonpath='{range .items[*]}{range .status.containerStatuses[*]}{.image}{"\t"}{.imageID}{"\n"}{end}{end}'
- Kontrollera att varje worker har startats om. PHP-FPM och Apache har den gamla koden inläst tills de startas om; processkontrollen under ”Kontrollera om du har komprometterats” visar alla som fortfarande kör den.
- Om du fortfarande förlitar dig på de tillfälliga inställningarna, kontrollera varje pool med kommandot
php-fpm -iovan, och behåll dem tills uppgraderingen är klar överallt. - Kör inventeringen igen från kontrollavsnittet över ditt register, dina CI-avbilder och de releaser som kunder kör, inte bara produktion.
Kontrollera om du har komprometterats
PHP2Shell utnyttjas aktivt, och Amazon såg det första försöket den 17 oktober 2026, fyra dagar före rättningen. Om en internetexponerad PHP vid något tillfälle sedan dess körde en berörd version utan de tillfälliga inställningarna, kontrollera den.
Hur stor exponeringen är. Antal Shodan-banners som Mallory publicerade den 20 oktober, rapporterade av CybelAngel, visade 2,24 miljoner internetexponerade värdar som annonserar PHP; av de cirka 1,5 miljoner som visar en version kör 883 717 (59 %) en gren utan officiell rättning. Det är värdar som räknas, inte bekräftat sårbara system: bakåtporterade paket kan se gamla ut men vara patchade, och cirka 740 000 värdar döljer sin version.
Utrustning och produkter som paketerar PHP. PHP körs också i utrustning, nätverksenheter, administrationsgränssnitt och leverantörsprodukter där du kanske inte själv kan uppdatera den. NCSC-NL:s inventering följde 968 sådana produkter den 9 november 2026: 205 rättade, 215 sårbara, 93 under utredning, 240 beroende av körmiljön och 214 inte berörda. Kontrollera de produkterna separat och installera leverantörernas uppdateringar så snart de finns.
Se till att rättningen verkligen körs. På värdar och virtuella maskiner kör en PHP-FPM-, php-cgi- eller Apache-process som startade före uppgraderingen fortfarande den gamla koden. Dess minneskarta visar då den ersatta binären eller libphp som borttagen. Jämför också processernas starttider med tidpunkten för uppgraderingen:
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 från primärkällor:
- Förfrågningar: POST-förfrågningar med formuläruppladdning som innehåller strängen
PHP_SESSION_UPLOAD_PROGRESS, som Amazon Threat Intelligence såg i utnyttjandeförsök. Amazon listar också källadresser (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 påpekar att de tillhör delad anonymiseringsinfrastruktur: utred en träff, men se den inte som ett bevis. - Processer och filer: PHP-workerprocesser som startar skal eller laddar ner verktyg (CISA, som lade till en Sigma-detekteringsregel den 23 oktober), och oväntad processkörning eller oväntade filändringar på webbservrar (Amazon).
- Loggar: i loggar från Apache, PHP-FPM, omvända proxyer och tjänster: varningar eller kärnfel som upprepas innan skript körs, fatala fel och tolkningsfel, och
Maximum execution time exceeded. PHP:s säkerhetsmeddelande tillägger att ”avsaknad av fel i loggarna inte är ett bevis på säkerhet.”
När du ska utgå från att du har komprometterats. Om du hittar någon av dessa indikatorer, eller om en exponerad server körde en berörd PHP utan skyddsåtgärder och dina loggar inte kan utesluta utnyttjande, behandla den som komprometterad. PHP beskriver konsekvensen som fjärrkörning av kod som webbworkerns konto, och det kontot kan oftast läsa applikationens konfiguration och hemligheter.
Rotera det som workern kunde läsa. Databaslösenord, API-nycklar och tokens i miljövariabler och konfigurationsfiler, nycklar som signerar sessioner eller cookies (och sessionerna som signerats med dem), och alla molnuppgifter som värden har åtkomst till. Rotera efter att värden har byggts om, så att de nya hemligheterna aldrig hamnar på en komprometterad maskin.
Bygg om i stället för att rensa. Ersätt en komprometterad värd eller container från en känd ren avbild, och för inte över filer som workern kunde skriva, som uppladdningskataloger, cachar eller genererad kod. Återanvänd inte avbilder, byggcachar eller artefakter som har producerats på en komprometterad värd.
Vad du ska säga till dina kunder
Om du levererar programvara som körs på PHP kommer dina kunder att fråga. Svara med versioner och åtgärder, även innan du har alla svar. Ett svar du kan anpassa:
PHP2Shell (CVE-2026-109618, CVE-2026-109619) berör PHP-versioner före 8.5.12, 8.4.27, 8.3.36 och 8.2.35, samt alla äldre PHP-grenar. [Produkt] version [x till y] levereras med PHP [version] och berörs; version [z], släppt [datum], levereras med PHP [rättad version]. Uppgradera till [z]. Om du inte kan uppgradera direkt, tillämpa PHP-inställningarna i vårt säkerhetsmeddelande [länk] och begränsa nätverksåtkomsten till applikationen. [Produkt] version [a till b] berörs inte. Vi uppdaterar det här meddelandet senast [datum].
Om du fortfarande kontrollerar, säg det, och säg när du kommer att svara. Ett första uttalande och mallar för varje utfall finns i hur du svarar kunder efter en attack mot leveranskedjan.
Så hjälper CRACI
CRACI kör dina GitHub Actions-jobb och registrerar vad varje jobb drar in medan det bygger, inklusive containeravbilder, apt- och apk-paket och Composer-paket, och sparar varje tidigare bygge med dess SBOM. När en CVE publiceras flaggar den löpande omvärderingen de tidigare byggen som innehöll det berörda paketet, så att du ser vilka releaser som var exponerade och hur länge, inte bara vad dagens skanning hittar. Policyspärrar kan blockera byggen som innehåller en specifik CVE.
En begränsning för den här incidenten: PHP som är kompilerad in i en officiell php:-avbild kommer in i avbilden, inte som en paketnedladdning. CRACI registrerar avbildsreferensen som varje bygge hämtade, så sök i dina byggen efter php:-taggarna och inte bara efter PHP-paket.
Hitta varje bygge som levererade en sårbar PHP
Mer om registrering av byggen: SBOM:er från bygget, SBOM:er för Docker-avbilder, vad containerskanning missar, CISA KEV-katalogen och trender i CVE-publiceringen. Andra incidenter: alla sårbarheter.
För PHP-säkerhet utöver den här incidenten, se vår guide till PHP-säkerhet.
Källor och uppdateringar
Primärkällor:
- PHP: säkerhetsmeddelande av den 21 oktober 2026, informationsmeddelande av den 23 oktober 2026, GHSA-w8hw-w9fx-j79w, GHSA-6wmf-4rv5-p3rp, versioner som stöds
- CVE-poster: CVE-2026-109618, CVE-2026-109619
- CISA: varning av den 21 oktober 2026, KEV-katalogen
- NCSC-NL: repot php2shell
- NVD: CVE-2026-109618, CVE-2026-109619
- FIRST: EPSS-poäng
Forskning och analys:
- Calif: PHP2Shell, a tale of two PHP remote vulnerabilities
- Amazon Threat Intelligence
- watchTowr
- Akamai
- CybelAngel
- Searchlight Cyber php2shell-scanner
Uppdateringar:
- 2026-11-11: Lade till NVD:s poäng, EPSS, CWE-klasser, krediteringar, senaste säkra versioner och datum för slut på support i rutan, PHP 8.6.0 RC4, samt avsnitt om hur buggarna fungerar, hur du verifierar rättningen och hur du kontrollerar om du har komprometterats.
- 2026-11-11: Första publicering.