Skip to content

exposeDevLinks is fail-open: make the __test/* gate an allowlist, not a denylist #223

Description

@unforced

Surfaced by the auth-and-scope specialist during the #218 review. Pre-existing, not introduced by #218, and currently defended — filing because the failure mode is silent and the fix is one line.

workers/identity/src/oauth-shared.ts:219

exposeDevLinks: env.ENVIRONMENT !== "production",

This is a denylist: everything that is not the exact string production gets dev links and __test/* routes. So it fails open — if ENVIRONMENT is unset, misspelled, capitalized differently, or carries trailing whitespace, production silently exposes __test/* and the magic-link echo header.

Today it is safe: workers/identity/wrangler.toml:268 sets ENVIRONMENT = "production" at the top level (which is prod), and smoke-prod.ts independently pins __test/* to 404. Two layers, both working.

The concern is the direction of failure, not the current state. The entire production posture rests on one string literal in a config file matching exactly. A typo (Production, production ) does not fail loudly — it quietly flips a security gate open, and the only thing that would catch it is the prod smoke's 404 pin running and being read.

Fix — invert to an allowlist so the gate fails closed:

exposeDevLinks: env.ENVIRONMENT === "staging" || env.ENVIRONMENT === "development",

Then an unset or misspelled ENVIRONMENT yields a locked worker rather than an open one. A staging box that mistakenly locks itself is a visible, harmless annoyance; a production box that mistakenly opens itself is not.

Worth grepping for sibling !== "production" checks and inverting them as a set — the echo header and mock-billing flags are described in the same wrangler.toml comments and likely share the shape.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions