Configuration & Environment
MCP server generates session IDs from `random.*`, `Math.random`, `time.time`, `uuid.uuid1`, or counter increments — predictable IDs let an attacker enumerate or guess valid sessions. Sibling of MCP-082 (general weak-RNG-for-security) scoped specifically to session-identifier names; the two rules partition cleanly and do not double-fire.
Session IDs are bearer tokens — knowing one is sufficient to impersonate the session owner. They MUST be drawn from a CSPRNG (cryptographically secure RNG): `secrets.token_urlsafe`, `crypto.randomBytes`, `crypto.randomUUID`, or `uuid.uuid4`. Anything else is predictable to an attacker who can observe the rate of new sessions.
MCP-082 covers weak randomness in general (`token`, `secret`, `password` identifiers) but excludes `session_id`. MCP-267 fills that gap. Session predictability is the most common oversight after token passthrough.
import random |
from fastmcp import FastMCP |
mcp = FastMCP("my-mcp") |
@mcp.tool() |
def new_session() -> str: |
session_id = str(random.randint(1, 10**9)) |
return session_id |
import secrets |
from fastmcp import FastMCP |
mcp = FastMCP("my-mcp") |
@mcp.tool() |
def new_session() -> str: |
session_id = secrets.token_urlsafe(32) |
return session_id |
Per-occurrence in MCP-server-context files. Fires when `session_id` / `sess_id` / `sid` / `session_token` (+ camelCase TS `sessionId`/`sessionToken`) is generated from `random.*` (randint/randrange/choice/getrandbits/sample/uniform), `time.time`, `uuid.uuid1` (leaks MAC + time), JS `Math.random`, `Date.now`, `new Date().getTime()`, or counter increment (`var=counter+1`, `var=++counter`).
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