Read the docs
TI-2026-66691 Aliases GHSA-53hj-r94p-8c8f

Kanidm has non-constant-time comparison of OAuth2 client_secret

Priority LOW 38CWE-208Published · Updated

Key facts

Attack vector
—
Privileges required
—
User interaction
—
Attack complexity
—
Impact type
Information disclosure
Confidentiality · integrity · availability
—
Fix status
Fixed

No CVSS vector from any source. Fix status from GitHub. Impact type from CWE-208.

Summary

### Summary The kanidmd OAuth2 token-exchange (`/oauth2/token`) and token-introspection (`/oauth2/token/introspect`) endpoints compare the supplied `client_secret` against the stored secret using Rust's `PartialEq` on `String`, which short-circuits on the first mismatching byte. This produces an observable timing discrepancy that varies with the length of the matching prefix. ### Details - https://github.com/kanidm/kanidm/blob/master/server/lib/src/idm/oauth2.rs#L1135 — variable-time comparison in `check_oauth2_token_exchange` - https://cwe.mitre.org/data/definitions/208.html — CWE-208: Observable Timing Discrepancy ### PoC Static analysis only — no timing-recovery script was run because remote recovery of a 48-byte high-entropy secret over HTTPS is not practically demonstrable. The variable-time behaviour is established by inspection: ```rust // server/lib/src/idm/oauth2.rs:1135 (check_oauth2_token_exchange) if authz_secret == &secret { … } else { return Err(Oauth2Error::AuthenticationRequired); } ``` `String: PartialEq` delegates to `<[u8] as PartialEq>::eq`, which checks length equality then iterates byte-by-byte and returns on the first difference. ### Impact An unauthenticated network attacker who can reach the OAuth2 endpoints can submit arbitrary `client_id`/`client_secret` pairs and observe response latency. In principle the early-exit comparison leaks the position of the first mismatching byte, providing a timing oracle toward incremental recovery of a confidential client's secret. In practice the stored secret is a server-generated 48-character high-entropy string, the comparison runs inside an async tokio handler behind TLS, and network jitter is orders of magnitude larger than a single byte-compare — so remote recovery is not considered realistic with current techniques. This is a hardening issue rather than a practically exploitable vulnerability. ### Affected versions All published `kanidmd_lib` releases; the comparison is still variable-time on `master` at 1.10.0-dev

Why it matters now

Fix Fixed kanidm (crates.io): 1.9.3

SSVC decision points

Not available: CISA has not published SSVC decision points for this record.

Affected products

VendorProductAffected versionsFixed inStatusSource
—kanidm (crates.io)before 1.9.31.9.3Patch availableGHSA-53hj-r94p-8c8f
  • kanidm (crates.io) Vendor— Affected before 1.9.3 Fixed in 1.9.3 Patch available GHSA-53hj-r94p-8c8f

Remediation

  • Fix · GHSA-53hj-r94p-8c8f kanidm (crates.io) Fixed in 1.9.3 Advisory →

Timeline

  1. 2026-10-03 Threatist record created from GHSA-53hj-r94p-8c8f

References

Sources

This product uses the NVD API but is not endorsed or certified by the NVD. Sources and licences