Lyhyesti: FrankenPHP on Caddyyn perustuva sovelluspalvelin, joka upottaa PHP:n omaan ohjelmaansa. FrankenPHP:n tietoturvan kannalta PHP2Shellin jälkeen tämä tarkoittaa: ratkaisevia eivät ole jakelun PHP-paketit vaan FrankenPHP-binäärin tai konttikuvan PHP-versio. Rakenna tai lataa versio, jossa on korjattu PHP, ja käynnistä kaikki workerit uudelleen.
Miksi FrankenPHP korjataan eri tavalla
Perinteisissä ympäristöissä jakelu toimittaa PHP:n pakettina, ja päivitys vaihtaa tiedostot. FrankenPHP sen sijaan sisältää PHP:n upotettuna kirjastona. Joka käyttää virallista binääriä tai siihen perustuvaa konttikuvaa, saa PHP:n mukanaan. Isännän apt upgrade ei muuta siinä mitään.
PHP2Shell koostuu haavoittuvuuksista CVE-2026-109618 ja CVE-2026-109619, kumpikin CVSS v4.0 9.2. PHP-projekti luettelee FrankenPHP:n nimenomaisesti koskeneiden toimintatapojen joukossa. Korjatut versiot ovat PHP 8.5.12, 8.4.27, 8.3.36 ja 8.2.35. Ratkaisevaa on siis, mitä PHP-versiota vasten FrankenPHP:si on rakennettu.
Worker-tila ja PHP2Shell
FrankenPHP voi ajaa sovelluksia worker-tilassa. Silloin sovellus ladataan kerran ja se käsittelee sen jälkeen monta pyyntöä peräkkäin samassa prosessissa. Se tuo nopeutta, mutta pidentää jokaisen prosessin elinikää.
CVE-2026-109619 kuvaa pyynnön sisäistä tilaa, joka voi jäädä voimaan muistin vapauttamisen jälkeen; myöhempi pyyntö samassa workerissa voi hyödyntää sitä ennen kuin se nollataan. Worker-tilassa usean pyynnön yhteisvaikutus yhdessä prosessissa on normaalitapaus. Se ei ole syy luopua worker-tilasta, mutta selvä syy toteuttaa päivitykset ja uudelleenkäynnistykset erityisen huolellisesti. Tekniset yksityiskohdat ovat sivulla CVE-2026-109619.
FrankenPHP:n tietoturva: tarkista versio
Tarkista upotettu PHP-versio suoraan käynnissä olevasta järjestelmästä. Seuraavat komennot vain lukevat; palvelujen ja konttien nimet ovat esimerkkejä.
# Asennettu binääri
frankenphp version
# Käynnissä olevassa kontissa (kontin nimi esimerkkinä)
docker exec app frankenphp version
docker exec app php -v
# Mikä image todella pyörii? (Digest näyttää tarkan tilan)
docker inspect --format '{{.Image}} {{.Config.Image}}' app
Kirjaa tulosteen PHP-versio ylös. Jos se on korjattuja tiloja vanhempi, järjestelmä on haavoittuva. Tarkista aina käynnissä oleva kontti, älä vain viimeksi rakennettua imagea, sillä uusi image tulee voimaan vasta, kun kontit on vaihdettu.
Asenna päivitys ja käynnistä kaikki workerit uudelleen
Miltä päivitys näyttää, riippuu asennuksestasi:
- Binääri isännällä: asenna uusi FrankenPHP-julkaisu, jossa on korjattu PHP-versio, ja käynnistä palvelu uudelleen.
- Kontti: hanki peruskuva, jossa on korjattu PHP-versio, rakenna oma image uudelleen ilman välimuistia peruskerroksen osalta ja vaihda kontit.
- Itse käännetty: rakenna uudelleen korjattua PHP-versiota vasten, luo kaikki laajennukset uudelleen samalla versiolla.
# Esimerkki isäntäasennuksesta systemd-palveluna
systemctl restart frankenphp
# Esimerkki Docker Compose: rakenna ilman välimuistia ja vaihda kontit
docker compose build --pull --no-cache
docker compose up -d --force-recreate
Sen jälkeen tarkista uudelleen PHP-versio käynnissä olevassa kontissa ja prosessien käynnistysaika. Worker-tilassa jokainen worker on käynnistettävä uudelleen. Kubernetesissa pätevät lisävaiheet, jotka kuvataan sivulla PHP:n korjaus Kubernetesissa, konteille yleisesti sivulla PHP:n korjaus Docker-konteissa.
Tunniste kuten latest tai pääversio image-nimessä ei takaa, että sinulla on uusin tila. Hae peruskuva aktiivisesti uudelleen ja tarkista sen jälkeen PHP-versio käynnissä olevassa kontissa.
Väliaikaiset toimenpiteet ja koventaminen
Jos päivitystä ei voi tehdä heti, php.net suosittelee väliaikaisia toimenpiteitä, jotka eivät tarjoa täydellistä suojaa. FrankenPHP:ssä asetat arvot php.ini-tiedostossa, jonka FrankenPHP lataa, tai Caddyn konfiguraation PHP-asetusten kautta, et ini_set()-kutsulla sovelluksessa.
; php.ini kontissa tai isännällä
session.upload_progress.enabled = 0
post_max_size = 8M
upload_max_filesize = 6M
Latausominaisuuden kanssa php.net mainitsee arvon post_max_size = 32M. PHP 8.5:ssä lisätään fatal_error_backtraces=0. Muistiraja kuuluu konttitasolle, esimerkiksi kontin muistirajalla, ei RLIMIT_AS- tai RLIMIT_DATA-asetuksilla. Jokaisen muutoksen jälkeen kaikki workerit käynnistetään uudelleen.
Jatkuvaan käyttöön kannattaa viitata imageihin kiinteällä digestillä, rakentaa ne säännöllisesti automaattisesti uudelleen ja ottaa image-skanneri mukaan build-ketjuun. Korjaus ei myöskään poista haittaohjelmaa, joka on asennettu aiemmin. Säilytä lokit 20.10.2026 alkaen; konteilla se tarkoittaa niiden turvaamista ennen vaihtoa.
Jos käytät FrankenPHP:tä staattisesti rakennettuna binäärinä, tiedä, että siihen on PHP:n lisäksi kiinteästi upotettu myös kaikki laajennukset. Päivitys tarkoittaa siksi aina koko binäärin vaihtamista. Tarkista vaihdon jälkeen versio ja ladattujen laajennusten luettelo, onko kaikki saatavilla kuten aiemmin, ja testaa sovellus, ennen kuin hylkäät vanhan tilan. Konttiympäristöissä kannattaa merkitä jokainen image rakennuspäivämäärällä. Näin voit milloin tahansa jäljittää, mikä tila pyöri milloinkin, ja tarvittaessa palata kohdennetusti takaisin putoamatta uudelleen haavoittuvaan tilaan. Kirjaa imagen, PHP-version ja ajankohdan liitos dokumentaatioosi.
Miten PHP SOS auttaa konkreettisesti?
- Tarkistamme, mikä PHP-versio FrankenPHP-binääreissänne ja käynnissä olevissa konteissanne todella on.
- PHP-korjauspalvelun kautta rakennamme imaget uudelleen, vaihdamme kontit ja käynnistämme kaikki workerit uudelleen todisteineen.
- Turvaamme lokit ennen vaihtoa ja tarkistamme sovelluksen jälkien varalta.
- Jatkuvaan käyttöön otamme käyttöön automatisoidut uudelleenrakennukset ja image-tarkistukset osana palvelimen koventamista.
Usein kysytyt kysymykset
Auttaako apt- tai dnf-päivitys FrankenPHP:n kohdalla?
Vain jos FrankenPHP itse tulee näistä pakettilähteistä ja on rakennettu korjattua PHP:tä vasten. Usein PHP on kiinteä osa FrankenPHP-binääriä tai konttikuvaa. Silloin sinun on päivitettävä binääri tai image.
Miksi worker-tila on PHP2Shellin kohdalla erityisen tärkeä?
Worker-tilassa sovellus pysyy muistissa ja käsittelee monta pyyntöä peräkkäin samassa prosessissa. CVE-2026-109619 koskee juuri sisäistä tilaa, joka voi säilyä pyyntöjen välillä samassa workerissa. Kaikkien workerien uudelleenkäynnistys päivityksen jälkeen on siksi pakollinen.
Miten tarkistan, mikä PHP-versio FrankenPHP:ssä on?
FrankenPHP-binääri tulostaa versiokutsussa upotetun PHP-version. Kontissa komennon voi ajaa docker exec -komennolla. Huolehdi, että tarkistat version todella käynnissä olevassa kontissa, et vasta rakennetussa imagessa.
Onko FrankenPHP:lle omia väliaikaisia toimenpiteitä?
Pätevät php.net:n yleiset ohjeet. Asetat arvot php.ini-tiedostossa, jonka FrankenPHP lataa, tai Caddy-tiedoston PHP-konfiguraatiossa, et ini_set()-kutsulla sovelluksessa. Sen jälkeen kaikki workerit käynnistetään uudelleen.