[security] fix(mcp): harden signed upload URL authority#2319
Open
Hinotoi-agent wants to merge 1 commit into
Open
[security] fix(mcp): harden signed upload URL authority#2319Hinotoi-agent wants to merge 1 commit into
Hinotoi-agent wants to merge 1 commit into
Conversation
PR Reviewer Guide 🔍Here are some key observations to aid the review process:
|
PR Code Suggestions ✨No code suggestions found for the PR. |
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
This PR hardens the MCP signed-upload URL authority boundary so upload instructions are not derived from attacker-controlled request authority headers.
X-Forwarded-Host/X-Forwarded-Protofrom controlling the returned signed upload URL unless an operator explicitly configures a trusted public base URL.Hostauthorities such aslocalhost:1933,127.0.0.1:1933, and[::1]:1933.public_base_urlprecedence, and authority-confusion inputs such aslocalhost:1933@attacker.example.Security issues covered
Before this PR
_resolve_public_base_url()could derive signed upload URLs from request headers.X-Forwarded-Host/X-Forwarded-Protowere trusted as URL authority inputs even though they can be supplied by clients unless sanitized by a trusted proxy.Hostfallback was needed for localhost clients, but it needed a strict authority parser before interpolation intohttp://{host}.After this PR
OPENVIKING_PUBLIC_BASE_URL/server.public_base_urlremains the authoritative way to publish a non-local MCP upload origin.X-Forwarded-Host/X-Forwarded-Protono longer control signed upload URLs by default.Hostis accepted only for loopback/local authorities with safe syntax.Explicit operator choice
OPENVIKING_PUBLIC_BASE_URLorserver.public_base_urlto the externally reachable base URL.Hostvalues remain supported so local MCP clients can receive usable upload URLs without extra configuration.Why this matters
MCP
add_resource()can return upload instructions containing a signed temporary upload URL. If that URL authority is chosen from untrusted request headers, an attacker who can influence those headers in a proxied or exposed deployment can cause clients to receive attacker-origin upload URLs. That can leak signed upload tokens and divert client uploads away from the intended OpenViking server.How this differs from related issue/PR
public_base_urlandupload_signed_ttl_seconds(#1847) #2153 documentedpublic_base_url/ upload TTL behavior; this PR enforces that public origins come from explicit operator configuration rather than request-supplied forwarding headers.public_base_url,X-Forwarded-Host, andHost poisoningdid not find an existing open PR fixing this request-authority trust boundary.Attack flow
Affected code
openviking/server/mcp_endpoint.py,tests/server/test_mcp_endpoint.py,tests/unit/test_mcp_public_base_url_trust.pyRoot cause
MCP signed upload URL authority poisoning:
CVSS assessment
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:H/I:H/A:NRationale:
Safe reproduction steps
1. Forwarded authority poisoning
OPENVIKING_PUBLIC_BASE_URL/server.public_base_url.X-Forwarded-Hostsuch asattacker.example.2. Raw Host authority confusion
Hostvalue such aslocalhost:1933@attacker.exampleorlocalhost/path.http://{host}.Expected vulnerable behavior
Changes in this PR
X-Forwarded-Host/X-Forwarded-Protofor signed upload URL authority generation.Hostfallback.Files changed
openviking/server/mcp_endpoint.pytests/server/test_mcp_endpoint.pytests/unit/test_mcp_public_base_url_trust.pyMaintainer impact
Fix rationale
Hostvalues.Type of change
Test plan
ragfs_pythonbinding is unavailable.Executed with:
PYTHONPATH=. /Users/$USER/.hermes/hermes-agent/venv/bin/python -m pytest -o addopts='' tests/unit/test_mcp_public_base_url_trust.py -q/Users/$USER/.hermes/hermes-agent/venv/bin/python -m ruff check openviking/server/mcp_endpoint.py tests/server/test_mcp_endpoint.py tests/unit/test_mcp_public_base_url_trust.pyLocal result:
tests/unit/test_mcp_public_base_url_trust.py:5 passedruff check:All checks passed!Not run successfully:
tests/server/test_mcp_endpoint.pycould not run locally because importing the server fixture path failed withImportError: ragfs_python native library is not available: Rust binding not available.Disclosure notes