Dobry pentest aplikacji webowej nie polega na uruchomieniu skanera i wygenerowaniu raportu PDF. Skaner jest tylko jednym z narzędzi. Prawdziwa wartość pojawia się wtedy, gdy tester rozumie logikę aplikacji, role użytkowników, przepływy biznesowe, API, sesje, integracje, eksporty danych, panele administracyjne i miejsca, w których system podejmuje decyzje.
W aplikacjach webowych najgroźniejsze podatności często nie mają efektownej nazwy CVE. Nie wyglądają jak klasyczny „exploit z internetu”. Zwykle są to błędy autoryzacji, nieprawidłowe założenia biznesowe, zbyt szerokie uprawnienia, brak separacji tenantów, nadmiarowe dane w API, źle obsłużony reset hasła albo workflow, który można obejść przy ręcznej manipulacji żądaniami HTTP.
Dlaczego automatyczny skan to za mało
Automatyczne narzędzia są dobre w wykrywaniu pewnych klas problemów: brakujących nagłówków, znanych wersji bibliotek, części podatności XSS, błędów TLS, prostych podatności injection. Problem zaczyna się tam, gdzie podatność wynika z kontekstu.
Przykład: aplikacja pozwala zalogowanemu użytkownikowi pobrać plik faktury. Endpoint wygląda niepozornie:
GET /api/documents/918273/download HTTP/1.1
Host: app.example.local
Authorization: Bearer eyJ...
Cookie: session=...
Skaner widzi poprawny endpoint. Tester sprawdza, co stanie się po zmianie identyfikatora, zmianie tenant ID, zmianie nagłówków organizacji albo wykonaniu tej samej operacji z konta o niższej roli. Jeżeli system zwróci cudzy dokument, mamy problem klasy BOLA/IDOR, czyli błąd kontroli dostępu do obiektu. To może być podatność krytyczna, mimo że w automatycznym raporcie wygląda jak zwykły request HTTP.
Co powinien obejmować profesjonalny test aplikacji webowej
Zakres zależy od systemu, ale w praktyce dobry pentest webowy powinien objąć przynajmniej kilka warstw. Pierwsza to rekonesans aplikacyjny: struktura ścieżek, role, formularze, endpointy API, pliki statyczne, konfiguracja frontendu, parametry ukryte i logika przejść. Druga to analiza mechanizmów bezpieczeństwa: uwierzytelnianie, sesje, MFA, reset hasła, rejestracja, zaproszenia użytkowników, uprawnienia i separacja danych. Trzecia to testy podatności technicznych: injection, XSS, SSRF, upload plików, deserializacja, path traversal, template injection, błędy CORS i nagłówki bezpieczeństwa. Czwarta to logika biznesowa: rabaty, płatności, koszyki, workflow akceptacji, limity, eksporty i stany przejściowe.
| Obszar | Co sprawdzamy | Po co |
|---|---|---|
| Uwierzytelnianie | logowanie, reset hasła, MFA, sesje, cookies, logout | żeby konto użytkownika nie było łatwe do przejęcia albo utrzymania po wylogowaniu |
| Autoryzacja | role, obiekty, tenanty, funkcje administracyjne | żeby zwykły użytkownik nie miał dostępu do cudzych danych lub funkcji |
| Dane wejściowe | XSS, SQL/NoSQL injection, SSRF, upload, parsery | żeby wejście użytkownika nie sterowało aplikacją w niekontrolowany sposób |
| Logika biznesowa | kolejność kroków, limity, płatności, workflow | żeby procesów nie dało się obejść ręcznie przez API |
| Konfiguracja | nagłówki, CORS, TLS, cache, debug, mapy źródłowe | żeby aplikacja nie ujawniała informacji i nie obniżała ochrony przeglądarki |
Przykład 1: BOLA w panelu klienta
Załóżmy, że użytkownik A ma prawo do faktury 8128, ale nie powinien widzieć faktury 8129. Test polega na kontrolowanej zmianie identyfikatora i porównaniu odpowiedzi aplikacji.
GET /api/invoices/8129 HTTP/1.1
Authorization: Bearer token_uzytkownika_A
HTTP/1.1 200 OK
{
"id": 8129,
"company": "Inny klient sp. z o.o.",
"amount": "48 320.00 PLN",
"pdfUrl": "/api/invoices/8129/pdf"
}
Poprawne zachowanie to 403 Forbidden albo 404 Not Found, zależnie od modelu aplikacji. Jeżeli system zwraca dane, problem nie dotyczy jednego endpointu. Zwykle oznacza brak centralnej kontroli uprawnień do obiektów. W raporcie nie wystarczy napisać „zmień ID i widać fakturę”. Trzeba pokazać klasę błędu, wpływ, warunki wykorzystania, listę podobnych endpointów, rekomendację architektoniczną i sposób retestu.
Przykład 2: stored XSS, który ma znaczenie biznesowe
Nie każdy XSS jest tak samo istotny. Jeżeli payload działa tylko na koncie testera i nie ma wpływu na innych użytkowników, ryzyko jest mniejsze. Jeżeli jednak treść wprowadzona przez zwykłego użytkownika wyświetla się administratorowi w panelu zgłoszeń, mówimy o innym poziomie ryzyka.
POST /support/tickets HTTP/1.1
Content-Type: application/x-www-form-urlencoded
subject=Problem&message=<img src=x onerror=alert(document.domain)>
W dojrzałym raporcie opisujemy kontekst: gdzie payload się zapisuje, kto go widzi, jakie uprawnienia ma ofiara, czy istnieje CSP, czy cookie ma HttpOnly, czy możliwe jest wykonanie akcji w imieniu administratora, czy podatność może służyć do eskalacji. Dzięki temu klient wie, czy to kosmetyka, czy realny problem bezpieczeństwa.
Przykład 3: SSRF przez integrację z webhookiem
W nowoczesnych aplikacjach częste są integracje: webhooki, import URL, pobieranie avatarów, generowanie PDF z adresu, podgląd linków, integracje z CRM i systemami płatności. Każde miejsce, w którym serwer pobiera zasób wskazany przez użytkownika, wymaga ostrożności.
POST /api/integrations/webhook-test HTTP/1.1
Content-Type: application/json
{"url":"http://127.0.0.1:8080/admin/status"}
Tester sprawdza, czy aplikacja pozwala serwerowi odpytać zasoby lokalne, prywatne adresacje, metadane chmurowe albo panele administracyjne niedostępne z internetu. Dobra rekomendacja obejmuje allowlistę hostów, blokadę adresów prywatnych po rozwiązaniu DNS, kontrolę przekierowań, limity czasu, rozmiaru odpowiedzi i logowanie prób nadużycia.
Jak wygląda raport, który naprawdę pomaga
Raport powinien być zrozumiały dla trzech grup: zarządu, IT/security i developmentu. Zarząd potrzebuje odpowiedzi: co nam grozi, czy są dane klientów, czy jest ryzyko regulacyjne, ile mamy krytycznych tematów i co trzeba zrobić najpierw. IT potrzebuje listy systemów, zakresu, warunków testu i priorytetów. Developer potrzebuje kroków reprodukcji, request/response, kont testowych, oczekiwanego zachowania i rekomendacji technicznej.
Dlatego przy poważnym pentestcie opis podatności powinien zawierać: tytuł, wpływ biznesowy, opis techniczny, warunki wykorzystania, dowody, klasyfikację CVSS, mapowanie do STRIDE/OWASP, rekomendację krótkoterminową, rekomendację docelową oraz kryterium retestu. Bez kryterium retestu często dochodzi do „naprawy objawu”, a nie przyczyny.
Kiedy warto zamówić pentest aplikacji webowej
Najlepszy moment to okres przed produkcyjnym wdrożeniem ważnej funkcji, przed audytem klienta korporacyjnego, po większej zmianie architektury, po dodaniu nowego API, po migracji do chmury albo przed wejściem w sektor regulowany. Pentest warto też zrobić wtedy, gdy aplikacja rośnie od kilku lat i nikt nie miał czasu wrócić do starych decyzji bezpieczeństwa.
Jeżeli aplikacja obsługuje dane osobowe, płatności, dane medyczne, dokumenty firmowe, panele klientów, wielodostęp tenantowy albo role administracyjne, test manualny jest dużo bardziej wartościowy niż sam skan. W takich systemach podatność nie musi dawać przejęcia serwera, żeby była krytyczna. Wystarczy dostęp do cudzych danych albo możliwość wykonania akcji w cudzym imieniu.
Najczęstsze błędy, które realnie znajdujemy w aplikacjach webowych
W praktyce największy wpływ mają zwykle problemy na styku logiki biznesowej i kontroli dostępu: możliwość pobrania cudzego dokumentu, zmiana statusu zamówienia bez odpowiedniej roli, eksport danych innego klienta, obejście kroku akceptacji, wykonanie akcji administracyjnej z konta operatora albo dostęp do panelu przez nieudokumentowany endpoint. Takie błędy rzadko wychodzą z samego skanera, bo wymagają zrozumienia procesu.
- broken access control, IDOR/BOLA i brak separacji tenantów,
- nadużycie funkcji eksportu, importu, generowania PDF i pobierania plików,
- błędy resetu hasła, zaproszeń użytkowników, aktywacji kont i zmiany e-maila,
- stored XSS w panelach administracyjnych, zgłoszeniach i komentarzach,
- SSRF w webhookach, importerach URL, preview linków i integracjach,
- nadmiarowe dane zwracane przez API, mimo że frontend ich nie pokazuje.
Co warto przygotować przed testem
Aby pentest był skuteczny, warto przygotować środowisko testowe podobne do produkcji, konta dla wszystkich ról, opis najważniejszych procesów, przykładowe dane, listę integracji, informacje o ograniczeniach i kontakt techniczny. Dobrze przygotowany zakres skraca czas na organizację i pozwala skupić budżet na testowaniu, a nie na odgadywaniu działania systemu.