Kort sagt: När en webbläsare begär en PHP-sida tar webbservern emot förfrågan och för den vidare till PHP via ett gränssnitt (SAPI). PHP översätter skriptet till bytekod, kör den i Zend Engine och lämnar resultatet, oftast HTML, tillbaka till webbservern. Därefter städas förfrågans tillstånd upp så att nästa förfrågan börjar rent.
Vad händer när någon öppnar er webbplats?
För besökaren är det ett klick. På servern avlöper många steg på millisekunder. Den som känner till förloppet förstår bättre varför uppdateringar, omstarter och konfiguration är så viktiga, och varför en sårbarhet i själva PHP väger tyngre än en sårbarhet i ett plugin.
PHP-manualen nämner tre komponenter som behövs för en PHP-webbplats: PHP-tolken (som CGI eller servermodul), en webbserver och en webbläsare. Tolken är det program som läser och kör PHP-kod. Hur den är kopplad till webbservern avgör driftläget.
Hur fungerar PHP? Sju steg i en förfrågan
- Förfrågan: Webbläsaren skickar en HTTP-förfrågan, till exempel
GET /kontakt.php, till servern. - Webbserver: Apache, Nginx eller LiteSpeed tar emot förfrågan. Statiska filer som bilder levererar de själva. För
.php-filer anropar de PHP. - Överlämning via SAPI: Serverns gränssnitt (SAPI) lämnar över förfrågningsdata som rubriker, parametrar och formulärdata till PHP. Med PHP-FPM sker det via FastCGI-protokollet, med mod_php direkt i Apache-processen. Detaljer finns under SAPI förklarat.
- Förbereda förfrågan: PHP lägger förfrågningsdata i variabler som
$_GET,$_POST,$_COOKIEoch$_FILESoch reserverar minne för förfrågan. - Översätta: Skriptet delas upp i byggstenar (tokens), av dem skapas ett abstrakt syntaxträd (AST) och av det opcodes, en sorts maskinspråk för PHP. Är OPcache aktiv hoppas det här steget över om skriptet redan ligger i cachen.
- Köra: Den virtuella maskinen i Zend Engine går igenom opcodes, frågar databaser, läser filer och skapar utdata.
- Svar och uppstädning: Utdata går via SAPI tillbaka till webbservern och därifrån till webbläsaren. Därefter frigör PHP förfrågans minne och återställer tillståndet.
AST har funnits sedan PHP 7. Enligt det tillhörande RFC-dokumentet skapade parsern tidigare opcodes direkt under inläsningen; uppdelningen i tre faser gjorde kompilatorn enklare att underhålla.
Ett exempel: vad skriptet ser av förfrågan
Följande ofarliga skript visar vilken information PHP får från förfrågan och i vilket driftläge det körs:
<?php
header('Content-Type: text/plain; charset=utf-8');
echo 'Betriebsart (SAPI): ' . PHP_SAPI . "\n";
echo 'PHP-Version: ' . PHP_VERSION . "\n";
echo 'Methode: ' . ($_SERVER['REQUEST_METHOD'] ?? '-') . "\n";
echo 'Speicher in dieser Anfrage: ' . memory_get_usage() . " Bytes\n";
På en server med PHP-FPM ger PHP_SAPI värdet fpm-fcgi, under Apache med mod_php apache2handler. Lägg sådana kontrollfiler i den publika katalogen bara tillfälligt och aldrig permanent, eftersom versionsuppgifter också hjälper angripare att orientera sig.
Var bytekodcachen och JIT kommer in
Översättningen i steg 5 tar tid. OPcache lagrar enligt manualen förkompilerad bytekod i delat minne och besparar PHP att läsa in och dela upp skripten vid varje förfrågan. Sedan PHP 8.0 kan dessutom en JIT-kompilator skapa verklig maskinkod av opcodes. Enligt JIT-RFC:t är den en nästan fristående del av OPcache.
| Fas | Resultat | Cachas? |
|---|---|---|
| Lexing | tokenström | nej |
| Parsing | abstrakt syntaxträd (AST) | nej |
| Kompilering | opcodes (op-arrayer per fil och funktion) | ja, i OPcache |
| JIT (valfritt) | maskinkod | ja, i OPcache-minnet |
| Körning | sidans utdata | nej |
Cachen gäller bara den översatta koden. Data från den enskilda förfrågan, till exempel formulärinmatning eller sessionsvärden, delas inte via OPcache.
Varför PHP2Shell sätter in just i det här förloppet
De båda PHP2Shell-sårbarheterna berör inte en applikation utan förloppet självt. Vid CVE-2026-109618 kan ett out-of-memory-tillstånd avbryta PHP medan förfrågningsdata bara delvis är förberedda, alltså i steg 4. Vid den efterföljande uppstädningen kan ogiltiga data sedan behandlas som giltiga.
Vid CVE-2026-109619 kan internt tillstånd från en förfrågan finnas kvar sedan minnet frigjorts. En senare förfrågan i samma worker kan använda det innan det återställs. Det gäller steg 7, uppstädningen. Bakgrund finns på sidan CVE-2026-109619 och i artikeln om förfrågans livscykel.
Av detta följer: Skyddsåtgärder i applikationskoden, till exempel säkerhetsplugin, verkar först i steg 6. Vid mod_php visades enligt PHP-teamet till och med en exploit innan någon applikationskod alls körs. Verksamt är bara PHP-uppdateringen till 8.5.12, 8.4.27, 8.3.36 eller 8.2.35 och en omstart av alla PHP-processer, eftersom långlivade workers annars fortsätter att köra den gamla koden.
Hur hjälper PHP SOS konkret?
- Göra förloppet synligt: Vi tar reda på vilket driftläge, vilken konfiguration och vilken cache som faktiskt är aktiva på er server.
- Uppdatera rätt: Vi installerar PHP-uppdateringen och kontrollerar via starttiderna att ingen gammal process längre körs.
- Säkra lagren: Inom ramen för serverhärdning begränsar vi förfrågningsstorlekar, minne och rättigheter där de verkar: före applikationskoden.
- Granska spår: På servrar som har varit oskyddat nåbara söker vi efter tecken på ett intrång.
Vanliga frågor
Översätts PHP-koden på nytt vid varje anrop?
Utan cache ja: PHP delar upp skriptet, bygger ett syntaxträd och skapar opcodes av det. Med aktiv OPcache ligger opcodes i delat minne och återanvänds så länge filen inte har ändrats.
Vad finns kvar i minnet efter en förfrågan?
I grunden städas förfrågans tillstånd upp i slutet så att nästa förfrågan börjar rent. Långlivade är bara saker som OPcache eller persistenta anslutningar. Det är just vid den här uppstädningen som CVE-2026-109619 sätter in.
Varför måste PHP startas om efter en uppdatering?
Med PHP-FPM och mod_php körs processerna kontinuerligt och har laddat den gamla programkoden. Nya filer på disken ändrar inget av det. Först en omstart laddar den rättade koden.
Är en webbserver utan PHP säkrare?
Den har mindre angreppsyta eftersom ingen programlogik svarar på förfrågningar. För rent statiskt innehåll är det ett verkligt alternativ. För webbutiker, formulär och inloggningar behövs dock ett serverspråk, och då är underhållet av det avgörande.