safehttp: SSRF-safe transport for client and fetch#24
Merged
Conversation
Adds an HTTP transport that hardens registry fetches against three
related threats:
* Server-Side Request Forgery via a registry / CDN that 30x's to an
internal address (http://localhost, RFC1918, link-local, ...) so
the client probes services it shouldn't reach.
* DNS rebinding between resolve and connect — the IP that comes back
from DNS is not necessarily what gets connected to if the resolver
cache or upstream is poisoned.
* Redirect-target exfiltration via non-http(s) schemes (file://,
gopher://, data://) returned in a Location header.
Three defences in concert:
1. Dial-time IP gate. DNS is resolved once per dial; each resolved
address is checked against the block list (loopback, RFC1918,
CGNAT 100.64.0.0/10, link-local, multicast, unspecified) before
any TCP connect. The connection then dials the resolved IP
directly, so a rebind between check and connect cannot escape.
2. Redirect cap at 10 hops, re-validating every target through the
same dial gate.
3. Non-http(s) scheme rejected on redirect.
New package github.com/git-pkgs/registries/safehttp holds the
transport. client.WithSafeHTTP() opts a Client into it. The fetch
package's existing dnscache-backed dialer now gates each resolved IP
against safehttp.CheckIP before connecting.
Loopback opt-out via safehttp.EnableLoopbackForTesting (called from
TestMain) keeps existing httptest.Server-backed test suites working;
production paths never see the opt-out.
ac4054f to
ba424c1
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds an HTTP transport that hardens registry fetches against SSRF, DNS rebinding, and redirect-target exfiltration. Surfaced as a new `registries/safehttp` package plus a `client.WithSafeHTTP()` option; the `fetch` package's existing dnscache-backed dialer now gates each resolved IP against the block list.
Threats
Defences
API
```go
c := client.NewClient(client.WithSafeHTTP())
```
`fetch.NewFetcher` picks up the IP gate automatically — no API change for fetch consumers.
Test opt-out
`safehttp.EnableLoopbackForTesting()` (called from TestMain) flips loopback + private-IP gates off for the test binary so existing `httptest.Server`-backed test suites continue to work. Production paths never see this.