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

stacklok / toolhive / 28402376273
68%

Build:
DEFAULT BRANCH: main
Ran 29 Jun 2026 09:06PM UTC
Jobs 1
Files 773
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

29 Jun 2026 09:00PM UTC coverage: 67.497% (+0.1%) from 67.384%
28402376273

push

github

web-flow
Add Origin header validation for DNS-rebind protection (#4908)

Add Origin header validation middleware

ToolHive's proxy layer had no Origin-header validation, and the legacy
HTTP+SSE transport sent `Access-Control-Allow-Origin: *`, leaving both
modes open to DNS-rebinding attacks from browser clients. MCP 2025-11-25
§"Security Warning" requires servers to validate Origin on all
connections and respond 403 when the value is invalid.

This change introduces a dedicated middleware at
pkg/transport/middleware/origin/ that rejects requests whose Origin
header is present and not in an operator-configured allowlist. It is
wired centrally in runner.Run for both the factory-based chain
(thv run / thv-proxyrunner) and inline in the `thv proxy` chain.

Wiring is done in runner.Run rather than in the builder because that is
the only point where the effective Host/Port/AllowedOrigins are fully
resolved: the CLI builder (WithMiddlewareFromFlags) defers port
resolution to validateConfig, so an earlier hook would see port 0 and
silently disable loopback-default protection for `thv run`. The
middleware is prepended so Origin validation runs first in the chain.

Behavior:
- New --allowed-origins flag on `thv run` and `thv proxy` accepts a
  repeatable exact-match list. When empty and the bind host is
  loopback, a default loopback-only allowlist is derived automatically
  (http://localhost:PORT + 127.0.0.1 + [::1]). When empty and the
  bind is non-loopback, the middleware is skipped and a warning is
  logged — the bind-opt-in hardening lands in a follow-up.
- Matching parses each value with net/url and compares scheme://host
  [:port] with scheme and host lowercased per RFC 6454 §4. Values
  carrying userinfo (RFC 6454 §6) or that fail to parse never match,
  closing an Origin-smuggling vector. Requests with multiple Origin
  headers are rejected outright.
- 403 responses carry a JSON-RPC error body (id: null, code -32600,
  message "Origin not allowed").
- `Access-... (continued)

161 of 192 new or added lines in 7 files covered. (83.85%)

3 existing lines in 2 files now uncovered.

70752 of 104823 relevant lines covered (67.5%)

64.36 hits per line

Uncovered Changes

Lines Coverage ∆ File
15
9.69
0.68% cmd/thv/app/proxy.go
5
79.56
-0.48% pkg/runner/config_builder.go
5
96.09
pkg/transport/middleware/origin/origin.go
3
83.88
0.5% pkg/runner/middleware.go
2
36.95
0.08% pkg/runner/runner.go
1
31.87
0.31% cmd/thv/app/run_flags.go

Coverage Regressions

Lines Coverage ∆ File
2
93.94
-6.06% pkg/foreach/foreach.go
1
83.88
0.5% pkg/runner/middleware.go
Jobs
ID Job ID Ran Files Coverage
1 28402376273.1 29 Jun 2026 09:06PM UTC 773
67.5
GitHub Action Run
Source Files on build 28402376273
  • Tree
  • List 773
  • Changed 13
  • Source Changed 8
  • Coverage Changed 13
Coverage ∆ File Lines Relevant Covered Missed Hits/Line
  • Back to Repo
  • Github Actions Build #28402376273
  • 87b4f101 on github
  • Prev Build on main (#28401542217)
  • Next Build on main (#28407311417)
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