MCP Server Security · Referrer Policy

MCP server Referrer-Policy security — preventing URL parameter leakage in outbound tool requests, strict-origin vs no-referrer trade-offs

When an MCP tool handler makes an outbound HTTP request, the browser or Node.js HTTP client attaches a Referer header containing the URL of the page that triggered the request. If that URL contains session tokens in query parameters (?token=abc123), user identifiers in the path (/users/42/sessions), or internal routing state, these values are sent in plaintext to the third-party server your tool called. The Referrer-Policy header (and the referrerPolicy fetch option) controls what gets sent — and the browser default sends more than most developers realize.

What the browser default policy actually sends

The browser default Referrer-Policy is strict-origin-when-cross-origin. This means:

The cross-origin case looks safe, but the same-origin case leaks the full URL — including any query parameters — to every same-origin subresource. For a browser-based MCP client UI where the client URL is https://app.example.com/sessions/42?auth=token123, every same-origin API request in a tool handler sends Referer: https://app.example.com/sessions/42?auth=token123 to the server.

Server-side MCP tool handlers are different. In a Node.js MCP server, fetch() uses the Node.js undici client, not a browser. By default, undici does not send a Referer header unless you explicitly set one. The leakage risk here is not Referer from Node.js — it's the Origin and Referer headers that a browser-based MCP client UI sends when making cross-origin fetch calls to external APIs through the user's browser.

Referrer-Policy values: reference table

PolicySame-origin requestCross-origin (HTTPS→HTTPS)Cross-origin (HTTPS→HTTP)
no-referrerNothingNothingNothing
no-referrer-when-downgradeFull URLFull URLNothing
originOrigin onlyOrigin onlyOrigin only
origin-when-cross-originFull URLOrigin onlyOrigin only
same-originFull URLNothingNothing
strict-originOrigin onlyOrigin onlyNothing
strict-origin-when-cross-originFull URLOrigin onlyNothing
unsafe-urlFull URLFull URLFull URL

Choosing the right policy for MCP server admin UIs

For MCP server admin UIs that load analytics, CDN assets, or call third-party APIs directly from the browser, use strict-origin as the page-level default:

<!-- In the <head> of every admin UI page -->
<meta name="referrer" content="strict-origin">

<!-- Or set via HTTP header for stronger coverage (headers take precedence) -->
# Caddy
header Referrer-Policy "strict-origin"

strict-origin sends only the origin for all requests (same-origin and cross-origin), and sends nothing on HTTPS→HTTP downgrades. The full URL — with any tokens in path segments or query parameters — never leaves your origin in the Referer header.

Per-request override in fetch() and img tags

For MCP tool handlers that make fetch requests from a browser-based client, override the policy per-request to be maximally restrictive:

// Browser-side MCP tool handler making outbound request
const result = await fetch('https://api.external-service.com/data', {
  method: 'GET',
  referrerPolicy: 'no-referrer',  // suppress Referer entirely for this request
  credentials: 'omit',           // don't send cookies to third-party
});

// For image resources loaded by tool output rendering
const img = document.createElement('img');
img.referrerPolicy = 'no-referrer';  // don't reveal current URL to image origin
img.src = toolOutput.imageUrl;
document.body.appendChild(img);

When to use no-referrer vs strict-origin

Don't put secrets in URL parameters. Referrer-Policy is damage control, not the primary fix. Session tokens, API keys, and authentication credentials should not appear in URL paths or query parameters. Use Authorization headers or POST body instead. Referrer-Policy prevents leakage of accidentally-present parameters but doesn't eliminate the root cause.

Server-side MCP tool handlers: Referer header injection risks

When a Node.js MCP server tool handler makes a fetch to an external API, Node's undici does not automatically send a Referer header. The risk runs in the opposite direction: an attacker who can control tool arguments might inject a Referer header to spoof the server's identity to the external API. Prevent this by stripping any user-supplied headers that include Referer before forwarding:

const BLOCKED_HEADERS = new Set(['referer', 'referrer', 'origin', 'cookie', 'authorization']);

function sanitizeUserHeaders(headers) {
  const safe = {};
  for (const [key, value] of Object.entries(headers ?? {})) {
    if (!BLOCKED_HEADERS.has(key.toLowerCase())) {
      safe[key] = value;
    }
  }
  return safe;
}

server.tool('fetchWithHeaders', { url: z.string(), headers: z.record(z.string()).optional() }, async ({ url, headers }) => {
  await safeResolveUrl(url); // SSRF check
  const response = await safeFetch(url, {
    headers: sanitizeUserHeaders(headers), // strip Referer, Origin, Cookie
  });
  return { content: [{ type: 'text', text: await response.text() }] };
});

SkillAudit findings

CRITICAL −20unsafe-url Referrer-Policy — full URL including query parameters sent to every cross-origin endpoint, including HTTP destinations; session tokens in URL parameters leak to external servers
HIGH −16No Referrer-Policy header on admin UI — browser default (strict-origin-when-cross-origin) sends full URL for same-origin requests; analytics scripts and same-origin API calls receive session tokens in path/query
HIGH −14Session token or API key present in URL query parameter (?token=, ?api_key=) — leaked to any resource loaded on that page regardless of Referrer-Policy policy (server logs, CDN access logs, analytics)
MEDIUM −10Tool handler forwards user-supplied Referer or Origin headers to external APIs — allows attacker to spoof the referring origin for external service authentication
MEDIUM −8no-referrer-when-downgrade policy on admin UI — sends full URL to all same-origin and cross-origin HTTPS destinations; tokens in URL parameters leak to analytics and API backends

See also: Content Security Policy · CORS preflight security · SSRF advanced patterns

Audit your MCP server for Referrer-Policy gaps

SkillAudit checks for missing or permissive Referrer-Policy headers, tokens in URL parameters, and user-controlled Referer header forwarding.

Run free audit →