Skip to main content

Security Considerations

This page summarizes the security settings and behaviors you should verify for every OAuth integration. It covers recommended configuration per client type, redirect URI validation, token storage, mix-up attack prevention, and CSRF protection via the state parameter.

SettingPublic clients (SPA / mobile)Confidential clients (server)
Grant typeauthorization_codeauthorization_code, client_credentials
PKCE✅ Required (S256)✅ Recommended
state✅ Required✅ Required
nonce✅ Required for OIDC✅ Required for OIDC
Client authnoneclient_secret_basic or private_key_jwt
Token bindingDPoP recommendedDPoP recommended
PARRecommendedRequired for FAPI

PKCE is defined by RFC 7636 — Proof Key for Code Exchange: the client generates a random secret (the code verifier) and sends a hash of it when starting the authorization flow, then the real secret when exchanging the code. DPoP is defined by RFC 9449 — Demonstrating Proof-of-Possession: binds an access token to a client-held key so that a stolen token alone is useless from another host. PAR is defined by RFC 9126 — Pushed Authorization Requests: the client POSTs the authorization parameters to a back-channel endpoint first, receiving a request_uri that it then uses in the front-channel redirect.

Redirect URI Validation

LumoAuth performs exact-match validation on redirect_uri:

  • Wildcards are not permitted.
  • For mobile apps, use custom URI schemes (e.g., com.example.app:/callback) or claimed HTTPS redirect URIs (RFC 8252 — OAuth 2.0 for Native Apps).
  • localhost URIs are allowed for development clients only.

Token Storage

TokenRecommended storage
Access token (SPA)In-memory only
Refresh token (SPA)Avoid; use silent auth or offline_access with a BFF pattern
Access token (mobile)Secure enclave / Keychain
Refresh token (mobile)Secure enclave / Keychain
Access token (server)In-memory / short-lived cache
Refresh token (server)Encrypted database
danger

Never store tokens in localStorage or in cookies without HttpOnly + SameSite=Strict flags.

Mix-Up Attack Prevention

LumoAuth includes the iss claim in authorization responses (RFC 9207). Always verify that iss matches your expected authorization server before using the authorization code. This prevents an attacker from tricking your client into exchanging a code with a different authorization server.

CSRF Protection

Always include and verify the state parameter. The state value must:

  1. Be cryptographically random (≥ 128 bits of entropy).
  2. Be bound to the user's session on your side.
  3. Be verified before processing the authorization response.