Krótko: Przegląd kodu PHP pod kątem bezpieczeństwa to celowe czytanie kodu źródłowego z jednym pytaniem: gdzie obce dane wejściowe mogą zrobić coś, czego nie powinny? Sprawdzają się dwie formy: przegląd każdej zmiany oraz przegląd podstawowy całego projektu, wsparte analizą statyczną za pomocą PHPStan lub Psalm. Luk w interpreterze PHP, takich jak PHP2Shell, przegląd nie znajdzie, za to znajdzie wiele błędów powstających we własnym kodzie.
Dlaczego właśnie teraz spojrzeć we własny kod?
PHP2Shell zajmował w ostatnim tygodniu października 2026 przede wszystkim administratorów. Łatać, restartować, udokumentować: praca leżała po stronie serwera. Dla zespołów programistycznych zostaje potem niewygodne pytanie. Jeśli atakujący może przez inną lukę wykonać kod, co zastanie w naszej aplikacji? I ile z tych luk sami napisaliśmy?
OWASP Top 10 pokazuje od lat, że większość podatności w aplikacjach internetowych nie jest egzotyczna. Brak kontroli dostępu, injection i niebezpieczna konfiguracja plasują się wysoko. To błędy, które wprawne oko znajduje w kodzie źródłowym na długo, zanim atakujący je wypróbuje.
Dochodzi powód praktyczny. Wiele firm i tak właśnie teraz daje swoje serwery do sprawdzenia, łata je i utwardza. Kto przy okazji spojrzy na własną aplikację, zamyka lukę między eksploatacją a programowaniem. Utwardzony serwer z podatną aplikacją pozostaje narażony na atak, a starannie napisana aplikacja na niezałatanym PHP również.
Przegląd podstawowy czy przegląd zmian?
Ściągawka OWASP o Secure Code Review rozróżnia dwa rodzaje, które w praktyce się uzupełniają:
| Rodzaj | Kiedy | Zakres | Cel |
|---|---|---|---|
| Przegląd podstawowy (baseline) | nowy projekt, duże wydanie, po incydencie | cały projekt, ważony ryzykiem | ująć zasób podatności |
| Przegląd zmian (diff) | każdy pull request | tylko zmieniony kod | zapobiegać nowym błędom |
Przegląd podstawowy po incydencie jest szczególnie wartościowy. Kto właśnie oczyścił serwer, powinien wiedzieć, czy aplikacja oferuje kolejne wejścia. Przegląd zmian utrzymuje potem stan w czystości, ponieważ każda zmiana przed scaleniem jest czytana także pod kątem bezpieczeństwa.
Przegląd kodu w PHP: gdzie kumulują się błędy bezpieczeństwa
W projektach PHP warto celowo przyjrzeć się określonym funkcjom i wzorcom. Nie są zakazane, ale każde znalezisko zasługuje na pytanie, czy mogą do niego trafić obce dane.
| Wzorzec w kodzie | Możliwe ryzyko | Pogłębienie |
|---|---|---|
| SQL przez konkatenację ciągów ze zmiennymi | SQL injection | Zapobieganie SQL injection w PHP |
unserialize() na danych z zewnątrz |
wstrzyknięcie obiektów | Niebezpieczna deserializacja w PHP |
include lub require ze zmienną ścieżką |
dołączanie obcych plików | Zapobieganie Local i Remote File Inclusion |
exec(), system(), shell_exec(), proc_open() |
wykonanie poleceń | Command injection |
Wyjście bez htmlspecialchars() |
Cross-Site Scripting | escapowanie zależne od kontekstu |
== przy tokenach lub skrótach |
zamiana typów omija kontrole | hash_equals(), ścisłe porównania |
eval(), extract() na danych wejściowych |
wstrzyknięcie kodu lub zmiennych | zwykle usunąć bez zastępowania |
Szybki pierwszy przegląd daje proste wyszukiwanie. Nie zastępuje przeglądu, ale pokazuje, od czego zacząć:
# Miejsca ryzykownych funkcji we własnym kodzie (bez vendor)
grep -rnE "\b(unserialize|eval|extract|shell_exec|exec|system|passthru|proc_open)\s*\(" src/ app/ 2>/dev/null
Co najmniej tak samo ważne jest to, czego w kodzie brakuje. Czy każdy kontroler sprawdza, czy zalogowany użytkownik może zobaczyć lub zmienić właśnie ten rekord? Czy uploady są ograniczone co do typu i miejsca zapisu? Takich luk nie znajdzie żadne wyszukiwanie nazw funkcji, tylko czytanie przebiegu.
Narzędzia, które wspierają przegląd
Analiza statyczna sprawdza kod bez jego wykonywania. PHPStan i Psalm znajdują błędy typów, nieosiągalny kod i błędne założenia o wartościach zwracanych. Psalm oferuje dodatkowo analizę taint, która śledzi, czy dane z żądań przepływają bez kontroli do krytycznych miejsc. Oba można stopniowo zaostrzać, dzięki czemu mogą zacząć także starsze projekty. Przegląd daje artykuł Analiza statyczna: PHPStan i Psalm.
# Analiza statyczna w projekcie, poziom podnosić stopniowo
vendor/bin/phpstan analyse src --level=5
# Analiza taint z Psalm
vendor/bin/psalm --taint-analysis
Narzędzia dostarczają wskazówek, a nie wyroków. Każde trafienie wymaga oceny, a pusty raport nie oznacza, że aplikacja jest bezpieczna.
Równie ważne jak znajdowanie jest utrwalanie. Każde ustalenie powinno być ujęte z miejscem znalezienia, krótkim opisem, oceną ryzyka, zalecaną naprawą i statusem, najlepiej bezpośrednio w systemie zgłoszeń zespołu. Dzięki temu można prześledzić, co naprawiono, co świadomie zaakceptowano i co jest jeszcze otwarte. Po naprawie warto spojrzeć drugi raz: czy usunięto przyczynę, czy tylko jeden objaw? Czy ten sam wzorzec pojawia się w innych miejscach kodu? Błąd, który raz popełniono, jak pokazuje doświadczenie, rzadko tkwi tylko w jednym miejscu.
Lista kontrolna dla własnego zespołu
Dla przeglądów zmian sprawdziła się krótka, stała lista. Należy do szablonu pull requestów:
- Skąd pochodzą wszystkie dane przetwarzane przez tę zmianę i czy są sprawdzane po stronie serwera?
- Czy zapytania do bazy danych są budowane wyłącznie z placeholderami?
- Czy każde wyjście jest escapowane dla swojego kontekstu, czyli HTML, atrybut, JavaScript lub URL?
- Czy kod sprawdza uprawnienie do dokładnie tego obiektu, a nie tylko zalogowanie?
- Czy hasła, tokeny lub dane osobowe trafiają do logów lub komunikatów o błędach?
- Czy sekrety znajdują się w kodzie lub w plikach objętych wersjonowaniem?
- Czy dodano nowe zależności i czy są utrzymywane?
Części krytyczne dla bezpieczeństwa, takie jak logowanie, zarządzanie uprawnieniami, procesy płatności i uploady, zawsze niech czyta druga osoba, która nie uczestniczyła w tworzeniu kodu. Obce spojrzenie znajduje założenia, które autor uważa za oczywiste.
Jak konkretnie pomaga PHP SOS?
- Przeprowadzamy ze specjalistycznymi partnerami przegląd podstawowy Państwa aplikacji PHP, ważony według części o najwyższym ryzyku.
- Konfigurujemy PHPStan lub Psalm odpowiednio do stanu Państwa projektu i piszemy listę kontrolną dla Państwa pull requestów.
- Łączymy przegląd ze spojrzeniem na serwer i konfigurację, ponieważ wiele luk powstaje dopiero we współdziałaniu.
- Tam, gdzie pożądana jest kontrola z zewnątrz, uzupełniamy przegląd o audyt bezpieczeństwa i test penetracyjny.
Podsumowanie: Przegląd kodu to najtańsze miejsce na naprawę błędów bezpieczeństwa, czyli zanim zostaną wdrożone. Kto sprawdza każdą zmianę krótką listą i od czasu do czasu przegląda cały projekt, trwale zmniejsza powierzchnię ataku.
Częste pytania
Jaka jest różnica między przeglądem kodu a testem penetracyjnym?
Przegląd kodu czyta kod źródłowy i znajduje błędy, zanim zostaną wdrożone. Test penetracyjny atakuje działającą aplikację z zewnątrz. Oba się uzupełniają: przegląd znajduje przyczyny, test pokazuje, co faktycznie da się wykorzystać.
Czy przegląd kodu znajduje luki takie jak PHP2Shell?
Nie. PHP2Shell tkwi w interpreterze PHP, a nie w kodzie aplikacji. Pomaga na to wyłącznie aktualizacja PHP z restartem. Przegląd znajduje błędy we własnym kodzie, takie jak injection, brakujące kontrole uprawnień czy niebezpieczna deserializacja.
Czy PHPStan lub Psalm wystarczą do przeglądu bezpieczeństwa?
Są dobrą podstawą i automatycznie znajdują wiele błędów. Błędy logiki, brakujące kontrole uprawnień i błędne założenia o przebiegu rozpozna jednak tylko człowiek, który wie, co aplikacja ma robić.
Jak długo trwa przegląd kodu pod kątem bezpieczeństwa?
Zależy to od zakresu. Przegląd każdej zmiany w pull requeście kosztuje niewiele czasu. Pełny przegląd rozrośniętego projektu to osobne przedsięwzięcie, które według ryzyka ogranicza się do najważniejszych części.