Configuration & Environment
Frontend stores an MCP session or auth token in `localStorage` / `sessionStorage` — any XSS gives an attacker permanent token theft.
`localStorage` is readable by any JavaScript executing on the page. A single XSS — even a transient one — exfiltrates everything in storage to the attacker. The defense is to keep auth tokens in HttpOnly cookies (which JS cannot read) or in memory only (cleared on reload).
MCP servers often ship with their own admin UIs or web dashboards that use a JWT for auth. Putting that JWT in `localStorage` is the path of least resistance for SPA development, but it's the most common vector by which an MCP server's admin gets popped via an unrelated XSS in a dependency.
async function login(creds) { |
const res = await fetch("/api/login", { method: "POST", body: JSON.stringify(creds) }); |
const { token } = await res.json(); |
localStorage.setItem("auth_token", token); |
} |
// Server sets HttpOnly cookie; JS never sees the token. |
async function login(creds) { |
const res = await fetch("/api/login", { |
method: "POST", |
body: JSON.stringify(creds), |
credentials: "include", |
}); |
if (!res.ok) throw new Error("login failed"); |
// No client-side token storage. |
} |
MCPSafe flags `localStorage.setItem(...)` / `sessionStorage.setItem(...)` calls where the key contains `token`, `jwt`, `auth`, `session`, or `bearer` (case-insensitive). Server-side cookie sets are not flagged.
See the full threat catalog for every documented detection.
MCPSafe runs this check — and every other rule in the catalog — on any MCP server you paste in.
Scan now