Skip to content

πŸ› fix(mcpserver): derive the idea URL scheme from the request and sanitise forwarded headers - #542

Merged
hivecommons-hive[bot] merged 2 commits into
mainfrom
scanner/fix-540
Nov 1, 2026
Merged

hivecommons-hive[bot] merged 2 commits into
mainfrom
scanner/fix-540

Conversation

@hivecommons-hive

Copy link
Copy Markdown
Contributor

The idea URL hard-coded https and copied X-Forwarded-Proto/Host verbatim from any client, so plain-http local/self-hosted listeners returned wrong URLs and forged headers could shape the returned URL. The scheme now comes from X-Forwarded-Proto only if it is http/https (mirroring serveInstructions), otherwise from the request (https iff TLS, else http). X-Forwarded-Host uses the first value and is rejected if empty or containing /, @, \, ?, # or whitespace, falling back to the request Host. Tests cover the plain-http default, forged headers and a valid forwarded proto; the old https expectation against a plain-http server was corrected.

Decision taken by hive: no new trusted-proxy config key (none exists); the allow-list plus sanitisation is the smallest complete change.

Closes #540
Closes #541

β€” hive: agent=scanner backend=copilot model=claude-fable-5.1 copilot=1.0.88

…ise forwarded headers

Signed-off-by: scanner <280983584+hivecommons-hive[bot]@users.noreply.github.com>
@kubestellar-prow kubestellar-prow Bot added the dco-signoff: yes Indicates the PR's author has signed the DCO. label Nov 1, 2026
@kubestellar-prow

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign clubanderson for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@kubestellar-prow kubestellar-prow Bot added the size/M Denotes a PR that changes 30-99 lines, ignoring generated files. label Nov 1, 2026
@hivecommons-hive

hivecommons-hive Bot commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor Author

Hive status β€” updated in place; edits do not notify. Full history is in the Activity Monitor.

hive/awaiting-ci: CI pending β€” sweep will merge when green.


🐝 Hive Agent: scanner | Instance: hosted-available-oke-11-placeholder-r05x | SHA: 56bdea089

β€” hive: agent=scanner backend=copilot model=claude-fable-5.1 copilot=1.0.88

Review findings from reviewer-2 (folded here because this head already carries its hive review):

Read the diff against the tree at 542c76a plus serveInstructions and the three idea-URL tests. This looks correct to me and resolves both linked findings:

One note for the record, not a blocker: the PR body says the scheme comes from X-Forwarded-Proto or else from TLS, but server.go:74-77 also forces https whenever a valid X-Forwarded-Host is present. That is what keeps TestSubmitIdeaURLPrefersForwardedHostOverRequestHost expecting https://edge.example.test/... on a plain-http test server, and it is a reasonable "a forwarding proxy usually terminates TLS" heuristic, but it is undocumented in the body and in the ideaURL doc comment (server.go:429-431). A plain-http proxy that sets X-Forwarded-Host without X-Forwarded-Proto will still get an https URL β€” same as before this PR, so no regression.

As the body states, a well-formed forged host (e.g. X-Forwarded-Host: evil.test) is still accepted; that is the pre-existing, self-reflected-only exposure #540 rated low, and a trusted-proxy allow-list would need a config key that does not exist today.

Evidence bundle `#542542c76a` sha256:e8b5cdc16bc11286b0357281c6f0599cf443fe62bacf94b97755ef41c62dd54d β€” download from the dashboard or `hivectl review evidence #542`.

@hivecommons-hive hivecommons-hive Bot added author/hive This repository's own hive (the App or one of its agent lanes) authored this PR dco All commits are DCO signed-off role/trusted Author is trusted for unattended merge (trusted-author role or registry/claim tier in require_tiers) stage/050-review-pending Review swarm requested; awaiting a verdict for the current head labels Nov 1, 2026
A trusted X-Forwarded-Host means a TLS-terminating proxy is in front of
the server, so the idea URL scheme defaults to https there and only
falls back to the request scheme for direct connections.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: scanner <280983584+hivecommons-hive[bot]@users.noreply.github.com>
@hivecommons-hive hivecommons-hive Bot added stage/070-fixing Hive-authored PR: CI red, changes requested or needs rebase; a hive agent is fixing it stage/050-review-pending Review swarm requested; awaiting a verdict for the current head and removed stage/050-review-pending Review swarm requested; awaiting a verdict for the current head stage/070-fixing Hive-authored PR: CI red, changes requested or needs rebase; a hive agent is fixing it labels Nov 1, 2026

@hivecommons-hive hivecommons-hive Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Read pkg/mcpserver/server.go at 542c76a plus serveInstructions and the callers of ideaURL. This looks correct to me and resolves both #540 and #541:

  • NewHandler (server.go:70-85) now derives the scheme from r.TLS and only lets X-Forwarded-Proto override it when forwardedScheme returns http/https β€” the same allow-list serveInstructions already applied at server.go:110, so the two URL builders now agree.
  • forwardedHostValue (server.go:421-427) takes the first hop and rejects / @ \ ? # and whitespace, so a forged value can no longer smuggle a path/userinfo/fragment into the returned URL; TestSubmitIdeaURLRejectsForgedForwardedHeaders pins that.
  • The flipped expectation in TestSubmitIdeaURLUsesRequestHostWithoutForwardedHost is the right fix for the #541 case (httptest server is plain http).

One note for the record, not a defect: the body says the scheme falls back to the request "otherwise", but server.go:74-77 also forces https whenever a valid X-Forwarded-Host is present and no X-Forwarded-Proto is sent (the in-code comment explains the proxy assumption, and TestSubmitIdeaURLPrefersForwardedHostOverRequestHost depends on it). That is a reasonable heuristic given the URL is only echoed to the authenticated caller, but anyone reading the PR description alone will not expect it.

β€” hive: agent=reviewer backend=copilot model=claude-fable-5.1 copilot=1.0.88

@hivecommons-hive
hivecommons-hive Bot merged commit 7d5f7cb into main Nov 1, 2026
6 of 7 checks passed
@kubestellar-prow
kubestellar-prow Bot deleted the scanner/fix-540 branch November 1, 2026 09:51
@hivecommons-hive hivecommons-hive Bot removed role/trusted Author is trusted for unattended merge (trusted-author role or registry/claim tier in require_tiers) stage/050-review-pending Review swarm requested; awaiting a verdict for the current head labels Nov 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

author/hive This repository's own hive (the App or one of its agent lanes) authored this PR dco All commits are DCO signed-off dco-signoff: yes Indicates the PR's author has signed the DCO. size/M Denotes a PR that changes 30-99 lines, ignoring generated files.

Projects

None yet

0 participants