Skip to content

OAuth introspection & revocation endpoints are unauthenticated (RFC 7662 §2.1 / RFC 7009) #201

@saucam

Description

@saucam

Problem

/oauth2/token/introspect and /oauth2/token/revoke accept any caller. They are registered in registerOAuthRoutes (internal/handler/oauth.go:156-171) with no Security and no auth middleware, and the handlers derive the tenant from the submitted token itself rather than from an authenticated caller identity:

  • introspectOpinternal/handler/oauth.go:328-334
  • revokeOpinternal/handler/oauth.go:337-340

RFC 7662 §2.1: "To prevent token scanning attacks, the endpoint MUST also require some form of authorization to access this endpoint." An open introspection endpoint lets anyone probe token validity and metadata (active status, scopes, cnf, expiry) by submitting tokens — a token-scanning / validity-oracle surface.

For revocation, RFC 7009 §2.1 requires client authentication; an unauthenticated /revoke lets anyone who can present a token force its revocation. Because revoke always returns 200 per RFC 7009 §2.2, it's also a blind operation with no caller accountability.

Impact

  • Introspection: token-scanning / validity oracle for anyone who obtains or guesses a token.
  • Revocation: anyone holding a token can force-revoke it — an availability/DoS surface against agent credentials.
  • No caller-identity audit trail on either endpoint; the tenant comes from the token, not the requester.

Proposed change

Require caller authentication on both endpoints (RFC 7662 §2.1 / RFC 7009 §2.1):

  • Confidential clients authenticate (client_secret / private_key_jwt, or the internal-service secret), consistent with how the rest of the platform authenticates service callers.
  • Public clients: per RFC 7662, still require some authorization — decide the policy (e.g. restrict introspection to the internal mesh, or require a client credential alongside the token).
  • Keep the RFC 7009 §2.2 "always 200" response for revoke, but gate access first.
  • Derive/verify the tenant from the authenticated caller and cross-check it against the token's tenant, rather than trusting the token alone.

References

  • RFC 7662 §2.1 — introspection endpoint MUST require authorization (token-scanning defense)
  • RFC 7009 §2.1 — revocation client authentication
  • Code: internal/handler/oauth.go:156-171 (registration), :328-340 (handlers)
  • Reported by Andrii Deinega via WIMSE WG review of ZeroID. Related: Validate DPoP proofs in /oauth2/token/verify forward-auth endpoint #193 (DPoP validation on the sibling /oauth2/token/verify forward-auth endpoint).

Metadata

Metadata

Assignees

No one assigned

    Labels

    securitySecurity issuespec-complianceDeviation from SPIFFE/WIMSE/JWT-SVID specs

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions