Skip to content

fix(http): strict-mode SSRF guard (#4420) and docs (#4423) - #4425

Open
stevenvegt wants to merge 3 commits into
V5.4from
backport-4420-v5.4
Open

fix(http): strict-mode SSRF guard (#4420) and docs (#4423)#4425
stevenvegt wants to merge 3 commits into
V5.4from
backport-4420-v5.4

Conversation

@stevenvegt

Copy link
Copy Markdown
Member

What

Backport of #4420 (strict-mode SSRF dial guard) and #4423 (deployment documentation) to V5.4.

V5.4 predates the shared http/client package where the fix lives on master, so this is a port rather than a cherry-pick. The SSRF guard itself (ssrf.go, the IANA prefix lists, allow/deny config handling) is copied unchanged from #4420; the wiring is written against the V5.4 code base:

  • New http/client package containing the guard and a SafeHttpTransport: a clone of http.DefaultTransport with the strict-mode dial guard installed (checked against the resolved IP, so DNS rebinding cannot bypass it, and applied on every connection including redirect hops).
  • The clients that fetch URLs influenced by other parties now use that transport: the OpenID4VCI issuer and wallet clients (vcr/vcr.go), the OpenID4VCI identifier resolver (vcr/openid4vci/identifiers.go), and the OAuth relying party client (auth/services/oauth/relying_party.go, which resolves endpoints from peer DID documents).
  • core.NewStrictHTTPClient now refuses redirects that downgrade from HTTPS to HTTP in strict mode (reimplementing the standard library's 10-redirect cap, which setting CheckRedirect replaces).
  • New config options http.client.allowedinternalcidrs and http.client.deniedcidrs, wired through Engine.Configure (invalid CIDRs fail startup). Cloud metadata endpoints are always blocked and cannot be re-admitted via the allowlist.
  • OpenID4VCI e2e test configs allow the RFC1918 ranges, since Docker auto-assigns the compose network a private subnet.
  • Deployment documentation: "Outbound HTTP and SSRF protection" section added to the production configuration page (V5.4 has no security considerations page), linked from the release notes entry.

Deliberate deviations from #4420

  • The guard is NOT installed on http.DefaultTransport itself. PKI CRL/denylist fetching, the external crypto storage client, and the internal API clients keep their current behavior, so strict-mode deployments with a private CRL endpoint or an internal secret store are not broken by a patch release. This mirrors master, where those clients are also outside the guarded transport (Route PKI CRL and denylist fetching through the hardened HTTP client #4422).
  • The code.dny.dev/ssrf test-only dependency and the IANA drift test are not included. 5.4 is EOL; keeping the prefix lists in sync with the IANA registries happens on 6.2 and master, and list updates can be backported from there if ever needed.

Testing

  • Full go test ./... passes locally on this branch.
  • http/client keeps the behavioral tests from fix(http): block SSRF to non-public addresses in strict mode #4420 (guard blocking, allowlist, denied-over-allowed precedence, metadata blocking, zoned addresses), plus engine-level tests that the config options propagate through Engine.Configure.

Fixes potential SSRF vulnerability by preventing the internal http client of connecting to a curated IANA list of prohibited (internal) endpoints/ip ranges.

This check is executed at the transport layer just after IP lookup so we don't rely on DNS.

An administrator has the config options to allow or deny additional ip ranges.

See #4420 for additional info.

Assisted-by: AI
Add an SSRF section to the security considerations page explaining the
strict-mode outbound guard and how to configure allowedinternalcidrs and
deniedcidrs in production. Link to it from the release notes entry.

Assisted-by: AI
TestOpenID4VCIConnectionReuse limits connections by mutating
http.DefaultTransport at test time. The OpenID4VCI clients now clone
client.SafeHttpTransport, which was cloned from http.DefaultTransport at
package init, so the limit no longer reached them and the test counted
unbounded connections. Set the limit on SafeHttpTransport as well.

Assisted-by: AI
@qltysh

qltysh Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Qlty


Coverage Impact

This PR will not change total coverage.

Modified Files with Diff Coverage (8)

RatingFile% DiffUncovered Line #s
Coverage rating: A Coverage rating: A
http/engine.go100.0%
Coverage rating: B Coverage rating: B
http/cmd/cmd.go100.0%
Coverage rating: C Coverage rating: C
vcr/vcr.go100.0%
Coverage rating: B Coverage rating: B
core/http_client.go46.2%150-156
Coverage rating: B Coverage rating: B
auth/services/oauth/relying_party.go100.0%
Coverage rating: B Coverage rating: B
vcr/openid4vci/identifiers.go100.0%
New Coverage rating: A
http/client/ssrf.go97.0%197-198
New Coverage rating: A
http/client/client.go100.0%
Total91.9%
🤖 Increase coverage with AI coding...
In the `backport-4420-v5.4` branch, add test coverage for this new code:

- `core/http_client.go` -- Line 150-156
- `http/client/ssrf.go` -- Line 197-198

🚦 See full report on Qlty Cloud »

🛟 Help
  • Diff Coverage: Coverage for added or modified lines of code (excludes deleted files). Learn more.

  • Total Coverage: Coverage for the whole repository, calculated as the sum of all File Coverage. Learn more.

  • File Coverage: Covered Lines divided by Covered Lines plus Missed Lines. (Excludes non-executable lines including blank lines and comments.)

    • Indirect Changes: Changes to File Coverage for files that were not modified in this PR. Learn more.

@stevenvegt stevenvegt changed the title Backport: strict-mode SSRF guard (#4420) and docs (#4423) to V5.4 Backport: strict-mode SSRF guard (#4420) and docs (#4423) Jul 31, 2026
@stevenvegt stevenvegt changed the title Backport: strict-mode SSRF guard (#4420) and docs (#4423) fix(http): strict-mode SSRF guard (#4420) and docs (#4423) Jul 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants