Back to scan results
What this check probes
We GET /.well-known/openid-configuration and parse the JSON. If it's not present, the check is skipped (most sites are not identity providers). When found, we look at:
id_token_signing_alg_values_supported — the list of JWT algorithms the IdP accepts. "none" is a critical fail (lets anyone forge tokens). "HS256" alone is suspicious (symmetric key shared with all clients). Modern best practice: RS256, ES256, or EdDSA only.
code_challenge_methods_supported — must include "S256" for PKCE support. Without PKCE, public clients (mobile apps, SPAs) are vulnerable to authorization-code interception.
token_endpoint_auth_methods_supported — should include "client_secret_post" or "client_secret_basic". Avoid "none" for confidential clients.
response_types_supported — implicit flow ("token", "id_token token") is deprecated by OAuth 2.1; should be removed in favor of authorization code + PKCE.
- JWKS reachability — the
jwks_uri should be HTTPS and respond with valid JSON.
Why this matters for PCI DSS
The classic "alg: none" attack: an attacker takes a legitimate JWT, changes the algorithm header to "none", removes the signature, and substitutes their own claims. A library that honors the header value impersonates any user. CVE-2018-1000531, CVE-2015-9235, and many more.
Without PKCE, a malicious app on the same device can register a custom URL scheme handler and intercept the authorization code from the callback URL, then exchange it for a token.
PCI DSS 4.0 Requirement 8.3 covers strong authentication. Requirement 8.6 covers application/system account management. Requirement 6.2.4 covers injection and access-control attacks.
How to fix it
Remove "none" and weak algorithms from your IdP configuration. The setting is provider-specific:
- Keycloak — Realm Settings → Tokens → "Default Signature Algorithm" (set to RS256), then Clients → per-client → "ID Token Signature Algorithm".
- Auth0 — Application Settings → Advanced Settings → OAuth → JsonWebToken Signature Algorithm.
- Okta — Apps → your application → General → OpenID Connect ID Token → Algorithm.
- IdentityServer4 / Duende — server-side, register only RS256 in
SigningCredentials.
- Custom JWT verification code — never honor the
alg header; pin to your expected algorithm and key.
Require PKCE for all authorization-code clients (not just public ones — it's now best practice for confidential clients too):
- Keycloak: Client → Settings → "Proof Key for Code Exchange Code Challenge Method" = S256.
- Auth0: enable "Require PKCE" toggle on the application settings.
- Authorization request from the client must include
code_challenge + code_challenge_method=S256.
Disable implicit flow at the IdP unless you have a specific legacy client that needs it. Authorization code + PKCE replaces every legitimate use case.
Validate the discovery document with oauth.tools or OpenID Connect Conformance Tests.