ASVS 5.0 V10.6.1 (Level 2) says the OpenID Provider may allow only the response values code, ciba, id_token or id_token code. The plain code flow is preferred over the hybrid id_token code flow, and any flow that returns an access token through the front channel, response type token, must not be used.
Why it matters
Front channel token delivery exposes tokens to browser history, referrers and scripts. The authorization code flow keeps tokens on the back channel, where the client authenticates and PKCE applies.
How to implement it
Disable every flow that returns an access token through the browser, in the provider configuration, and prefer plain code over the hybrid flow. In Keycloak that means turning off Implicit flow on every client. For your own provider, whitelist values:
ALLOWED_RESPONSE_TYPES = {"code"}
def check_response_type(response_type):
if response_type not in ALLOWED_RESPONSE_TYPES:
raise UnsupportedResponseType()
Also publish only supported values in response_types_supported in discovery metadata.
How to test it
Request response_type=token, id_token token and code token at the authorization endpoint and expect errors. Fetch discovery metadata and read response_types_supported.
Keeping legacy clients in check
Old integrations are why implicit flows linger. Find them by listing clients with implicit enabled and checking recent use in your logs. Contact owners, set a date, and then switch the flow off. Each migration is a small change to the authorization code flow with PKCE, which libraries handle for the client.
Common mistakes
- Leaving a legacy client with implicit enabled.
- Advertising more types in metadata than you accept.
Quick check
Which flow is preferred?
The plain authorization code flow, over the hybrid one.