8000 Client uris validation improvements by graziang · Pull Request #54062 · keycloak/keycloak · GitHub
[go: up one dir, main page]

Skip to content

Client uris validation improvements - #54062

Merged
mposolda merged 3 commits into
keycloak:mainfrom
graziang:issue-54046
Nov 2, 2026
Merged

mposolda merged 3 commits into
keycloak:mainfrom
graziang:issue-54046

Conversation

@graziang
@graziang graziang commented Oct 16, 2026 •
Copy link
Copy Markdown
Contributor

Closes #54046

This PR adds ClientUriField, a single catalog of the client URI fields with the common code to read and validate them, and makes all validators use it. Existing configuration keys, field names, patterns, wildcard options and the handling of relative URIs, data: logos and the +, *, - and null markers are unchanged.

  • Add ClientUriField as the shared list of client URI fields, with common code to read values and run validation.
  • Update DefaultClientValidationProvider to use the shared list and keep existing validation rules and error messages.
  • Update TrustedHostClientRegistrationPolicy to check all listed URI fields on creation and update, including post-logout redirects.
  • Update SecureClientUrisExecutor to also check sector identifier attributes and SAML endpoint and metadata URLs.
  • Update SamlSecureClientUrisExecutor to check the shared list for SAML clients, including stored URLs during login and logout.
  • Update SecureClientUrisPatternExecutor and its factory to use the shared list while keeping field selection and literal regex matching.
  • Keep existing configuration names, wildcard options and relative URI behavior.
  • Add regression tests and upgrade notes for values that the new checks now reject.

Copilot AI balanced review requested due to automatic review settings October 16, 2026 10:34
@graziang
graziang requested a review from a team as a code owner October 16, 2026 10:34
Copilot AI left a comment
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The focused changes follow existing validation patterns and include regression coverage, with no blocking issues identified; tests were not executed.

0 open findings

What changed in this PR

Extends Trusted Hosts client registration validation to post-logout redirect URIs, addressing #54046.

Changes:

  • Applies existing trusted-host checks to post-logout redirects while excluding special markers.
  • Rejects null hosts safely.
  • Adds regression coverage for rejected create/update requests and accepted redirects.
File Description
tests/​base/​src/​test/​java/​org/​keycloak/​tests/​client/​ClientRegistrationPoliciesTest.java Tests post-logout redirect validation during registration and updates.
services/​src/​main/​java/​org/​keycloak/​services/​clientregistration/​policy/​impl/​TrustedHostClientRegistrationPolicy.java Validates post-logout redirect hosts and handles null hosts.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

< 8000 div data-view-component="true" class="comment-reactions js-reactions-container js-reaction-buttons-container social-reactions reactions-container d-flex">
@oleksii-udovychenko oleksii-udovychenko left a comment
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should backchannel_logout_uri and frontchannel_logout_uri also be checked against the trusted hosts here?

An anonymous registration with a redirect_uris entry on an untrusted host gets 403. The same registration with either logout URI on that host gets 201, and for the backchannel one Keycloak sends the logout token to that host when the user logs out.

With this PR, the Trusted Hosts policy checks rootUrl, baseUrl, adminUrl, redirect_uris and now post_logout_redirect_uris (verifyClientUrls). The two logout URIs are stored from the registration request (backchannel, frontchannel), but the policy doesn't check them.

How I tested, on this PR's head with a probe test in ClientRegistrationPoliciesTest:

  1. Trusted host set to localhost. An HTTP listener on 127.0.0.1 plays the untrusted host.
  2. Registered a client anonymously with one URI field on 127.0.0.1 at a time.
  3. For the backchannel client, logged in a user, then logged that user out from the admin API. To log in I turned off consent and enabled direct grants on that client through the admin API. Neither change touches the URIs.

I didn't check the frontchannel iframe in a browser. #50530 tracks the same two fields for CIMD.

Field on 127.0.0.1 Expected Actual
redirect_uris 403 403
post_logout_redirect_uris 403 403 (this PR)
frontchannel_logout_uri 403 201, client created
backchannel_logout_uri 403 201, client created; on logout, 127.0.0.1 received POST /backchannel with a logout_token

@girishkvs
Copy link
Copy Markdown

Thanks @graziang. I pulled this change on 26.8.1 and verified against the original report: untrusted post_logout_redirect_uris now get 403 on create and on update, including through the default provider and a +##<url> value, while trusted URIs and + still register.

Consider adding a default provider case to testAnonCreateWithPostLogoutRedirectUri, since that path sets post.logout.redirect.uris directly instead of through the OIDC converter.

Copilot AI balanced review requested due to automatic review settings October 19, 2026 08:18
Copilot AI left a comment
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Protocol-relative front-channel logout URLs can bypass the new trusted-host validation.

1 open issue

Review effort: Balanced

Copilot AI balanced review requested due to automatic review settings October 19, 2026 08:22
@graziang graziang changed the title Validate post_logout_redirect_uris in the Trusted Hosts client registration policy Validate uris in the Trusted Hosts client registration policy Oct 19, 2026
Copilot AI left a comment
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Scheme-relative front-channel logout URLs still bypass the trusted-host validation.

1 open issue

Review effort: Balanced

Copilot AI balanced review requested due to automatic review settings October 19, 2026 08:57
Copilot AI left a comment
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The validation changes address the reported weakness with regression coverage and no identified blocking issues.

No open issues 🎉

1 resolved since last review

Review effort: Balanced

@graziang
Copy link
Copy Markdown
Contributor Author

frontchannel_logout_uri

@oleksii-udovychenko added validation also for frontchannel_logout_uri and frontchannel_logout_uri, can you please check?

@graziang
Copy link
Copy Markdown
Contributor Author

Thanks @graziang. I pulled this change on 26.8.1 and verified against the original report: untrusted post_logout_redirect_uris now get 403 on create and on update, including through the default provider and a +##<url> value, while trusted URIs and + still register.

Consider adding a default provider case to testAnonCreateWithPostLogoutRedirectUri, since that path sets post.logout.redirect.uris directly instead of through the OIDC converter.

@girishkvs updated the test, can you please check?

@oleksii-udovychenko
Copy link
Copy Markdown
Contributor

Thanks @graziang. I re-ran the same probe on the latest commit, and both logout URIs are now rejected. Since the client can't be registered with an untrusted backchannel URI, the logout step doesn't run any more.

Field on 127.0.0.1, trusted host localhost Before Now
redirect_uris 403 403
post_logout_redirect_uris 403 403
frontchannel_logout_uri 201 403, URL doesn't match any trusted host or trusted domain
backchannel_logout_uri 201, logout token sent to 127.0.0.1 403, URL doesn't match any trusted host or trusted domain

@girishkvs
Copy link
Copy Markdown

@graziang testAnonCreateWithClientUrisDefaultProvider covers the default provider case. I pulled the latest commit on 26.8.1 and verified again: untrusted post_logout_redirect_uris, frontchannel_logout_uri, backchannel_logout_uri and request_uris now get 403, including a //<host> front-channel URI and an update through the default provider, while trusted URIs and + still register.

@mposolda mposolda left a comment
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see the possible problem of why the URIs like post_logout_redirect_uris or "frontchannel logout uri" should be checked, but other URIs like for example "logo URI" are not checked?

The documentation is not very specific . It mentions just "URLs of newly registered client must also use just those trusted hosts or domains."

As usual, I afraid that if we accept this one, we will have follow-up reports that client URI x is checked, but client URI y is not checked.

We have few places, where we check client URIs. Maybe there are more, but I am aware of:

  • DefaultClientValidationProvider
  • SecureClientUrisPatternExecutor
  • SecureClientUrisExecutor
  • TrustedHostClientRegistrationProvider

IMO it would be great if all those make sure that they check the same set of URIs. Can we have the list of URIs configured somewhere on single place and make sure that all those consume it from this single place?
Right now, we have metadata in SecureClientUrisPatternExecutorFactory.ALL_CLIENT_URI_FIELDS and DefaultClientValidationProvider.FieldMessages . Can we somehow unify those and update somehow the format of those metadata, so that it can be consumed by all places?

@jimmychakkalakal jimmychakkalakal left a comment
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @graziang, I have reviewed the changes LGTM, I approve PR from me end

Copilot AI balanced review requested due to automatic review settings October 26, 2026 10:08
@graziang
graziang requested a review from a team as a code owner October 26, 2026 10:08
Copilot AI left a comment
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Protocol-dependent pattern validation allows staged updates to activate a retained SAML endpoint outside the configured allowlist.

1 open issue

Review effort: Balanced

@graziang
graziang marked this pull request as draft October 26, 2026 10:16
@graziang
graziang force-pushed the issue-54046 branch 3 times, most recently from d4facd8 to ac3eccf Compare October 26, 2026 17:32
@graziang
graziang marked this pull request as ready for review October 27, 2026 10:02
Copilot AI balanced review requested due to automatic review settings October 27, 2026 10:02
Copilot AI left a comment
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Cross-protocol changes to security-sensitive registration and SAML login/logout validation warrant human compatibility review with regression-test results.

1 open issue

Review effort: Balanced

@graziang graziang changed the title Validate uris in the Trusted Hosts client registration policy Client uris validation improvements Oct 27, 2026
@mposolda mposolda self-assigned this Oct 27, 2026
mposolda
mposolda previously approved these changes Oct 27, 2026
@mposolda mposolda left a comment
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@graziang Thanks!

I've added one minor inline comment, but it is OK to merge without that. Just added that in case that there are some changes needed anyway for this PR.

However there is failing tests in Account UI, which failed for 3 re-runs. Can you check if it is related to this PR or not? It seems to me that changes in this PR are rather unrelated, but not 100% sure.

Client URI validation and client policies now share a catalog of URI fields. Existing policy configuration keys, selected field names, regular expressions, and wildcard options retain their meaning.
The following additional checks can reject previously accepted client configurations:

* With *Client URIs Must Match* enabled, the *Trusted Hosts* registration policy checks all supplied URI fields on creation and update, including post-logout redirects, logout endpoints, web origins, JWKS and request URIs, CIBA notification endpoints, logo, policy, terms of service, sector identifier attributes, and SAML endpoints and metadata URLs. Add any legitimate external hosts to the trusted-host list before updating these clients. Post-logout `*` is rejected because it permits redirects to any host. Explicit URLs accompanying `+` or `-` are also checked.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* With *Client URIs Must Match* enabled, the *Trusted Hosts* registration policy checks all supplied URI fields on creation and update, including post-logout redirects, logout endpoints, web origins, JWKS and request URIs, CIBA notification endpoints, logo, policy, terms of service, sector identifier attributes, and SAML endpoints and metadata URLs. Add any legitimate external hosts to the trusted-host list before updating these clients. Post-logout `*` is rejected because it permits redirects to any host. Explicit URLs accompanying `+` or `-` are also checked.
* With *Client URIs Must Match* enabled, the *Trusted Hosts* client registration policy checks all supplied URI fields on creation and update, including post-logout redirects, logout endpoints, web origins, JWKS and request URIs, CIBA notification endpoints, logo, policy, terms of service, sector identifier attributes, and SAML endpoints and metadata URLs. Add any legitimate external hosts to the trusted-host list before updating these clients. Post-logout `*` is rejected because it permits redirects to any host. Explicit URLs accompanying `+` or `-` are also checked.

Just a nitpick, but not a blocker for this PR from my point of view. Might be added just in case there are more issues in this PR (so that PR will need to be updated anyway).

@girishkvs
Copy link
Copy Markdown

@mposolda @graziang I did a local repro and it seems that the Account UI failure is related to this PR: linked-accounts.spec.ts:44 creates a client f 10BC8 rom groups-idp.json, which has web origin ${authAdminUrl}, and ac3eccf now rejects it with A web origin is not a valid URI (invalid_input). On today's nightly, web origins ${authAdminUrl}, ${authBaseUrl} and file:// are accepted on main and rejected with this change.

I also pulled latest commit head ac3eccf and verified against the original report: every untrusted post-logout, front/back-channel and request_uris value is now rejected on create and update through both openid-connect and default, and the trusted ones still go through.

One more change that may affect upgrades: with saml-secure-client-uris on, an existing SAML client with an http web origin, logo or stored ACS URL now fails login with Non secure scheme for ..., even when the request's ACS is https. On main only the request's ACS is checked. Is that intended?

Closes keycloak#54046

Signed-off-by: Giuseppe Graziano <g.graziano94@gmail.com>
Closes keycloak#54046

Signed-off-by: Giuseppe Graziano <g.graziano94@gmail.com>
Copilot AI balanced review requested due to automatic review settings October 27, 2026 17:06
@graziang
Copy link
Copy Markdown
Contributor Author

@girishkvs Thanks, confirmed and fixed the web-origin regression. Also relative logos now work with Trusted Hosts.
The broader SAML validation is intentional, I clarified the upgrade notes.
@mposolda applied your documentation suggestion and rebased, let's see the CI.

Copilot AI left a comment
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The security-sensitive changes span registration and runtime validation, and relative-URL resolution concerns need human review before approval.

No open issues 🎉

1 resolved since last review

Review effort: Balanced

Signed-off-by: Marek Posolda <mposolda@gmail.com>
Copilot AI balanced review requested due to automatic review settings November 2, 2026 15:02
Copilot AI left a comment
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Relative front-channel logout URLs are checked against the client root instead of their actual Keycloak frontend destination, allowing logout destinations on hosts outside the allowlist.

1 open issue

Review effort: Balanced

return value;
}

return rootUrl == null || rootUrl.isEmpty() ? null : rootUrl + value;
@mposolda mposolda left a comment
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@graziang Thanks!

@mposolda
mposolda merged commit ae8fa4c into keycloak:main Nov 2, 2026
96 of 97 checks passed
ruchikajha95 pushed a commit to ruchikajha95/keycloak that referenced this pull request Nov 3, 2026
Closes keycloak#54046


Signed-off-by: Giuseppe Graziano <g.graziano94@gmail.com>
Signed-off-by: Marek Posolda <mposolda@gmail.com>
Co-authored-by: Marek Posolda <mposolda@gmail.com>
mposolda pushed a commit that ref E50A erenced this pull request Nov 12, 2026
Closes #54046

Signed-off-by: Giuseppe Graziano <g.graziano94@gmail.com>
(cherry picked from commit ae8fa4c)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Trusted Hosts client registration policy does not constrain post_logout_redirect_uris

6 participants

0