Alla artiklar
#php#cve-2026-109618#cve-2026-109619#rce#patch-management#php-fpm#linux-packages#incident-response

PHP2Shell: två kritiska PHP-sårbarheter, och varför "patchat" måste kontrolleras

Alexander Norman

CVE-2026-109618 och CVE-2026-109619 gör det möjligt att köra kod på distans utan inloggning, i själva PHP och innan någon applikationskod körs. Attacker rapporterades redan innan de rättade versionerna fanns ute. PHP 8.5.12, 8.4.27, 8.3.36 och 8.2.35 åtgärdar felen. Här går vi igenom vad som påverkas, varför de officiella nödåtgärderna inte är något skydd, och fällorna vi såg under releasedagen: paket daterade i dag som saknar rättningen, CDN:er som går att runda, och varför ingen kan skanna sig till visshet.

Kort version

Den 21 oktober 2026 släppte PHP-projektet PHP 8.5.12, 8.4.27, 8.3.36 och 8.2.35 för att täppa till två kritiska sårbarheter. Båda har CVSS v4 9.2 och båda kan ge fjärrkörning av kod utan autentisering. Sansec, som döpt paret till PHP2Shell, skriver att felen påverkar alla webbservrar som kör PHP 5.4 eller senare.

Det här är inte ett sårbart WordPress-tillägg eller ett ramverksfel. Felet sitter i PHP, och enligt PHP:s säkerhetsmeddelande kan ett oautentiserat anrop utlösa det innan någon applikationskod hunnit köras. Din egen kod, din inloggningssida och applikationens egna skyddsregler får aldrig chansen att säga något.

Angriparna väntade inte på releasen. Cloudflare rapporterade tidiga attacker mot PHP-sajter klockan 07:43 UTC den 21 oktober, alltså innan de rättade versionerna publicerats.

Uppdatera PHP på varje server som hanterar webbtrafik. Det finns ingen fullständig nödlösning.

Vad sårbarheterna är

PHP:s säkerhetsmeddelande beskriver dem med en mening var:

  • CVE-2026-109618, RCE via minnesbrist (OOM): hanteringen av slut på minne kan avbryta PHP medan intern anropsdata bara är delvis initierad, och städningen efter anropet kan då behandla den ogiltiga datan som giltig.
  • CVE-2026-109619, RCE via kvarliggande globalt tillstånd: internt tillstånd som hör till ett anrop kan leva kvar efter att minnet bakom det frigjorts.

Enligt php.net är alla PHP-installationer som hanterar webbanrop i riskzonen, däribland PHP-FPM, Apache med mod_php, php-cgi, FrankenPHP och LiteSpeed. PHP-projektet bedömer att risken är störst för mod_php.

Vilka versioner som är rättade

Gren Rättad version Status
8.5 8.5.12 Stöds
8.4 8.4.27 Stöds
8.3 8.3.36 Stöds
8.2 8.2.35 Stöds till 31 december 2026
8.1 och äldre Ingen officiell release Backport från leverantör, eller uppgradering

PHP 8.1 och äldre får inga nya releaser från PHP-projektet. Med tanke på allvarlighetsgraden har PHP:s säkerhetsteam ändå publicerat minimala källkodsbackporter för 7.4, 8.0 och 8.1, till den som bygger PHP själv. Kör du paketerad PHP på de grenarna är du beroende av din distribution eller LTS-leverantör, eller av att uppgradera.

Nödåtgärderna är inget skydd

Säkerhetsmeddelandet listar åtgärder för den som inte kan uppdatera direkt, och är tydligt med att de "minskar exponeringen för specifika attackvägar men gör inte installationen säker". Releaseanteckningarna är ännu rakare: "There are no complete mitigations, updating is the only safe choice."

Mest omtalad är session.upload_progress.enabled=0. Enligt php.net stänger den de bekräftade session-vägarna för CVE-2026-109619, inte andra varianter, och den gör ingenting åt CVE-2026-109618. Den måste dessutom sättas på en nivå som gäller innan PHP tolkar anropet: i php.ini, i FPM-poolen eller i serverkonfigurationen, och sedan måste varje worker startas om. ini_set() eller en .user.ini för FPM fungerar inte. Kör du PHP-FPM, tänk på att CLI-versionens php.ini inte är den som dina webbanrop använder.

Meddelandet listar fler åtgärder per CVE. För CVE-2026-109618 rekommenderar det memory_limit=-1, satt så att applikationen inte kan ändra det (till exempel med php_admin_value i FPM-poolen), och ett lågt post_max_size: 8M om inga filuppladdningar behövs, annars 32M, med upload_max_filesize under det. Det varnar uttryckligen för att använda RLIMIT_AS eller RLIMIT_DATA i stället. Sansec påpekar att memory_limit = -1 låter ett enda anrop äta upp allt minne på servern, så den inställningen hör hemma i timmarna före patchning, inte i den permanenta konfigurationen. Se alltihop som att köpa tid, aldrig som ett alternativ till uppdateringen.

Lärdomar från releasedagen

1. Ett paket daterat i dag är inte nödvändigtvis ett rättat paket. Distributioner och LTS-leverantörer fick rättningarna i förväg, men det betyder inte att varje bygge du ser i dag innehåller dem. Kontrollera att CVE-numren faktiskt står i paketets ändringslogg innan du bockar av en server:

bash
# Debian/Ubuntu
zcat /usr/share/doc/php8.3-common/changelog.Debian.gz | grep -E 'CVE-2026-10961[89]'

# RHEL/Alma/Rocky och andra RPM-baserade system
rpm -q --changelog php-common | grep -E 'CVE-2026-10961[89]'

Ett exempel: den 21 oktober publicerade Sury-förrådet ett php8.1-bygge daterat samma dag vars ändringslogg bara räknade upp äldre bakåtporterade CVE:er, inte 109618 eller 109619. Det kan mycket väl ha ändrats sedan dess, men det visar varför ett färskt datum inte bevisar något. Remis förråd, som många använder på Enterprise Linux, väntades enligt Sansec inte publicera något den 21 oktober, men kom med rättade paket senare samma dag, även en backport för 8.1. Där står båda CVE-numren i ändringsloggen, och det är precis den skillnaden du ska leta efter.

2. session.upload_progress är en halv nödåtgärd. Se ovan. Är det det enda du ändrat i dag är du fortfarande exponerad.

3. Ett CDN eller en WAF framför hjälper bara om origin inte går att nå runt den. Cloudflare lade ut WAF-regler för alla kunder, och bolagets CTO kallade dem själv en "stopgap". Även som tillfällig spärr gäller de bara trafik som faktiskt passerar CDN:et. Svarar origin-servern vem som helst på internet går angriparen helt enkelt direkt dit. Begränsa origin till trafik från CDN:et, och var medveten om att en vitlista med CDN:ets IP-intervall är svagare än den ser ut. Vi har skrivit om det i varför Cloudflare-proxy ensam inte räcker.

4. Det går inte att skanna sig till visshet. De flesta servrar visar inte sin PHP-version, så en extern skanning kan inte på ett tillförlitligt sätt avgöra vem som är sårbar. Och en aktiv kontroll som faktiskt bevisar sårbarheten är i praktiken själva attacken. Utgå från att varje PHP-server är drabbad tills du verifierat den rättade versionen på servern. En skanning utan fynd är inget bevis på att du är säker.

5. Fast på en gammal gren? Fråga leverantören först. Applikationer som hålls kvar på en gammal PHP-gren av kodade eller tredjepartsmoduler är det svåraste fallet. Kontrollera om leverantören har en nyare version, eller en ominstallation av modulen, som höjer den PHP-version som stöds. Ibland är det allt som står mellan dig och en gren som stöds.

6. På Enterprise Linux, ta det stegvis. AppStream och tredjepartsförråd kan ligga efter den officiella releasen. Om kodade laddare som ionCube är inblandade, hoppa inte flera grenar på en gång. Gå en minor-version i taget och kontrollera att laddaren fungerar innan du tar nästa steg.

Så kontrollerar du versionen

  • php -v visar CLI-versionen. Det är inte nödvändigtvis den som hanterar din webbtrafik.
  • phpinfo() (tillfälligt, på en skyddad sökväg, och borttagen efteråt) visar versionen och vilket Server API som faktiskt hanterar webbanropen, till exempel FPM/FastCGI eller Apache 2.0 Handler. Kör du flera FPM-versioner sida vid sida, kontrollera varje pool.
  • Paketets ändringslogg (kommandona ovan) visar om CVE:erna faktiskt är rättade i distributionens bygge, något versionsnumret ensamt inte alltid avslöjar när rättningar bakåtporteras.

Gör så här nu

  • Inventera varje server och container som kör PHP för webbanrop, även de som ingen kommer ihåg.
  • Uppdatera till 8.5.12, 8.4.27, 8.3.36 eller 8.2.35, eller till ett leverantörsbygge vars ändringslogg nämner båda CVE:erna.
  • Starta om varje PHP-worker (FPM, Apache, LiteSpeed, FrankenPHP) så att den nya binären faktiskt körs.
  • Verifiera via Server API i ett webbanrop, inte bara med php -v.
  • På 8.1 eller äldre: skaffa en backport från leverantören eller planera uppgraderingen nu. Kontrollera om låsande moduler kan uppdateras.
  • Fram till patchning: lägg in meddelandets nödåtgärder på rätt konfigurationsnivå, och se till att origin inte går att nå förbi CDN:et.
  • Håll utkik efter oförklarliga omstarter av PHP-workers, minnesgränsfel och HTTP 500, som Sansec nämner bland signalerna värda att bevaka.
  • Har en server varit exponerad och opatchad efter att de tidiga attackerna började är det en incidentfråga, inte bara en patchuppgift.

Den obekväma delen

Det vanliga rådet att hålla applikationerna uppdaterade räcker inte här. Det som fallerar är körmiljön under varje PHP-applikation, och attackerna började innan rättningen fanns. Det som avgör utgången är det tråkiga jobbet: att veta var PHP körs, att verifiera att paketet faktiskt innehåller rättningen, och att starta om det som behöver startas om.


pentesting.se, som drivs av Adminor, övervakar löpande kunders externa attackyta: vad som är publicerat, vilka tjänster som svarar och hur det förändras över tid. Det säger inte vilka PHP-servrar som är sårbara för de här CVE:erna, men det visar var era exponerade webbservrar finns, och det är listan ni behöver i dag. Hör av dig om du vill ha hjälp.

Vill ni se vad er externa angreppsyta egentligen ser ut? Gratis hälsokoll, ingen creditcard, två minuter.