SSRF via HTTP redirect following — scanner reaches cloud metadata endpoints
Summary
Tsunami's HTTP client follows redirects by default (DEFAULT_FOLLOW_REDIRECTS = true), and the OkHttp-level redirect is resolved transparently before Tsunami's in-scope URL filter is applied. An attacker-controlled scan target can redirect the scanner to cloud instance metadata endpoints, exfiltrating GCP/AWS/Azure credentials.
Vulnerable Code
Root cause 1: HttpClientModule.java:335 — redirects enabled by default
private static final boolean DEFAULT_FOLLOW_REDIRECTS = true;Root cause 2: OkHttp resolves redirects before SimpleCrawlAction.java's scope check
// SimpleCrawlAction.java:96-101, 139-166
// The scope filter is applied AFTER OkHttp has already followed HTTP 302/301 redirects
.filter(crawlTarget -> CrawlConfigUtils.isCrawlTargetInScope(crawlConfig, crawlTarget))
// OkHttp's redirect following happens at the HTTP layer, returning the final response
// directly — isCrawlTargetInScope() never sees the redirect destination URLRoot cause 3: tsunami.yaml ships with trust_all_certificates: true
And HttpClientModule.java:163-175 disables hostname verification:
.hostnameVerifier((hostname, session) -> true)Attack Scenario
- Attacker controls
evil.example.com - Tsunami operator scans
evil.example.com(normal usage) - Server returns
HTTP 302 Location: http://169.254.169.254/latest/meta-data/iam/security-credentials/ - OkHttp silently follows redirect to cloud metadata endpoint (from the scanner's cloud VM)
- Response (IAM credentials JSON) is stored as a CrawlResult in Tsunami's scan output
Suggested Fix
Validate redirect destination URLs before following them: reject private IP ranges, cloud metadata endpoints, and loopback addresses. Consider adding a CheckRedirect policy to the OkHttp client.
Source: google/tsunami-security-scanner