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 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:
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
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.
vendor/bin/phpstan analyse --level 6 src tests --generate-baseline
Wygenerowany plik phpstan-baseline.neon włączają Państwo do konfiguracji:
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:
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
// 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:
- 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ę.
- Własne luki: Analiza taint znajduje drogi do SQL injection, 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. - 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 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 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.