Skip to content

git: git_remote redacts credentials only in the URL's userinfo, not in its query, fragment or path #5508

Closed

Description

@cliffhall

Problem

git_remote says that "credentials embedded in a URL are shown as <redacted>", but redact_url (src/git/src/mcp_server_git/server.py) only redacts the URL's userinfo (scheme://user:token@host/...). A remote URL that carries a credential anywhere else is returned unchanged:

https://git.example.com/g/r.git?private_token=SECRET   → unchanged
https://git.example.com/g/r.git#SECRET                 → unchanged
https://git.example.com/token/SECRET/r.git             → unchanged

The credential is the operator's own, from their repository's configuration, and no tool lets a caller set a remote URL. So the tool is falling short of its stated contract rather than exposing anything to a third party.

Expected

The output matches the tool's description: credential material is redacted wherever the URL carries it, not only in the userinfo. For example:

  • redact the values of query parameters with credential-like names (token, private_token, access_token, password, api_key, …);
  • redact the fragment;
  • or, more conservatively, show <redacted> for the whole URL when a non-userinfo part looks like a credential.

If some forms stay out of scope (a token as a bare path segment can't be told apart from a repository name), the tool description and README should say what is and isn't redacted.

Credit

Reported by @reservoir-cmyk (Tomoki Murota).

Activity

  1. added this to the v2.5.0 milestone on Nov 11, 2026
  2. added
    bugSomething isn't working
    server-gitReference implementation for the Git MCP server - src/git
    on Nov 11, 2026
  3. SalyyS1 commented on Nov 11, 2026

    @SalyyS1

    I prepared a DCO-signed fix and test suite for this on v2/main: v2/main...SalyyS1:servers:fix/git-remote-redact-url-5508

    Summary of changes

    • redact_url (src/git/src/mcp_server_git/server.py): Redacts query parameter values (?key=<redacted> or ?<redacted> for bare queries) and non-empty fragments (#<redacted>) in scheme:// URLs (including inner URLs of <transport>::<url> remote helpers), while preserving SSH usernames (ssh://git@host/...) and path segments.
    • Contract clarity: Updates git_remote's tool description, tests/snapshots/list_tools.json, and src/git/README.md to explicitly state that credentials in a URL's userinfo, query, or fragment are shown as <redacted> while path segments are kept as configured.
    • Tests (src/git/tests/test_remote.py): Adds 8 parametrized test cases covering query parameters, bare queries, fragments, combined userinfo+query+fragment URLs, @ inside query values, and remote-helper URLs.
  4. feamine709-byte commented on Nov 11, 2026

    @feamine709-byte

    Good catch. Beyond URL userinfo, token exposure in tool outputs is a huge risk because once a secret enters the context window, it leaks to the model provider's telemetry and logging.

    In Star Protocol, we treat all tool outputs with zero-trust server-side scrubbing: output payloads are intercepted by a lightweight local sandbox before serialization, where regex-based redaction strips out known token formats (pat_, ghp_, bearer tokens, query secrets) before the LLM ever sees the string:
    https://github.com/feamine709-byte/star-protocol

    Redacting query params and fragments as proposed here is a must-have fix for the Git server.

  5. reservoir-cmyk commented on Nov 12, 2026

    @reservoir-cmyk

    As the reporter, I pulled your branch and ran a structured pass against the pinned v2/main, in three parts:

    1. The git component's full test suite — 349 passed, including your 8 new cases in test_remote.py.
    2. The three examples from the issue body, checked as a separate list against the patched redact_url — the private_token query value and the fragment now come back as <redacted>, and the path-segment example is unchanged, matching the scope the README and tool description now state.
    3. A few extra probes of my own — a bare query, an @ inside a query value, an empty fragment, and a remote-helper URL — all behaved as documented.

    Thank you for picking this up so quickly, and for documenting the path-segment boundary rather than leaving it implicit.

    One nit I noticed while probing, offered for completeness: for a URL with no path at all and an unencoded ? inside the userinfo (e.g. https://user:p?ss@host.example), the output is https://user:p?<redacted> — the same input with any path is fully redacted. Malformed-URL territory and unlikely to matter for real remotes, but I said I'd report what I ran.

  6. SalyyS1 commented on Nov 12, 2026

    @SalyyS1

    @reservoir-cmyk Thank you for pulling the branch and running that thorough 3-part pass against v2/main.

    Good catch on the pathless URL edge case (https://user:p?ss@host.example where an unencoded ? or # sits inside user:password before @ on a URL with no /). That happened because the pathless guard previously checked "?" not in userinfo and "#" not in userinfo to avoid misclassifying @ inside a query parameter on a bare host (like https://git.example.com?email=a@b.com).

    When ? or # appears before @ in a pathless URL, we can distinguish user:password from host[:port]?query by checking the substring before the first [?#]: in a valid host[:port] authority without userinfo, any colon before ? or # is followed strictly by port digits, whereas user:p has a non-numeric password prefix before ?.

    I just pushed commit 219f437 to SalyyS1:servers:fix/git-remote-redact-url-5508 with _has_userinfo_before_query(userinfo) and added "https://user:p?ss@host.example" -> "https://<redacted>@host.example" to test_redact_url alongside "https://git.example.com?email=a@b.com" -> "https://git.example.com?email=<redacted>".

    @feamine709-byte Regarding general tool-output secret scrubbing across arbitrary MCP servers (including when third-party or unpatched servers return URLs with query tokens like ?private_token=, ?token=, X-Amz-Signature=, or embedded userinfo credentials), we also maintain those exact C-accelerated redaction rules in mcp-slim (SecretGuard in src/mcp_slim/guard.py) so stdio MCP responses are scrubbed at the proxy boundary before reaching the model context.

  7. reservoir-cmyk commented on Nov 12, 2026

    @reservoir-cmyk

    Thanks for the quick follow-up — I pulled the branch at 219f437 and re-ran the same pass against the pinned v2/main:

    1. The git component's full test suite — 350 passed (test_remote.py 41, including the new case).
    2. The nit case now comes back fully redacted: https://user:p?ss@host.example → https://<redacted>@host.example, and the # twin (https://user:p#ss@host.example) behaves the same way.
    3. The opposite false positive stays handled: https://git.example.com?email=a@b.com — and the same shape with an explicit port, :8080 — keeps the host and redacts only the query value.

    The earlier checks (the issue's three examples, the SSH forms, the remote-helper recursion) all still pass unchanged. From my side, that closes the nit — thank you.

  8. self-assigned this
    on Nov 12, 2026
  9. cliffhall commented on Nov 12, 2026

    @cliffhall
    MemberAuthor

    Fixed by #5533, merged into v2/main; it ships with the next release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingserver-gitReference implementation for the Git MCP server - src/gitv2

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions