Lyhyesti: Staattinen analyysi tarkistaa PHP-koodin suorittamatta sitä ja löytää näin tyyppivirheitä, määrittelemättömiä muuttujia, kuollutta koodia ja kutsuja mahdollisesti tyhjiin arvoihin. Kaksi yleistä työkalua ovat PHPStan (sääntötasot 0–10) ja Psalm (virhetasot 1–8, lisäksi taint-analyysi turvattomille tietovirroille). Ne löytävät virheitä sovelluksestanne, eivät PHP-tulkista; PHP2Shellin kaltaisia aukkoja vastaan auttaa vain PHP-päivitys.
Mitä staattinen analyysi on?
Testi suorittaa koodin ja vertaa tulosta. Staattinen analyysi sen sijaan lukee koodin kuin hyvin perusteellinen tarkastaja ja päättelee tyypeistä, paluuarvoista ja kutsuista, missä jokin voi mennä pieleen. Se löytää virheitä myös haaroista, joihin yksikään testi ei koskaan yllä.
Päättäjälle hyöty on yksinkertainen: ennen tuotantoon siirtoa löydetyt virheet maksavat murto-osan siitä, mitä asiakkaiden huomaamat virheet maksavat. Kehittäjälle se on jatkuva seuralainen, joka toimii kehitysympäristössä ja CI-putkessa. Jos analyysi hälyttää muutoksen kohdalla, muutosta ei oteta käyttöön ennen kuin virhe on korjattu. Näin uutta vanhaa kantaa ei kerry, kun olemassa olevaa puretaan vähitellen. Yhdessä PHPUnitilla ja Pestillä tehtävien testien kanssa se muodostaa koodin laadun perustan.
PHPStan: sääntötasot 0–10
PHPStan asennetaan kehitysriippuvuutena ja se tarvitsee toimiakseen PHP:n versiosta 7.4 alkaen:
composer require --dev phpstan/phpstan
vendor/bin/phpstan analyse src tests
Ilman lisämääreitä PHPStan tarkistaa vain välttämättömimmän. Tiukkuutta ohjataan yhdellätoista tasolla, joista jokainen sisältää alemmat:
| Taso | Mitä tarkistetaan lisäksi (valikoima) |
|---|---|
| 0 | tuntemattomat luokat ja funktiot, väärä argumenttien määrä, aina määrittelemättömät muuttujat |
| 3 | paluutyypit ja tyypit, joita ominaisuuksille sijoitetaan |
| 5 | argumenttien tyypit funktio- ja metodikutsuissa |
| 6 | puuttuvat tyyppimääritykset |
| 8 | metodikutsut ja ominaisuuksien käyttö arvoihin, jotka voivat olla null |
| 10 | tiukin mixed-tyypin käsittely, myös puuttuvilla tyypeillä |
Valitsimella --level max ajetaan aina korkein taso. Dokumentaatio kuitenkin varoittaa, että PHPStanin päivitys voi silloin tuoda paljon uusia ilmoituksia. Tyypillinen löydös tasolta 8 alkaen:
<?php
function kundenname(?Kunde $kunde): string
{
return $kunde->name(); // PHPStan: kutsu arvoon, joka voi olla null
}
PHPStanin käyttöönotto ilman virhetulvaa: baseline
Kasvaneissa hankkeissa PHPStan ilmoittaa korkealla tasolla usein satoja kohtia. Baseline ratkaisee ongelman: se tallentaa kaikki olemassa olevat ilmoitukset tiedostoon, ja PHPStan ilmoittaa siitä lähtien vain uusista virheistä.
vendor/bin/phpstan analyse --level 6 src tests --generate-baseline
Syntyvän tiedoston phpstan-baseline.neon liitätte konfiguraatioon:
includes:
- phpstan-baseline.neon
parameters:
level: 6
paths:
- src
- tests
Näin vanha kanta pysyy näkyvästi dokumentoituna, kun taas uuden koodin on oltava alusta asti siistiä.
Psalm ja taint-analyysi
Psalmilla on samanlaisia tavoitteita kuin PHPStanilla. Tasot kulkevat päinvastoin: 1 on tiukin, 8 pehmein, oletus on 2. Psalm tarvitsee PHP:n versiosta 8.2 alkaen ja otetaan käyttöön näin:
composer require --dev vimeo/psalm
./vendor/bin/psalm --init
./vendor/bin/psalm --taint-analysis
Taint-analyysi on tietoturvan kannalta erityisen kiinnostava. ”Taint” tarkoittaa saastumista: Psalm merkitsee dataa lähteistä, joita hyökkääjä voi hallita, kuten $_GET, $_POST, $_COOKIE, $_REQUEST tai php://input. Sen jälkeen se seuraa, päätyykö tämä data suojaamattomana vaarallisiin kohtiin, niin sanottuihin nieluihin: tuloste käskyllä echo, include, header tai SQL-kyselyt. Sisäänrakennettuihin luokkiin kuuluvat muun muassa sql, html, shell, include, eval, ssrf ja unserialize.
<?php
// Psalm ilmoittaa virran $_GET-muuttujasta HTML-tulosteeseen (luokka html)
echo 'Hallo ' . $_GET['name'];
// Korjattu: maskaa tuloste asiayhteyden mukaan
echo 'Hallo ' . htmlspecialchars($_GET['name'] ?? '', ENT_QUOTES, 'UTF-8');
Psalmin dokumentaatio nimeää rajat avoimesti: analyysi olettaa, että maskaus tehdään oikein. Hienovaraiset virheet, esimerkiksi puuttuvat lainausmerkit HTML-attribuutin ympäriltä, voivat silti jättää aukkoja. Psalm suosittelee siksi parametrisoituja kyselyjä SQL:lle ja asiayhteyden huomioivia mallipohjia HTML:lle. Tulokset voi tulostaa SARIF-muodossa, jonka ymmärtää muun muassa GitHub Code Scanning.
Staattinen analyysi ja tietoturva PHP2Shellin jälkeen
Tässä kannattaa tehdä rehellinen rajaus. PHP2Shell eli CVE-2026-109618 ja CVE-2026-109619 on PHP-tulkissa. Mikään sovelluskoodianne lukeva työkalu ei löydä näitä aukkoja, eikä mikään koodimuutos sulje niitä. Sen tekee vain päivitys versioon PHP 8.5.12, 8.4.27, 8.3.36 tai 8.2.35.
Staattinen analyysi edistää tietoturvaa silti kolmessa kohdassa:
- Päivityskyky: Se löytää koodin, joka ei enää toimi uusilla PHP-versioilla. Näin kynnys siirtyä versiosta 8.1 tai 8.2 tuettuun versioon madaltuu.
- Omat aukot: Taint-analyysi löytää reittejä SQL-injektiolle, cross-site scriptingille tai tiedostojen liittämiselle. PHP-hanke tekee tietoturvakäytännössään selväksi, että tarkistamattomat syötteet funktioille kuten
mysqli_query()eivät ole PHP:n virhe vaan kuuluvat sovelluksen vastuulle. - Kestävyys: Monet vakavat virheet syntyvät kutsuista null-arvoon tai väärästä tyypistä. php.net neuvoo CVE-2026-109619:n yhteydessä nimenomaisesti korjaamaan sovelluksessa ulkoa laukaistavissa olevat vakavat virheet.
Staattinen analyysi ei korvaa ihmisen tekemää tietoturvakoodikatselmusta, mutta tekee siitä tehokkaampaa, koska rutiinivirheet on seulottu pois etukäteen.
Miten PHP SOS auttaa konkreettisesti?
Tietoturvatarkastuksen ja tunkeutumistestin puitteissa toimimme näin:
- Työkalujen käyttöönotto: PHPStan tai Psalm sopivalla tasolla ja baselinella, liitettynä nykyiseen putkeenne.
- Tietoturvalöydösten arviointi: Tarkistamme taint-analyysin tulokset ja erotamme todelliset riskit vääristä hälytyksistä.
- Päivityksen valmistelu: Näytämme, mitkä kohdat estävät siirtymän tuettuun PHP-versioon.
- Tulosten luovutus: Saatte tiimillenne tai toimistollenne priorisoidun listan konkreettisista koodikohdista.
Usein kysytyt kysymykset
Mikä on ero PHPStanin ja Psalmin välillä?
Molemmat tarkistavat tyyppejä ja löytävät virheitä suorittamatta koodia. PHPStan numeroi tasonsa 0:sta (väljä) 10:een (tiukka), Psalm 8:sta (väljä) 1:een (tiukka). Psalmissa on sisäänrakennettu taint-analyysi tietoturvaongelmille.
Voinko ottaa PHPStanin käyttöön vanhassa hankkeessa?
Voit. Baselinen avulla PHPStan tallentaa kaikki olemassa olevat ilmoitukset tiedostoon ja ilmoittaa sen jälkeen vain uusista virheistä. Näin tiimi aloittaa ilman virhetulvaa ja purkaa vanhat kertymät vähitellen.
Löytääkö staattinen analyysi PHP2Shellin?
Ei löydä. PHP2Shell on PHP-tulkissa, ei teidän koodissanne. Sitä vastaan auttaa vain PHP-päivitys. Staattinen analyysi auttaa kuitenkin valmistelemaan koodin uusia PHP-versioita varten, jolloin päivitys onnistuu nopeammin.
Minkä tason pitäisi valita?
Aloitukseen matala taso ilman baselinea tai korkeampi taso baselinen kanssa. Lukua tärkeämpää on, että analyysi ajetaan automaattisesti jokaisessa muutoksessa eikä päästä uusia virheitä läpi.