Skip to main content
← All rules

mcp-scan rule

Data in URL

network-egress-data-in-urlhigh

What mcp-scan saw

While scanning each argument and the serialized config, the scanner matched a query parameter whose value is 32 or more characters of base64 alphabet with optional padding, and required the same string to also contain http or wss. The pattern is /[?&]name=<32+ chars>/, so it needs a real query separator, not just a long token.

Why it fires

A URL query string is the least private part of a request: it is logged by proxies, by the origin server's access log, and by anything in between, and it survives in browser and CLI history. Thirty-two characters of opaque base64 in a query parameter is either a credential or a payload, and both belong in a POST body.

When this is a false positive

  • A signed URL is exactly this shape. Presigned S3 links, Cloudflare signed URLs, and CDN tokens all carry a long opaque value in a query parameter by design.
  • An API that takes its key as a query parameter, which several public APIs still do. The finding is correct about the mechanism and wrong about it being your bug to fix in this config.
  • A JWT passed as ?token=eyJ... matches on shape. It is a legitimate pattern for some SSE endpoints, though it is still logged everywhere the URL is.

How to fix it

  1. Read the matched fragment in the finding text. It quotes the parameter name and the start of the value, which usually identifies what it is.
  2. If the value is a credential you control, move it to an Authorization header and pass it through env instead of the URL.
  3. If it is a presigned URL, confirm the expiry is short and that the URL is not written to a log or a committed config. Then treat this as a known accepted case.
  4. If the destination is your own service, add a POST route that takes the payload in the body and change the argument to point at it.
  5. To suppress, add 'network-egress-data-in-url' to suppressRules in .mcp-scan.json.