Fix guide · high · auth_token_in_url

Auth token passed in URL query string

What this rule means

An auth-shaped query parameter (access_token=, session_id=, jwt=, etc.) was found in the bundle. Tokens in URLs leak through server logs, browser history, Referer headers, and analytics — every system in the request path gets a copy.

Why it matters

Authentication credentials passed in URL parameters end up in places you don't expect:

Auth tokens belong in HTTP headers (typically Authorization: Bearer <token>) or in HttpOnly cookies that the browser attaches automatically. Both keep the token out of the URL bar, out of logs, out of analytics, and out of Referer headers.

Real-world precedent: tokens-in-URL has been the root cause of multiple major credential leaks where third-party analytics inadvertently logged auth tokens — this happened to multiple Y Combinator startups in 2022 alone.

How to fix it

1. Move the token to a header.

fetch('/api/me', {
  headers: { 'Authorization': 'Bearer ' + token }
});

2. Or use an HttpOnly cookie if the API is same-origin. The browser attaches the cookie automatically and it's invisible to JavaScript (so XSS can't steal it):

Set-Cookie: session=abc; HttpOnly; Secure; SameSite=Lax; Path=/

3. Audit the URLs that already shipped. Search your codebase for the param name (e.g. access_token=, auth_token=, session=). If any of those URLs were ever loaded in production, treat the corresponding tokens as leaked — rotate sessions, invalidate JWTs, force users to re-authenticate.

4. Set up rotation. If the leak surface is a long-lived bearer token, switch to short-lived access tokens + refresh tokens. Even if a single access token leaks, it's only valid for an hour.

5. Reset Referer policy to be strict to limit cross-origin leak: <meta name="referrer" content="strict-origin-when-cross-origin">. This stops the URL from being sent in Referer when the user clicks an external link.

Did vibecheck flag this on your app?

If you reached this page from a vibecheck inspection report, the redacted match in your scan output is the exact string we found in your bundle. After applying the fix above, run the inspection again — the finding should clear.

Run another inspection