Keycloak redirect URI wildcards: why "*" is dangerous and what to use instead
A redirect URI of "*" lets anyone send your users' login codes to their own site. Here is how to find the exact callback URLs and lock a Keycloak client down.
It usually starts with a login that fails with Invalid parameter: redirect_uri. Someone sets the client's redirect URIs to *, the error goes away, and the setting stays for years. This article explains what that wildcard allows, and how to replace it with the exact URLs your application uses.
What realmlint reports
HIGH Redirect URIs use wildcards [redirect-uri-wildcard]
- client "web-spa": redirect URI "*" allows any destination
- client "portal": redirect URI "https://portal.example.com/*" allows any path
A bare *, /* or https://* is reported as high: it matches any website. A path wildcard on a fixed host, such as https://portal.example.com/*, is reported as low: it is limited to your own host, but still wider than it needs to be.
Why it matters
When a user logs in, the application tells Keycloak where to send them afterwards in the redirect_uri parameter. Keycloak sends the authorization code there, as long as the address matches one of the client's Valid redirect URIs. That check is the only thing stopping the code going somewhere else.
With *, the check passes for any address. An attacker can send a user a normal-looking login link for your application with redirect_uri pointing at their own site. The user logs in on your real Keycloak page, and the code goes to the attacker. For a public client without PKCE, that code can be exchanged for the user's tokens.
A path wildcard on your own host is narrower. It still means any page on that host can receive codes, including old pages, user-generated content and any open redirect.
Find the exact callback URLs
Your application only needs the specific address its login library returns to. To find it:
- Look in the application's OIDC settings for
redirect_uri,redirectUriorcallback. - Or start a login in the browser and read the
redirect_uriparameter in the address bar of the Keycloak login page.
Collect one exact URL per environment, for example https://app.example.com/auth/callback and https://staging.example.com/auth/callback. Keep http://localhost addresses on a separate development client rather than on the production one.
Fix it in the admin console
- Open the realm and go to Clients, then select the client.
- On the Settings tab, find Access settings.
- In Valid redirect URIs, remove the wildcard entries and add each exact callback URL on its own line.
- Set Valid post logout redirect URIs to
+, which reuses the redirect URI list, or list the exact logout pages. - Set Web origins to
+, which allows only the origins of your redirect URIs, instead of*. - Click Save, then log in to the application once in each environment to confirm it still works.
If a login now fails with Invalid parameter: redirect_uri, the application is using an address you did not list. Add that exact address rather than going back to a wildcard.
Fix it in a realm file
If you keep realm configuration in Git, the same change in the client's JSON looks like this:
{
"clientId": "web-spa",
"redirectUris": [
"https://app.example.com/auth/callback",
"https://staging.example.com/auth/callback"
],
"webOrigins": ["+"],
"attributes": {
"post.logout.redirect.uris": "+"
}
}
Check it worked
kc.sh export --realm myrealm --file myrealm.json realmlint check myrealm.json
The redirect-uri-wildcard finding should be gone for that client. To stop wildcards coming back, run realmlint in CI on your realm files with --fail-on high.