GHSA-gpxg-fx2g-qxj2 The kanidmd web UI renders the WebAuthn passkey-registration challenge as raw JSON inside an inline `<script id="data">` element
An authenticated low-privilege user can inject HTML into another user's passkey page, triggering htmx requests to escalate privileges or take over accounts.
- Exploited in the wild
- Not known
- Login needed
- Any signed-in user
- Attackable
- Over the internet
- Victim action needed
- A user has to click or open something
- Fix
- Available
What is GHSA-gpxg-fx2g-qxj2?
GHSA-gpxg-fx2g-qxj2 is a cross-site scripting vulnerability in kanidm, published on 6 May 2026. Any signed-in user can exploit it over the network, and only if a user opens a file or follows a link.
Official description
Summary
The kanidmd web UI renders the WebAuthn passkey-registration challenge as raw JSON inside an inline <script id="data"> element using the Askama |safe filter. The challenge embeds the account's displayname, which serde_json serialises without escaping </>. A displayname containing </script> therefore terminates the script element early and injects arbitrary HTML into the credential-update page. Because the page is htmx-driven and the server's CSP allows 'unsafe-eval', injected hx-* attributes can issue authenticated same-origin API requests with the viewer's bearer cookie.
Impact
An authenticated attacker who is a member of idm_people_admins can write the displayname of any Person entry — including high-privilege persons — because idm_acp_people_pii_manage carries no high-privilege exclusion filter. When the targeted high-privilege user later opens Add Passkey on their own credential-update page (/ui/reset), the injected markup is swapped into the DOM and htmx fires attacker-chosen same-origin requests authenticated as the victim. This allows a helpdesk-tier operator to escalate to idm_admins (e.g. by POSTing themselves into the group) or otherwise act with the victim's session. The self-write path (idm_people_self_name_write) is self-XSS only and is not counted toward impact. Even without the htmx vector, the breakout permits <meta http-equiv='refresh'> open-redirect and arbitrary defacement of the credential page.
Details
- https://github.com/kanidm/kanidm/blob/master/server/core/templates/credential_update_add_passkey_partial.html#L3 — the
|safesink - https://github.com/kanidm/kanidm/blob/master/server/core/src/https/views/reset.rs#L506-L509 —
serde_json::to_stringof the challenge - https://github.com/kanidm/kanidm/blob/master/server/lib/src/idm/credupdatesession.rs#L2453-L2460 —
displaynameflows intostart_passkey_registration
Affected versions
All releases shipping the htmx credential-update views
Which versions are affected by GHSA-gpxg-fx2g-qxj2?
2 open source packages ship an affected version, including kanidm.
| Package | Affected | Fixed in |
|---|---|---|
kanidm crates.io | All versions | 1.9.3 |
kanidm crates.io | All versions | 1.9.3 |
How do I fix GHSA-gpxg-fx2g-qxj2?
Upgrade kanidm to 1.9.3 or later.
Escape output for the context it lands in and set a strict Content Security Policy. Upgrading the affected component is the real fix. More about Cross-site scripting.
Is GHSA-gpxg-fx2g-qxj2 being exploited?
There is no known exploitation of GHSA-gpxg-fx2g-qxj2 in the wild and no public exploit code.