Repository navigation
OpenConceptLab/ocl_online#535 | Percent-encode the query values in the Keycloak login, sign-up, reset and logout URLs - #946
Conversation
…e Keycloak login, sign-up, reset and logout URLs OpenIDAuthService built these URLs with f-strings, putting the already-decoded query values in raw. A post_logout_redirect_uri or redirect_uri carrying ?, & or # split into extra params or lost its tail. A new build_url helper encodes every value with urlencode(quote_via=quote), keeping the parameter names and order. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
snyaggarwal
left a comment
There was a problem hiding this comment.
Verdict: Approve
Issue complete: yes. Centralizing Keycloak URL construction with urlencode preserves redirect_uri, post_logout_redirect_uri, state, nonce, and PKCE values across the API-to-Keycloak hop, including embedded #, ? and & characters. Existing parameter order and endpoint selection remain intact.
Security blockers: none. Encoding the decoded query values removes parameter-splitting and fragment-loss behavior without weakening redirect validation.
Verification: the focused auth suite passed locally (7 tests), including the new round-trip encoding coverage; Snyk passes. GitHub Pylint was still pending at review time, so merge should remain gated on that check.
(snyaggarwal • ReviewAutomation/GPT-5)
Server-side part of OpenConceptLab/ocl_online#535.
Why
OpenIDAuthServicebuilt the Keycloak URLs with f-strings. The values come fromrequest.query_params, which Django has already decoded, and went into the URL raw. Apost_logout_redirect_uriorredirect_uricontaining?,&or#therefore split into extra parameters or, with#, lost everything after it on the redirect to Keycloak. That second hop contributed to the "Invalid redirect uri" page users hit after an expired session in the Mapper.What changes
OpenIDAuthService.build_url(endpoint, params, code_challenge, code_challenge_method)encodes every value withurlencode(..., quote_via=quote).get_login_redirect_url,get_registration_redirect_url,get_reset_password_redirect_urlandget_logout_redirect_urluse it. Parameter names and order are unchanged.redirect_uri=http%3A%2F%2Flocalhost%3A4000andscope=openid%20profile%20email. Keycloak decodes them to the same strings.No migrations, indexing or env var changes.
Verification
docker exec -e OIDC_SERVER_URL= -e OIDC_SERVER_INTERNAL_URL= oclapi2-api-1 python manage.py test core.services.auth core.users.tests --keepdb: 97 tests, OK.test_redirect_urls_keep_query_values_wholepasses aredirect_uricontaining#,?and&, plus&and#in state and nonce, through all four builders. It checks that each value reads back intact viaparse_qswith no fragment.OIDC_SERVER_URLset fails them before and after this change.docker exec oclapi2-api-1 pylint core/services/auth/openid.py core/services/auth/tests.py: 10.00/10.Companion PRs: OpenConceptLab/oclmap#109 and OpenConceptLab/oclweb3#67. Their values are already safe either way, so the three can be deployed in any order.
🤖 Generated with Claude Code