

0 / 2 embers
0 / 3000 xp
click for more info
Complete a lesson to start your streak
click for more info
Still calibrating
click for more info
Not enough gems
Cost: 6 gems
1: Managing Secrets
incomplete
2: Injecting Secrets at Runtime
incomplete
3: Protecting Secrets
incomplete
4: Build Artifacts and Deployment Hygiene
incomplete
5: Limiting Build Context
incomplete
6: Source Code and Config Leaks
incomplete
7: Public File Leaks
incomplete
8: Server-Side Request Forgery
incomplete
9: Defending Against SSRF
incomplete
10: Open Redirects
incomplete
11: Risks of Dependencies
incomplete
12: Auditing Dependencies
incomplete
13: Dependency Maintenance
incomplete
Back
ctrl+,
Next
ctrl+.
This lesson's interactive features are locked, please to keep using them
The safest SSRF defense is to avoid arbitrary destinations. If an app needs images from one provider, accept HTTPS URLs for that exact host and reject everything else.
Better yet, accept image IDs and build the URLs within server code.
Parse and validate the URL before sending a request:
func allowedURL(rawURL string) (*url.URL, bool) {
parsed, err := url.Parse(rawURL)
if err != nil || parsed.Scheme != "https" {
return nil, false
}
if parsed.User != nil || parsed.Host != "images.example.com" {
return nil, false
}
return parsed, true
}
Compare the parsed host exactly. That rejects unexpected ports and lookalike hosts such as images.example.com.attacker.test.
The HTTP client needs its own boundaries too. Set request, response-header, and TLS-handshake timeouts so a slow approved host can't hold resources indefinitely. Disable proxy discovery when it is not part of the feature's design.
Redirects need an explicit policy. Go's http.Client follows redirects by default, so an approved URL might redirect to an internal destination. A CheckRedirect function can return http.ErrUseLastResponse, leaving the redirect response unread for the caller to reject.
An exact-host allowlist avoids most DNS ambiguity, but if you truly need arbitrary public hosts, blocking private addresses gets much harder: validate every resolved IPv4 and IPv6 address and ensure the connection uses an address you checked. A separate DNS lookup followed by a normal request doesn't guarantee both operations use the same address, so it doesn't stop DNS rebinding by itself.
Bearly Secure's image-preview service can fetch any destination the server can reach. Restrict previews to the exact approved HTTPS host.
Run and submit the CLI tests from the project root.