Podczas testów penetracyjnych aplikacji webowej w modelu mikroserwisów wykryliśmy podatność SSRF (Server-Side Request Forgery) w module generowania PDF. System przyjmował URL do “załącznika” i pobierał go po stronie serwera, bez wystarczających ograniczeń. W kontrolowanych warunkach dało się wymusić zapytania do zasobów wewnętrznych i potencjalnie do metadata usług chmurowych. Naprawa objęła allowlistę domen, blokadę adresów prywatnych i metadanych, twarde time-outy, izolację sieciową kontenera oraz testy regresji.
Kontekst: szybki produkt, szybkie PDF-y, szybkie ryzyka
Klient rozwijał platformę webową B2B, w której raporty i potwierdzenia były generowane jako PDF i wysyłane mailem do użytkowników. Żeby nie blokować głównej aplikacji, PDF robił osobny mikroserwis: dostaje dane wejściowe, pobiera “dodatkowe zasoby” (np. logo klienta, wykresy, obrazki), renderuje i oddaje gotowy plik.
Brzmi rozsądnie.
(I dokładnie w takich “rozsądnych” rzeczach SSRF lubi się ukrywać.)
Problem: serwer pobierał URL wskazany przez użytkownika
Moduł PDF przyjmował parametr assetUrl lub podobny (adres zasobu, który ma zostać wklejony do dokumentu). Następnie serwer wykonywał request HTTP i pobierał dane.
Krytyczne było to, że walidacja URL była zbyt miękka. Sprawdzano np. czy to “jakiś URL”, ale nie narzucono twardych zasad, skąd serwer w ogóle ma prawo coś pobierać.
To jest definicja ryzyka SSRF: atakujący nie atakuje bezpośrednio internetu, tylko używa Twojego serwera jako przeglądarki do sieci wewnętrznej.
Jak pracowaliśmy: test SSRF krok po kroku
Zrobiliśmy klasyczną triadę testów, która szybko mówi prawdę:
- Czy serwer wykonuje request do adresu, który mu podam?
- Czy mogę sięgnąć do adresów prywatnych lub localhost?
- Czy mogę sięgnąć do usług “wrażliwych” w sieci wewnętrznej (panele, metadata, internal API)?
Wszystko w środowisku testowym i w trybie bezpiecznym. Tu nie chodzi o “wyciskanie” systemu, tylko o jednoznaczny dowód, że mechanizm jest podatny.
Odkrycie: SSRF przez parametr zasobu do PDF
Zanonimizowany proof-of-concept (mechanizm)
Żądanie normalne (pobranie obrazka z CDN):
POST /api/v1/pdf/render
Authorization: Bearer <token>
Content-Type: application/json
{
"template": "invoice",
"assetUrl": "https://cdn.example.com/assets/logo.png"
}
Żądanie testowe (wskazanie zasobu z sieci wewnętrznej):
POST /api/v1/pdf/render
Authorization: Bearer <token>
Content-Type: application/json
{
"template": "invoice",
"assetUrl": "http://127.0.0.1:8080/admin"
}
W kontrolowanym scenariuszu serwer próbował pobrać zasób spod wskazanego adresu. To samo dotyczyło adresów prywatnych (np. zakresy 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16), co oznaczało, że atakujący mógłby mapować sieć wewnętrzną lub uderzać w panele, które “niby są tylko internal”.
W środowiskach chmurowych SSRF ma jeszcze jeden “bonus level”: możliwość dotarcia do endpointów metadanych (zależnie od dostawcy). Dlatego potraktowaliśmy to jako podatność o wysokim priorytecie, nawet jeśli w danym momencie “nic nie wyciekło”.
Ryzyko biznesowe: dlaczego SSRF to nie jest “fajny trick”
SSRF bywa niedoceniane, bo wygląda jak “serwer pobiera URL, no i co?”. Problem zaczyna się, gdy uświadomisz sobie, co serwer widzi, a użytkownik nie:
- sieć wewnętrzna, do której nikt z zewnątrz nie powinien mieć dostępu,
- panele admin, usługi pomocnicze, wewnętrzne endpointy,
- w chmurze: potencjalnie metadane i poświadczenia runtime (zależnie od konfiguracji).
To jest podatność, która potrafi być “cicha”, a skutki potrafią być bardzo głośne.
Remediacja: jak to naprawiliśmy, żeby temat nie wrócił przy kolejnych feature’ach
Naprawa SSRF powinna być wielowarstwowa, bo jeden filtr URL to zwykle za mało.
1) Allowlista domen dla zasobów
Zamiast “blokować złe”, narzuciliśmy “pozwalamy tylko na dobre” (np. tylko własny CDN, tylko konkretne domeny). Jeśli zasób nie jest na allowliście, request jest odrzucany.
2) Blokada adresów prywatnych i localhost na poziomie resolvowania
Nie tylko regex na URL. Walidacja obejmowała resolvowanie DNS i sprawdzenie, czy końcowy adres IP nie wpada w zakresy prywatne, loopback, link-local itp. (to ważne, bo SSRF lubi obchodzić naiwne filtry).
3) Twarde limity requestów
Time-outy, limit rozmiaru odpowiedzi, limit redirectów. SSRF często łączy się z DoS (serwer wisi na requestach) albo z próbami “skakania” redirectami.
4) Izolacja sieciowa mikroserwisu PDF
Najbardziej inżynierska część: kontener od renderowania PDF nie potrzebował dostępu do sieci wewnętrznej. Ograniczyliśmy egress do absolutnego minimum, co zmniejsza blast radius nawet jeśli walidacja kiedyś pęknie.
5) Testy regresji
Dodaliśmy testy negatywne: prywatne IP, localhost, nietypowe formaty URL, redirect chain. Dzięki temu SSRF nie wraca “przy okazji” refaktoru.
Po wdrożeniu wykonaliśmy retesty i potwierdziliśmy, że mikroserwis nie wykonuje requestów poza allowlistę, a próby wskazania adresów wewnętrznych kończą się blokadą.
Efekt: bezpieczniejszy mikroserwis i mniejsze ryzyko “niewidzialnych przejść”
Po naprawie klient dostał nie tylko “zamkniętą dziurę”, ale też klarowny wzorzec dla wszystkich miejsc w systemie, które pobierają zasoby z zewnątrz (importy, webhooki, integracje, preview, generatory).
To jest fajny moment, bo SSRF lubi pojawiać się w wielu modułach, tylko pod innymi nazwami.
Powiązane case studies
- Kopia zapasowa dla każdego: wyciek kodu przez katalog .git — Katalog repozytorium zostawiony w webroocie oddaje kod i wszystkie poświadczenia.
- Jeden upload i pełne RCE — Plik, który przechodzi walidację, trafia do katalogu wykonywalnego i uruchamia kod.
- Niewidzialny pracownik: token JWT ważny po wylogowaniu — Wylogowanie po stronie przeglądarki nie kończy sesji, jeśli backend nie unieważnia tokena.
Jak Pentestica może pomóc
Jeśli masz mikroserwisy, integracje, importy plików, generowanie PDF, preview linków, webhooki, to SSRF jest jedną z tych klas podatności, które warto sprawdzić wcześniej niż później.
W Pentestica robimy testy penetracyjne aplikacji web i API w sposób, który łapie takie “logiczne” błędy. Nie tylko klasyczne XSS-y, ale też rzeczy, które realnie dotykają infrastruktury i chmury.

Redakcja Pentestica to zespół pentesterów i konsultantów bezpieczeństwa, którzy na co dzień wykonują testy penetracyjne, testy TLPT wymagane przez DORA, red teaming i audyty bezpieczeństwa IT, a także prowadzą wdrożenia zgodności z NIS2, DORA i MiCA. Teksty na tym blogu piszemy z tej praktyki, a nie z opracowań. Każde twierdzenie o przepisie, terminie albo karze opieramy na źródle pierwotnym: dzienniku ustaw, tekście dyrektywy, komunikacie organu nadzoru. Jeśli czegoś nie da się potwierdzić, piszemy o tym wprost, zamiast powtarzać liczbę krążącą po branżowych portalach.