{"id":"GHSA-22w3-693w-x895","aliases":[],"url":"https://o3.security/vulnerability/GHSA-22w3-693w-x895","summary":"webauthn-rs-core/webauthn-authenticator-rs: Origin validation mismatch possible when subdomains are allowed","details":"### Summary\n\n`webauthn-rs-core` ([Relying Party][rp]) and `webauthn-authenticator-rs` ([client][]) checked that [an `Origin` in `CollectedClientData`][origin] is valid for [an RP ID][rpid] with [`str::ends_with()`][ends-with], [without checking for a dot (`.`) before the RP ID when allowing subdomains][registerable-suffix].\n\nThis check is flawed, and could allow requests from an attacker-controlled domain such as `hermit-crab.example` to be accepted for the RP ID `crab.example` (assuming `.example` was publicly-registerable TLD) when the RP allows authenticating from a subdomain (disabled by default in `webauthn-rs-core` and `webauthn-rs`).\n\n[registerable-suffix]: https://html.spec.whatwg.org/multipage/browsers.html#is-a-registrable-domain-suffix-of-or-is-equal-to\n[ends-with]: https://doc.rust-lang.org/stable/std/primitive.str.html#method.ends_with\n[client]: https://www.w3.org/TR/webauthn-3/#client\n[rp]: https://www.w3.org/TR/webauthn-3/#relying-party\n[rpid]: https://www.w3.org/TR/webauthn-3/#rp-id\n[origin]: https://www.w3.org/TR/webauthn-3/#dom-collectedclientdata-origin\n\n* In `webauthn-rs-core`, this **only** applies when:\n  * [`WebauthnCore::allow_subdomains_origin`](https://docs.rs/webauthn-rs-core/0.5.4/webauthn_rs_core/struct.WebauthnCore.html#method.new_unsafe_experts_only) is `true` (the default is `false`), *and*\n  * the attacker could register a domain that ends with the RP ID as a raw string, *and*,\n  * the client does not implement these checks correctly either\n\n  `webauthn-rs` can set `allow_subdomains_origin` via [`WebauthnBuilder::allow_subdomains`](https://docs.rs/webauthn-rs/0.5.4/webauthn_rs/struct.WebauthnBuilder.html#method.allow_subdomains). Fixing the bug in `webauthn-rs-core` also fixes it in `webauthn-rs`.\n\n* In `webauthn-authenticator-rs`, the flawed check is in [`WebauthnAuthenticator::do_registration()`](https://docs.rs/webauthn-authenticator-rs/0.5.4/webauthn_authenticator_rs/struct.WebauthnAuthenticator.html#method.do_registration) and [`do_authentication()`](https://docs.rs/webauthn-authenticator-rs/0.5.4/webauthn_authenticator_rs/struct.WebauthnAuthenticator.html#method.do_registration). \n\n  A conforming [Relying Party][rp] implementation would reject such requests, but `webauthn-rs-core` did not.\n\n  An application can still provide an incorrect `origin` parameter to `webauthn-authenticator-rs`, or use lower-level APIs that bypass these checks entirely, and this is by design.\n\nThese issues are a violation of [WebAuthn Level 3 §13.4.9](https://www.w3.org/TR/webauthn-3/#sctn-validating-origin), [§5.1.3 Step 8](https://www.w3.org/TR/webauthn-3/#CreateCred-DetermineRpId) and [§5.1.4.1 Step 7](https://www.w3.org/TR/webauthn-3/#GetAssn-DetermineRpId).\n\n### Details\n\n* `webauthn-rs-core/src/core.rs` line 1213:\n\n  https://github.com/kanidm/webauthn-rs/blob/197cddf8487a2dbdd5d374e50d80aa1e4682f3ab/webauthn-rs-core/src/core.rs#L1211-L1216\n\n* `webauthn-authenticator-rs/src/lib.rs` line 274:\n\n  https://github.com/kanidm/webauthn-rs/blob/197cddf8487a2dbdd5d374e50d80aa1e4682f3ab/webauthn-authenticator-rs/src/lib.rs#L274-L277\n\n* `webauthn-authenticator-rs/src/lib.rs` line 335:\n\n  https://github.com/kanidm/webauthn-rs/blob/197cddf8487a2dbdd5d374e50d80aa1e4682f3ab/webauthn-authenticator-rs/src/lib.rs#L335-L338\n\n[`str::ends_with()`][ends-with] performs a raw string suffix match _without_ [enforcing a domain label boundary][registerable-suffix]:\n\nOrigin | RP ID | Expected result | Result with incorrect `ends_with` check\n-- | -- | -- | --\n`hermit-crab.example` | `crab.example` | rejected | accepted **(bug!)**\n`auth.crab.example` | `crab.example` | accepted | accepted (subdomain)\n`crab.example` | `crab.example` | accepted | accepted (exact match)\n`hermit-crab.example` | `auth.crab.example` | rejected | rejected\n`auth.crab.example` | `auth.crab.example` | accepted | accepted (exact match)\n\n### Fix\n\nWhen `webauthn-rs-core` v0.5.5 checks if an `Origin` is a valid subdomain of an RP ID, it will check that it ends with the RP ID prefixed with a dot (`.{rp_id}`). `webauthn-rs` v0.5.5 will be fixed by depending on `webauthn-rs-core` v0.5.5.\n\n`webauthn-authenticator-rs` v0.5.5 now uses `webauthn-rs-core`'s checks in `WebauthnAuthenticator`.\n\nRegression tests for this bug have been added to both libraries.\n\n### Impact\n\nWith a **both** a non-conforming [client][] implementation and vulnerable version of `webauthn-rs-core` configured to allow subdomains (not the default), this bug would allow an attacker at `hermit-crab.example` to phish a target's credential for the RP ID `crab.example` by directly proxying a legitimate `navigator.credentials.get()` request on the attacker's domain.\n\nHowever, _conforming_ [client implementations][client] (ie: all web browsers) will refuse to process WebAuthn requests for an RP ID that does not match the `Origin` of the current page and is not [a related `Origin`](https://www.w3.org/TR/webauthn-3/#sctn-related-origins).\n\nIn the scenario above with _conforming_ client-side checks, this would force the attacker to change the request's RP ID to `hermit-crab.example` (the attacker's `Origin`). This would also change the RP ID hash, [and `webauthn-rs-core` would reject it](https://github.com/kanidm/webauthn-rs/blob/197cddf8487a2dbdd5d374e50d80aa1e4682f3ab/webauthn-rs-core/src/core.rs#L825-L840) (per [WebAuthn §7.2 Step 15](https://www.w3.org/TR/webauthn-3/#rp-op-verifying-assertion-step-rpid-hash)).\n\n### Severity\n\nPer [WebAuthn §13.4.9](https://www.w3.org/TR/webauthn-3/#sctn-validating-origin):\n\n> The [Relying Party](https://www.w3.org/TR/webauthn-3/#relying-party) MUST NOT accept unexpected values of [origin](https://www.w3.org/TR/webauthn-3/#dom-collectedclientdata-origin), as doing so could allow a malicious website to obtain valid [credentials](https://www.w3.org/TR/credential-management-1/#concept-credential). Although the [scope](https://www.w3.org/TR/webauthn-3/#scope) of WebAuthn credentials prevents their use on domains outside the [RP ID](https://www.w3.org/TR/webauthn-3/#rp-id) they were registered for, the [Relying Party](https://www.w3.org/TR/webauthn-3/#relying-party)’s origin validation serves as an additional layer of protection in case a faulty [authenticator](https://www.w3.org/TR/webauthn-3/#authenticator) fails to enforce credential [scope](https://www.w3.org/TR/webauthn-3/#scope).\n\nUnfortunately, [the chain needed to exploit this bug makes it difficult to classify with the CVSS framework](https://www.first.org/cvss/v4.0/user-guide#Vulnerability-Chaining). Kanidm came up with anywhere between \"low\" and \"high\" depending on the approach, and GitHub only provides one CVSS field for everything.\n\nAn attacker could easily bypass a _correctly-implemented_ server-side `Origin` check, if they can convince a target to use their authenticator with [an attacker-controlled client device](https://fidoalliance.org/specs/common-specs/fido-security-ref-v2.1-ps-20220523.html#dfn-t-1.3.2) or [buggy/malicious client application](https://fidoalliance.org/specs/common-specs/fido-security-ref-v2.1-ps-20220523.html#dfn-t-1.3.1). FIDO's Security Reference [assumes that \"the FIDO user device and applications involved in a FIDO operation are trustworthy agents of the user\"](https://fidoalliance.org/specs/common-specs/fido-security-ref-v2.1-ps-20220523.html#dfn-sa-4), and violating that [limits the protections FIDO can provide](https://fidoalliance.org/specs/common-specs/fido-security-ref-v2.1-ps-20220523.html#discussion), so it would be ridiculous to describe those bypasses as a \"high\" severity vulnerability.\n\nHowever, `webauthn-rs-core` should take reasonable steps to prevent these sorts of issues where it can, especially when they're part of the WebAuthn specification.\n\nDue to the complex preconditions and non-default configuration required to execute a successful attack, and that it is *not exploitable* in popular web browsers, Kanidm considers this a **low severity** issue.","published":"2026-05-06T23:31:27Z","modified":"2026-09-10T03:51:04.039013566Z","cvss":null,"epss":null,"cisaKev":null,"exploitsKnown":0,"affectedPackages":[{"ecosystem":"crates.io","name":"webauthn-rs-core","fixedVersion":"0.5.5"},{"ecosystem":"crates.io","name":"webauthn-authenticator-rs","fixedVersion":"0.6.1-dev"},{"ecosystem":"crates.io","name":"webauthn-rs-core","fixedVersion":"0.6.1-dev"},{"ecosystem":"crates.io","name":"webauthn-authenticator-rs","fixedVersion":"0.5.5"}],"fix":null,"references":[{"type":"WEB","url":"https://github.com/kanidm/webauthn-rs/security/advisories/GHSA-22w3-693w-x895"},{"type":"PACKAGE","url":"https://github.com/kanidm/webauthn-rs"}],"provenance":{"sources":["OSV.dev","FIRST.org (EPSS)"],"lastVerified":"2026-09-10T03:51:04.039013566Z"}}