OAuth 2.0
debt(d7/e5/b5/t7)
Closest to 'only careful code review or runtime testing' (d7). The detection_hints indicate semgrep can catch specific patterns (missing state parameter, exposed client_secret in JS), but the tool notes automated=no, meaning a human must craft and maintain the rules. Many OAuth2 misconfigurations — like accepting tokens from wrong audiences or not restricting redirect_uri — require manual code review or integration testing to surface; they won't appear as obvious compiler or default linter errors.
Closest to 'touches multiple files / significant refactor in one component' (e5). The quick_fix says to use an established library (league/oauth2-client) and implement state, PKCE, and secret handling correctly. Migrating from a bespoke or flawed OAuth2 implementation to a library-based one typically touches the auth callback controller, session handling, configuration/environment files, and possibly frontend code — more than a one-liner but contained to the auth component rather than being fully cross-cutting.
Closest to 'persistent productivity tax' (b5). OAuth2 flows apply to web and API contexts (applies_to includes both), and auth decisions shape session management, API gateway configuration, and how third-party integrations are structured. However, the burden is not quite architectural (b7/b9) because a well-chosen library can encapsulate most of the complexity, leaving the rest of the codebase relatively unaffected beyond the auth layer.
Closest to 'serious trap — contradicts how a similar concept works elsewhere' (t7). The canonical misconception is that OAuth 2.0 is an authentication protocol when it is actually an authorisation framework — a fundamental confusion that leads developers to skip OpenID Connect entirely and derive identity from access tokens insecurely. Combined with the common_mistakes (missing state, open redirect_uri, Implicit flow), these are well-documented but frequently repeated traps that cause account takeover vulnerabilities, scoring close to t7.
Also Known As
TL;DR
Explanation
OAuth 2.0 defines several grant types for different use cases. The Authorization Code flow (with PKCE for public clients) is the most secure: the user authenticates with the identity provider, receives a short-lived code, and the client exchanges it for tokens. The Implicit flow is deprecated. Client Credentials is used for machine-to-machine. OAuth 2.0 handles authorisation only; OpenID Connect adds identity (authentication) on top.
Diagram
sequenceDiagram
participant U as User
participant C as Client App
participant A as Auth Server
participant R as Resource Server
U->>C: Click Login with Google
C->>A: Redirect + client_id + state + scope
A->>U: Show login and consent screen
U->>A: Approve
A->>C: Redirect with code + state
C->>A: POST code + client_secret
A->>C: access_token + id_token
C->>R: GET /userinfo Bearer token
R->>C: User profile data
Common Misconception
Why It Matters
Common Mistakes
- Not validating the state parameter — enables CSRF against the OAuth callback.
- Not restricting redirect_uri — any URI can receive the authorisation code.
- Using Implicit flow — the access token is exposed in the browser URL and history.
- Not validating the id_token audience (aud) claim when using OIDC — tokens issued to other clients are accepted.
Code Examples
// Missing state validation — CSRF on OAuth callback:
$code = $_GET['code'];
// state parameter not checked — attacker can forge the callback
$tokens = exchangeCode($code);
loginUser($tokens);
// State validation prevents CSRF:
$state = $_GET['state'] ?? '';
if (!hash_equals($_SESSION['oauth_state'], $state)) {
throw new SecurityException('Invalid state — possible CSRF');
}
unset($_SESSION['oauth_state']);
$tokens = exchangeCode($_GET['code']);