# Statična analiza: PHPStan in Psalm

> PHPStan in Psalm razložena: stopnje pravil, baseline, analiza taint ter kaj statična analiza zmore za varne aplikacije PHP in česa ne zmore.

Vir: https://phpsos.de/sl/php/statische-analyse/  
Stanje: 25.10.2026  
Ponudnik: PHP SOS, Nujna pomoč za PHP in varnost strežnikov. Takojšnja pomoč po WhatsAppu: https://wa.me/491736494914?text=Pozdravljeni%2C%20PHP%20SOS%2C%20potrebujemo%20pomo%C4%8D%20z%20na%C5%A1im%20stre%C5%BEnikom%20PHP.%20Podjetje%3A%20%E2%80%A6%20Spletna%20stran%3A%20%E2%80%A6

**Na kratko:** Statična analiza preverja kodo PHP, ne da bi jo izvedla, in tako najde napake tipov, nedefinirane spremenljivke, mrtvo kodo in klice na morda praznih vrednostih. Najbolj razširjeni orodji sta PHPStan (stopnje pravil od 0 do 10) in Psalm (stopnje napak od 1 do 8, poleg tega analiza taint za nevarne tokove podatkov). Najdeta napake v vaši aplikaciji, ne v interpreterju PHP; proti vrzelim, kot je PHP2Shell, pomaga samo posodobitev PHP.

## Kaj je statična analiza?

Test izvede kodo in primerja rezultat. Statična analiza pa kodo bere kot zelo temeljit pregledovalec in iz tipov, vrnjenih vrednosti in klicev sklepa, kje se lahko kaj zalomi. Najde napake tudi v vejah, do katerih noben test nikoli ne pride.

Za odločevalce je korist preprosta: napake, najdene pred zagonom v živo, stanejo del tega, kar stanejo napake, ki jih opazijo stranke. Za razvijalce je stalni spremljevalec, ki teče v razvojnem okolju in v cevovodu CI. Če analiza ob spremembi sproži alarm, se ta ne prevzame, dokler napaka ni odpravljena. Tako ne zraste nov stari tovor, medtem ko se obstoječi postopoma odpravlja. Skupaj s [testi s PHPUnit in Pest](https://phpsos.de/sl/php/php-testen/) tvori temelj kakovosti kode.

## PHPStan: stopnje pravil od 0 do 10

PHPStan se namesti kot razvojna odvisnost in za delovanje potrebuje PHP od 7.4:

```bash
composer require --dev phpstan/phpstan
vendor/bin/phpstan analyse src tests
```

Brez nadaljnjih navedb PHPStan preverja le najnujnejše. Strogost nadzorujete prek enajstih stopenj, vsaka vključuje tiste pod seboj:

| Stopnja | Kaj se dodatno preverja (izbor) |
|---|---|
| 0 | neznani razredi in funkcije, napačno število argumentov, vedno nedefinirane spremenljivke |
| 3 | vrnjeni tipi in tipi, ki se dodelijo lastnostim |
| 5 | tipi argumentov pri klicih funkcij in metod |
| 6 | manjkajoče navedbe tipov |
| 8 | klici metod in dostopi do lastnosti na vrednostih, ki so lahko null |
| 10 | najstrožje ravnanje z `mixed`, tudi pri manjkajočih tipih |

Z `--level max` vedno teče najvišja stopnja. Dokumentacija pa opozarja, da lahko nadgradnja PHPStan tedaj prinese veliko novih sporočil. Tipična najdba od stopnje 8:

```php
<?php
function kundenname(?Kunde $kunde): string
{
    return $kunde->name();   // PHPStan: klic na vrednosti, ki je lahko null
}
```

## Uvedba PHPStan brez poplave napak: baseline

V zrelih projektih PHPStan na visoki stopnji pogosto javi na stotine mest. Težavo reši baseline: vsa obstoječa sporočila shrani v datoteko, PHPStan pa od takrat javlja samo še nove napake.

```bash
vendor/bin/phpstan analyse --level 6 src tests --generate-baseline
```

Ustvarjeno datoteko `phpstan-baseline.neon` vključite v konfiguracijo:

```neon
includes:
    - phpstan-baseline.neon

parameters:
    level: 6
    paths:
        - src
        - tests
```

Tako ostane stari tovor vidno dokumentiran, nova koda pa mora biti od začetka čista.

## Psalm in analiza taint

Psalm zasleduje podobne cilje kot PHPStan. Stopnje tečejo obratno: 1 je najstrožja, 8 najbolj popustljiva, privzeta je 2. Psalm potrebuje PHP od 8.2 in se vzpostavi takole:

```bash
composer require --dev vimeo/psalm
./vendor/bin/psalm --init
./vendor/bin/psalm --taint-analysis
```

Analiza taint je za varnost posebej zanimiva. „Taint“ pomeni onesnaženje: Psalm označi podatke iz virov, ki jih lahko nadzira napadalec, na primer `$_GET`, `$_POST`, `$_COOKIE`, `$_REQUEST` ali `php://input`. Nato spremlja, ali ti podatki nezaščiteni prispejo na nevarna mesta, tako imenovane ponore (sink): izpis z `echo`, `include`, `header` ali poizvedbe SQL. Med vgrajene kategorije med drugim sodijo `sql`, `html`, `shell`, `include`, `eval`, `ssrf` in `unserialize`.

```php
<?php
// Psalm javi tok iz $_GET v izpis HTML (kategorija html)
echo 'Hallo ' . $_GET['name'];

// Odpravljeno: izpis maskirati glede na kontekst
echo 'Hallo ' . htmlspecialchars($_GET['name'] ?? '', ENT_QUOTES, 'UTF-8');
```

Dokumentacija Psalm odkrito navaja meje: analiza predpostavlja, da se maskiranje izvaja pravilno. Fine napake, na primer manjkajoči narekovaji okoli atributa HTML, lahko kljub temu pustijo vrzeli. Psalm zato priporoča parametrizirane poizvedbe za SQL in kontekstno ozaveščene predloge za HTML. Rezultate je mogoče izpisati v formatu SARIF, ki ga med drugim razume GitHub Code Scanning.

## Statična analiza in varnost po PHP2Shell

Tu se splača poštena razmejitev. PHP2Shell, torej CVE-2026-109618 in CVE-2026-109619, tiči v interpreterju PHP. Nobeno orodje, ki bere kodo vaše aplikacije, teh vrzeli ne najde, in nobena sprememba kode jih ne zapre. To zmore samo posodobitev na PHP 8.5.12, 8.4.27, 8.3.36 ali 8.2.35.

Kljub temu statična analiza k varnosti prispeva na treh mestih:

1. **Sposobnost nadgradnje:** najde kodo, ki na novih različicah PHP ne teče več. S tem se zniža ovira za prehod z 8.1 ali 8.2 na podprto različico.
2. **Lastne vrzeli:** analiza taint najde poti za [SQL injection](https://phpsos.de/sl/ratgeber/sql-injection-php/), cross-site scripting ali vključitev datotek. Projekt PHP v svoji varnostni politiki pojasni, da neprevereni vnosi v funkcije, kot je `mysqli_query()`, niso napaka PHP, temveč so v odgovornosti aplikacije.
3. **Robustnost:** številne smrtne napake nastanejo zaradi klicev na null ali napačnih tipov. php.net v zvezi s CVE-2026-109619 izrecno svetuje, da se od zunaj sprožljive smrtne napake v aplikaciji odpravijo.

Statična analiza ne nadomesti [varnostnega pregleda kode](https://phpsos.de/sl/blog/sicherheits-code-review-php/) s strani ljudi, naredi pa ga učinkovitejšega, ker so rutinske napake predhodno izločene.

## Kako PHP SOS pomaga konkretno?

V okviru [varnostnega pregleda in penetracijskega testa](https://phpsos.de/sl/leistungen/sicherheitsaudit-penetrationstest/) ravnamo takole:

- **Vzpostaviti orodja:** PHPStan ali Psalm z ustrezno stopnjo in baseline, vključena v vaš obstoječi cevovod.
- **Oceniti varnostne najdbe:** preverimo rezultate analize taint in ločimo prava tveganja od lažnih alarmov.
- **Pripraviti nadgradnjo:** pokažemo, katera mesta blokirajo prehod na podprto različico PHP.
- **Predati rezultate:** prejmete prednostni seznam s konkretnimi mesti v kodi za svojo ekipo ali agencijo.


## Pogosta vprašanja

**Kakšna je razlika med PHPStan in Psalm?**  
Oba preverjata tipe in najdeta napake brez izvajanja. PHPStan šteje svoje stopnje od 0 (ohlapno) do 10 (strogo), Psalm od 8 (ohlapno) do 1 (strogo). Psalm ima vgrajeno analizo taint za varnostne težave.

**Ali lahko PHPStan uvedem v star projekt?**  
Da. Z baseline PHPStan vsa obstoječa sporočila shrani v datoteko in nato javlja samo nove napake. Tako ekipa začne brez poplave napak in stare bremene postopoma odpravlja.

**Ali statična analiza najde PHP2Shell?**  
Ne. PHP2Shell tiči v interpreterju PHP, ne v vaši kodi. Proti njemu pomaga samo posodobitev PHP. Statična analiza pa pomaga kodo pripraviti na nove različice PHP, da je posodobitev hitrejša.

**Katero stopnjo izbrati?**  
Za začetek nizko stopnjo brez baseline ali višjo stopnjo z baseline. Pomembnejša od številke je, da analiza teče samodejno ob vsaki spremembi in novih napak ne spusti skozi.

## Viri

- [PHPStan](https://phpstan.org/)
- [Psalm](https://psalm.dev/)
- [OWASP Cheat Sheet Series](https://cheatsheetseries.owasp.org/)
