Aktuel situation: PHP2Shell. To kritiske PHP-sårbarheder (CVSS 9,2) tillader skadelig kode uden login. Rettelser siden 21.10.2026.Hvad der skal gøres nu →

Zend Engine: PHP's hjerte

Zend Engine oversætter PHP-kode til opcodes og udfører dem. Den, der kender dens byggesten, forstår, hvorfor sårbarheder i kernen som PHP2Shell kun rettes af en PHP-opdatering.

Status 4 min. læsetidPHP-viden

Kort sagt: Zend Engine er kernen i PHP. Den oversætter PHP-kode til opcodes, udfører dem i en virtuel maskine og administrerer herunder variabler og hukommelse. Siden PHP 4 sidder den i enhver PHP-installation. Fordi PHP2Shell-sårbarhederne ligger i denne kerne, hjælper hverken plugins eller CMS-opdateringer, kun en opdateret PHP med genstart.

Hvad er Zend Engine?

Zend Engine er den del af PHP, der udfører selve arbejdet. Alt andet, f.eks. tilslutningen til webserveren eller udvidelser til databaser, bygger oven på den. Man kan sammenligne den med en bils motor: Karrosseri og udstyr er forskellige, men motoren driver det hele.

Ifølge PHP-manualen er navnet dannet af udviklernes fornavne, Zeev Suraski og Andi Gutmans. Motoren blev præsenteret midt i 1999 og var fra PHP 4.0, udkommet i maj 2000, kernen i PHP. Siden er den flere gange blevet grundlæggende omarbejdet.

PHP-version Motor Vigtigste ændring ifølge manual og RFC'er
PHP 4.0 (2000) Zend Engine første fælles kerne, bedre ydelse
PHP 5.0 (2004) Zend Engine 2.0 ny objektmodel
PHP 7.0 (2015) Zend Engine 3.0 PHPNG: mere kompakte datastrukturer, AST
PHP 8.0 (2020) videreudvikling JIT-compiler som del af OPcache

Byggestenene: compiler, virtuel maskine, hukommelse

Motoren arbejder i klart adskilte trin. Siden PHP 7 er det ifølge RFC'en om det abstrakte syntakstræ tre faser frem til bytekoden:

  1. Lexer: opdeler kildeteksten i tokens, f.eks. nøgleord, variabelnavne og tegnstrenge.
  2. Parser: bygger ud fra tokens et abstrakt syntakstræ (AST), der afbilder programmets struktur.
  3. Compiler: genererer ud fra AST'et op-arrays, altså lister af opcodes, ét pr. fil og funktion.
  4. Executor (Zend VM): afvikler opcodes. Ifølge JIT-RFC'en hører der til hver opcode en handler-funktion, som udfører den.
  5. Hukommelsesstyring: reserverer og frigiver hukommelse for hver forespørgsel og overvåger herved grænsen fra memory_limit.

Et scripts tokens kan gøres synlige med udvidelsen Tokenizer. Det er harmløst og lærerigt:

<?php
$code = '<?php $summe = 2 + 3; echo $summe;';
foreach (token_get_all($code) as $token) {
    if (is_array($token)) {
        echo token_name($token[0]), ': ', trim($token[1]), "\n";
    } else {
        echo 'Zeichen: ', $token, "\n";
    }
}

Outputtet viser poster som T_VARIABLE: $summe eller T_LNUMBER: 2. Netop med disse byggesten arbejder parseren videre.

Hvordan administrerer Zend Engine variabler?

Hver PHP-variabel ligger ifølge manualen i en beholder ved navn zval. Den indeholder type og værdi samt administrationsoplysninger, herunder en referencetæller (refcount). Tælleren angiver, hvor mange variabelnavne der peger på den samme beholder.

<?php
$a = str_repeat('x', 10);
$b = $a;        // ingen kopiering, begge peger på samme værdi
$b .= 'y';      // først nu kopieres der (copy on write)
unset($a);      // tælleren falder, hukommelsen frigives, når den når 0

Når tælleren når nul, frigiver motoren hukommelsen. Til cirkelreferencer mellem objekter findes desuden en garbage collector. Mere herom i indlægget Hukommelsesstyring i PHP.

Omarbejdelsen PHPNG til PHP 7 satte netop ind her. Ifølge RFC'en fra Dmitry Stogov og Zeev Suraski handlede det om mere kompakte datastrukturer og en smartere repræsentation af værdier. RFC'en nævnte ydelsesgevinster på 20 til 110 procent i reelle applikationer.

OPcache og JIT: udvidelser af motoren

Uden cache oversætter motoren hvert script på ny ved hver forespørgsel. OPcache holder de færdige opcodes klar i den delte hukommelse. Siden PHP 8.0 findes der desuden en JIT-compiler. Ifølge RFC'en bygger den på DynASM, et værktøj fra LuaJIT-projektet, og genererer maskinkode direkte ud fra bytekoden. Den virtuelle maskine forbliver herved uændret; JIT'en erstatter kun handlernes indgangspunkter.

For driftsansvarlige betyder det: OPcache og JIT gør motoren hurtigere, men ændrer intet ved dens adfærd ved fejl. En sårbarhed i kernen består også med aktiv cache.

Hvorfor sårbarheder i motoren vejer særligt tungt

De to PHP2Shell-sårbarheder ligger i PHP's kerne. Ved CVE-2026-109618 kan en out-of-memory-tilstand afbryde motoren, mens forespørgselsdata kun er delvis initialiseret; ved oprydningen behandles ugyldige data så som gyldige. Ved CVE-2026-109619 forbliver intern tilstand bestående, efter at hukommelsen er frigivet, og kan udnyttes af en senere forespørgsel i den samme worker.

De rettede versioner 8.5.12, 8.4.27, 8.3.36 og 8.2.35 ændrer ifølge PHP-manualen også hukommelsesgrænsens adfærd: memory_limit er dér en blød grænse, en ny indstilling memory_hard_limit_percent fastlægger en hård øvre grænse. Manualen gør opmærksom på, at en version, som ikke kender denne indstilling, er berørt af sårbarhederne. Ved distributioner med backports tæller desuden pakkens changelog.

Vigtigt

Motoren er indlæst i hver PHP-proces. Efter opdateringen skal derfor alle PHP-FPM-workere, Apache-processer med mod_php og øvrige PHP-tjenester genstartes.

Hvad der sker indeni ved en hukommelsesflaskehals, beskriver indlægget memory_limit og out-of-memory. Selve vurderingen af sårbarheden står under CVE-2026-109618.

Hvordan hjælper PHP SOS konkret?

  • Kontrollere version og pakkestatus: Vi finder ud af, hvilken motorstatus der faktisk kører, inklusive jeres distributions backports.
  • Opdatere og genstarte: Via PHP-patchservicen indspiller vi opdateringen og kontrollerer, at ingen proces med gammel kode er tilbage.
  • Sætte hukommelsesgrænser fornuftigt: Vi afstemmer memory_limit, den nye hårde grænse og cgroup-grænser efter jeres applikation.
  • Undersøge påfaldende forhold: Nedbrud hos workere eller processer med exit-status 137 vurderer vi og kontrollerer, om et angreb kan ligge bag.

Ofte stillede spørgsmål

Hvor har Zend Engine sit navn fra?

Navnet er sammensat af udviklernes fornavne: Zeev Suraski og Andi Gutmans. Ifølge PHP-manualen blev motoren præsenteret midt i 1999 og var fra PHP 4.0 i maj 2000 kernen i PHP.

Er Zend Engine et selvstændigt produkt, som jeg skal installere?

Nej. Zend Engine er en fast bestanddel af enhver PHP-installation. Den, der opdaterer PHP, opdaterer automatisk også motoren. Det har intet at gøre med de kommercielle produkter fra firmaet Zend.

Hvad er en opcode?

En opcode er en enkelt kommando til PHP's virtuelle maskine, f.eks. en addition, et funktionskald eller en tildeling. Compileren oversætter hvert script til en række af sådanne kommandoer, som motoren derefter afvikler.

Hvad har Zend Engine med memory_limit at gøre?

Motoren administrerer hukommelsen for hver forespørgsel og overholder herved grænsen fra memory_limit. Siden sikkerhedsudgivelserne fra 21.10.2026 er denne grænse ifølge manualen en blød grænse, suppleret med en hård grænse via memory_hard_limit_percent.

Kilder

Akut kontakt

Hver time tæller. Skriv til os nu.

Beskriv kort system, PHP-version og observation. Vi vender tilbage, afklarer situationen og arbejder på afstand, indtil hændelsen er afsluttet og dokumenteret.

Akut hjælp