Skip to content

Reject Authorization headers on routes that do not expect them #214

Description

@kilodesodiq-arch

Problem Statement. roles.guard.ts short-circuits when no @Roles() decorator is
present and returns true. A misconfigured hero route that silently accepts an
Authorization: Bearer header but only validates against x-api-key could let an attacker
bypass the role check by presenting a token nobody considered.

Why it matters. Defence-in-depth. A "no decorator => open" rule plus a header
introspection catch-all is a common authorisation-bypass primitive.

Technical Context. app/backend/src/auth/roles.guard.ts:

if (!requiredRoles) {
  return true; // No role required — open to any authenticated caller
}

Expected Outcome. A complementary UnexpectedAuthHeaderGuard (or a property on
RolesGuard) that fails (HTTP 401) when an undecorated handler receives any
authorisation credential. Operators opt-in by adding @NoAuthStrict() on handlers
explicitly designed for public anonymous access.

Acceptance Criteria.

  • New e2e test asserts: a route with no decorator and a Bearer header returns 401, not
    200.
  • Routes intentionally public (/health, /api/docs, /ai/metrics) opt out by an env
    list PUBLIC_AUTH_BYPASS=/health,/api/docs,/ai/metrics.
  • CI lint catches new undecorated routes: a nestjs-route-doctor runs in CI and reports.

Implementation Notes. The safest approach is to make the absence of credentials the
default state and require an explicit allowlist rather than the inverse.

Files or modules likely to be affected. src/auth/roles.guard.ts,
new src/common/guards/unexpected-auth-header.guard.ts,
app/backend/test/security.e2e-spec.ts.

Dependencies. None.

Difficulty. Medium
Estimated effort. S



Backlog item #6 from `docs/maintainer-issue-backlog.md.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions