# Analiza statyczna: PHPStan i Psalm

> PHPStan i Psalm wyjaśnione: poziomy reguł, baseline, analiza taint oraz to, co analiza statyczna może, a czego nie może dać dla bezpiecznych aplikacji PHP.

Źródło: https://phpsos.de/pl/php/statische-analyse/  
Stan: 25.10.2026  
Dostawca: PHP SOS, Pomoc awaryjna PHP i bezpieczeństwo serwerów. Natychmiastowa pomoc przez WhatsApp: https://wa.me/491736494914?text=Dzie%C5%84%20dobry%2C%20PHP%20SOS%2C%20potrzebujemy%20pomocy%20z%20naszym%20serwerem%20PHP.%20Firma%3A%20%E2%80%A6%20Strona%20internetowa%3A%20%E2%80%A6

**Krótko:** Analiza statyczna sprawdza kod PHP bez jego wykonywania i w ten sposób znajduje błędy typów, niezdefiniowane zmienne, martwy kod i wywołania na potencjalnie pustych wartościach. Dwa popularne narzędzia to PHPStan (poziomy reguł od 0 do 10) i Psalm (poziomy błędów od 1 do 8, do tego analiza taint dla niebezpiecznych przepływów danych). Znajdują błędy w Państwa aplikacji, a nie w interpreterze PHP; przeciw lukom takim jak PHP2Shell pomaga tylko aktualizacja PHP.

## Czym jest analiza statyczna?

Test wykonuje kod i porównuje wynik. Analiza statyczna natomiast czyta kod jak bardzo dokładny recenzent i wnioskuje z typów, wartości zwracanych i wywołań, gdzie coś może pójść źle. Znajduje błędy także w gałęziach, do których żaden test nigdy nie dociera.

Dla osób podejmujących decyzje korzyść jest prosta: błędy znalezione przed uruchomieniem kosztują ułamek tego, co błędy zauważone przez klientów. Dla programistów jest stałym towarzyszem, który działa w środowisku programistycznym i w pipeline CI. Jeśli analiza zgłosi alarm przy zmianie, zmiana nie zostanie przyjęta, dopóki błąd nie zostanie naprawiony. W ten sposób nie przybywa nowych zaległości, a istniejące są stopniowo spłacane. Razem z [testami z PHPUnit i Pest](https://phpsos.de/pl/php/php-testen/) tworzy fundament jakości kodu.

## PHPStan: poziomy reguł od 0 do 10

PHPStan instaluje się jako zależność deweloperską i do działania wymaga PHP od 7.4:

```bash
composer require --dev phpstan/phpstan
vendor/bin/phpstan analyse src tests
```

Bez dodatkowych ustawień PHPStan sprawdza tylko to, co niezbędne. Rygor sterują Państwo jedenastoma poziomami, z których każdy obejmuje poziomy niższe:

| Poziom | Co jest dodatkowo sprawdzane (wybór) |
|---|---|
| 0 | nieznane klasy i funkcje, błędna liczba argumentów, zmienne zawsze niezdefiniowane |
| 3 | typy zwracane i typy przypisywane właściwościom |
| 5 | typy argumentów przy wywołaniach funkcji i metod |
| 6 | brakujące deklaracje typów |
| 8 | wywołania metod i dostęp do właściwości na wartościach, które mogą być null |
| 10 | najbardziej rygorystyczne traktowanie `mixed`, także przy brakujących typach |

Z `--level max` zawsze działa najwyższy poziom. Dokumentacja ostrzega jednak, że wtedy aktualizacja PHPStan może przynieść wiele nowych komunikatów. Typowe znalezisko od poziomu 8:

```php
<?php
function kundenname(?Kunde $kunde): string
{
    return $kunde->name();   // PHPStan: wywołanie na wartości, która może być null
}
```

## Wprowadzanie PHPStan bez zalewu błędów: baseline

W rozrośniętych projektach PHPStan na wysokim poziomie często zgłasza setki miejsc. Baseline rozwiązuje ten problem: zapisuje wszystkie istniejące komunikaty w pliku, a PHPStan od tej chwili zgłasza już tylko nowe błędy.

```bash
vendor/bin/phpstan analyse --level 6 src tests --generate-baseline
```

Wygenerowany plik `phpstan-baseline.neon` włączają Państwo do konfiguracji:

```neon
includes:
    - phpstan-baseline.neon

parameters:
    level: 6
    paths:
        - src
        - tests
```

W ten sposób zaległości pozostają widocznie udokumentowane, a nowy kod musi być czysty od początku.

## Psalm i analiza taint

Psalm ma podobne cele jak PHPStan. Poziomy biegną odwrotnie: 1 jest najbardziej rygorystyczny, 8 najbardziej pobłażliwy, domyślny jest 2. Psalm wymaga PHP od 8.2 i konfiguruje się go tak:

```bash
composer require --dev vimeo/psalm
./vendor/bin/psalm --init
./vendor/bin/psalm --taint-analysis
```

Analiza taint jest dla bezpieczeństwa szczególnie interesująca. „Taint” oznacza skażenie: Psalm oznacza dane ze źródeł, które może kontrolować atakujący, na przykład `$_GET`, `$_POST`, `$_COOKIE`, `$_REQUEST` lub `php://input`. Następnie śledzi, czy te dane docierają bez ochrony do niebezpiecznych miejsc, tzw. ujść: wyjście przez `echo`, `include`, `header` lub zapytania SQL. Do wbudowanych kategorii należą między innymi `sql`, `html`, `shell`, `include`, `eval`, `ssrf` i `unserialize`.

```php
<?php
// Psalm zgłasza przepływ z $_GET do wyjścia HTML (kategoria html)
echo 'Hallo ' . $_GET['name'];

// Naprawione: maskować wyjście odpowiednio do kontekstu
echo 'Hallo ' . htmlspecialchars($_GET['name'] ?? '', ENT_QUOTES, 'UTF-8');
```

Dokumentacja Psalm otwarcie podaje granice: analiza zakłada, że maskowanie odbywa się prawidłowo. Subtelne błędy, na przykład brak cudzysłowów wokół atrybutu HTML, mogą mimo to zostawiać luki. Psalm zaleca dlatego parametryzowane zapytania dla SQL i szablony świadome kontekstu dla HTML. Wyniki można wyprowadzać w formacie SARIF, który rozumie między innymi GitHub Code Scanning.

## Analiza statyczna i bezpieczeństwo po PHP2Shell

Warto tu uczciwie wytyczyć granicę. PHP2Shell, czyli CVE-2026-109618 i CVE-2026-109619, tkwi w interpreterze PHP. Żadne narzędzie czytające kod Państwa aplikacji nie znajdzie tych luk i żadna zmiana kodu ich nie zamknie. Zrobi to tylko aktualizacja do PHP 8.5.12, 8.4.27, 8.3.36 lub 8.2.35.

Mimo to analiza statyczna przyczynia się do bezpieczeństwa w trzech miejscach:

1. **Zdolność do aktualizacji:** Znajduje kod, który nie działa już na nowych wersjach PHP. Zmniejsza to próg przejścia z 8.1 lub 8.2 na wspieraną wersję.
2. **Własne luki:** Analiza taint znajduje drogi do [SQL injection](https://phpsos.de/pl/ratgeber/sql-injection-php/), cross-site scriptingu lub dołączania plików. Projekt PHP wyjaśnia w swojej polityce bezpieczeństwa, że niesprawdzone dane wejściowe przekazywane do funkcji takich jak `mysqli_query()` nie są błędem PHP, lecz leżą w odpowiedzialności aplikacji.
3. **Odporność:** Wiele błędów krytycznych powstaje przez wywołania na null lub błędne typy. W związku z CVE-2026-109619 php.net wyraźnie radzi naprawiać w aplikacji błędy krytyczne, które można wywołać z zewnątrz.

Analiza statyczna nie zastępuje [przeglądu kodu pod kątem bezpieczeństwa](https://phpsos.de/pl/blog/sicherheits-code-review-php/) przez ludzi, ale czyni go bardziej efektywnym, ponieważ błędy rutynowe są wcześniej wyeliminowane.

## Jak konkretnie pomaga PHP SOS?

W ramach [audytu bezpieczeństwa i testu penetracyjnego](https://phpsos.de/pl/leistungen/sicherheitsaudit-penetrationstest/) postępujemy tak:

- **Konfiguracja narzędzi:** PHPStan lub Psalm z odpowiednim poziomem i baseline, włączone do Państwa istniejącego pipeline.
- **Ocena znalezisk dotyczących bezpieczeństwa:** Sprawdzamy wyniki analizy taint i oddzielamy prawdziwe ryzyka od fałszywych alarmów.
- **Przygotowanie aktualizacji:** Pokazujemy, które miejsca blokują przejście na wspieraną wersję PHP.
- **Przekazanie wyników:** Otrzymują Państwo listę priorytetów z konkretnymi miejscami w kodzie dla Państwa zespołu lub agencji.


## Częste pytania

**Jaka jest różnica między PHPStan a Psalm?**  
Oba sprawdzają typy i znajdują błędy bez wykonywania kodu. PHPStan liczy swoje poziomy od 0 (luźny) do 10 (rygorystyczny), Psalm od 8 (luźny) do 1 (rygorystyczny). Psalm ma wbudowaną analizę taint dla problemów bezpieczeństwa.

**Czy mogę wprowadzić PHPStan w starym projekcie?**  
Tak. Za pomocą baseline PHPStan zapisuje wszystkie istniejące komunikaty w pliku i potem zgłasza tylko nowe błędy. Zespół startuje wtedy bez zalewu błędów i stopniowo spłaca dług z przeszłości.

**Czy analiza statyczna znajdzie PHP2Shell?**  
Nie. PHP2Shell tkwi w interpreterze PHP, a nie w Państwa kodzie. Pomaga przeciw temu tylko aktualizacja PHP. Analiza statyczna pomaga jednak przygotować kod na nowe wersje PHP, aby aktualizacja była szybsza.

**Jaki poziom wybrać?**  
Na początek niski poziom bez baseline albo wyższy poziom z baseline. Ważniejsza od liczby jest to, aby analiza uruchamiała się automatycznie przy każdej zmianie i nie przepuszczała nowych błędów.

## Źródła

- [PHPStan](https://phpstan.org/)
- [Psalm](https://psalm.dev/)
- [OWASP Cheat Sheet Series](https://cheatsheetseries.owasp.org/)
