• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

stacklok / toolhive / 26950483544
66%

Build:
DEFAULT BRANCH: main
Ran 04 Jun 2026 12:08PM UTC
Jobs 1
Files 747
Run time 2min
Badge
Embed ▾
README BADGES
x

If you need to use a raster PNG badge, change the '.svg' to '.png' in the link

Markdown

Textile

RDoc

HTML

Rst

04 Jun 2026 12:02PM UTC coverage: 65.868%. Remained the same
26950483544

push

github

web-flow
Merge commit from fork

* Add NAT64 prefixes to IsPrivateIP SSRF guard

The hand-rolled private/reserved IP guard in pkg/networking/utilities.go did
not recognise the IPv6 NAT64 translation prefixes 64:ff9b::/96 (RFC 6052) and
64:ff9b:1::/48 (RFC 8215). A NAT64 address such as 64:ff9b:1::a9fe:a9fe is the
encoding of 169.254.169.254 (the cloud metadata endpoint) but is a syntactically
global-unicast IPv6 address, so IsPrivateIP returned false and the connection
was allowed. Behind a NAT64/DNS64 gateway this enabled SSRF to internal and
link-local services (including IMDS) via the CIMD authorization-server fetch
path and the webhook/remote HTTP client.

IsPrivateIP now detects NAT64-prefixed addresses, extracts the embedded IPv4
(low 32 bits), and re-evaluates it with the existing IPv4 private/reserved
checks. NAT64 addresses that embed a genuinely public IPv4 remain allowed, so
legitimate NAT64 egress is not over-blocked.

* Harden NAT64 /48 decoding and add SSRF tests

The initial fix always read the embedded IPv4 from the low 32 bits.
That is correct for the well-known 64:ff9b::/96 and the 64:ff9b:1::/96
sub-prefix, but the RFC 8215 local-use range is a /48 that operators may
subdivide with a shorter NAT64 prefix, placing the embedded IPv4 outside
the low 32 bits. Decoding the low 32 bits there could read attacker-chosen
suffix bytes and misclassify an internal target as public — a
false-negative SSRF bypass.

Limit low-32-bit decoding to the two /96 prefixes and block the remainder
of 64:ff9b:1::/48 wholesale, so undecodable NAT64 addresses fail closed.
Add NAT64 coverage (private and public embeddings, plus the non-/96
local-use case) to TestIsPrivateIP and TestAddressReferencesPrivateIp,
which the initial change asserted but did not commit.

Behavior change: addresses in 64:ff9b:1::/48 but outside 64:ff9b:1::/96
are now classified as private even when their low 32 bits embed a public
IPv4. This affects only deployments that use a non-/96 NAT64 pre... (continued)

27 of 28 new or added lines in 1 file covered. (96.43%)

13 existing lines in 5 files now uncovered.

66436 of 100862 relevant lines covered (65.87%)

61.49 hits per line

Uncovered Changes

Lines Coverage ∆ File
1
93.15
0.71% pkg/networking/utilities.go

Coverage Regressions

Lines Coverage ∆ File
4
87.79
-2.33% pkg/transport/proxy/transparent/sse_response_processor.go
3
79.44
-0.76% pkg/transport/proxy/httpsse/http_proxy.go
2
96.46
0.0% pkg/authserver/storage/memory.go
2
93.94
-6.06% pkg/foreach/foreach.go
2
72.73
-1.65% pkg/networking/port.go
Jobs
ID Job ID Ran Files Coverage
1 26950483544.1 04 Jun 2026 12:08PM UTC 747
65.87
GitHub Action Run
Source Files on build 26950483544
  • Tree
  • List 747
  • Changed 7
  • Source Changed 1
  • Coverage Changed 7
Coverage ∆ File Lines Relevant Covered Missed Hits/Line
  • Back to Repo
  • Github Actions Build #26950483544
  • 26912af4 on github
  • Prev Build on main (#26918946871)
  • Next Build on main (#26952689574)
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc