GHSA-F7PM-6HR8-7GGM

Vulnerability from github – Published: 2026-03-10 01:19 – Updated: 2026-03-10 22:21
VLAI
Summary
Webauthn Framework: allowed_origins collapses URL-like origins to host-only values, bypassing exact origin validation
Details

Summary

When allowed_origins is configured, CheckAllowedOrigins reduces URL-like values to their host component and accepts on host match alone. This makes exact origin policies impossible to express: scheme and port differences are silently ignored.

Details

CheckAllowedOrigins stores each configured allowed origin as:

parse_url($allowedOrigin)['host'] ?? $allowedOrigin

and later reduces the received clientDataJSON.origin the same way:

parse_url($C->origin)['host'] ?? $C->origin

If the reduced value matches, the method returns early. As a result, for the normal allowed_origins path, the later HTTPS check is not reached.

This differs from WebAuthn Level 2, which requires verifying that C.origin matches the RP's origin (scheme + host + port), separately from verifying that authData.rpIdHash matches the expected RP ID.

Affected code: - CheckAllowedOrigins.php

Spec references: - §7.1 Registering a New Credential - §7.2 Verifying an Authentication Assertion - CollectedClientData.origin

PoC

Configuration:

webauthn:
  allowed_origins:
    - https://login.example.com:8443
  allow_subdomains: false

Send a registration or authentication response whose clientDataJSON.origin is:

https://login.example.com:9443

Observed: the response is accepted, because both values are reduced to login.example.com.

Expected: the response should be rejected, because https://login.example.com:8443 and https://login.example.com:9443 are different origins.

Impact

This is an origin validation error (CWE-346) affecting deployments that use allowed_origins. The most practical browser-facing scenario is same-host / different-port origin confusion. In non-browser or custom clients, scheme confusion may also be relevant.

Fix

Fixed in version 5.2.4 by rewriting CheckAllowedOrigins to perform full origin comparison (scheme + host + port) as required by the WebAuthn spec:

  • Origins configured with a scheme (e.g. https://example.com:8443) are now stored and compared as full scheme://host[:port] values, with default port normalization (443 for HTTPS, 80 for HTTP).
  • Origins configured without a scheme are still matched by host only, for backward compatibility.
  • Subdomain matching now also verifies scheme and port consistency.

See commit b4cd9a43.

Mitigation

Upgrade to web-auth/webauthn-framework (or web-auth/webauthn-lib / web-auth/webauthn-symfony-bundle) >= 5.2.4.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "web-auth/webauthn-framework"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "5.2.0"
            },
            {
              "fixed": "5.2.4"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "web-auth/webauthn-lib"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "5.2.0"
            },
            {
              "fixed": "5.2.4"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "web-auth/webauthn-symfony-bundle"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "5.2.0"
            },
            {
              "fixed": "5.2.4"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-30964"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-346"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-03-10T01:19:46Z",
    "nvd_published_at": "2026-03-10T18:18:55Z",
    "severity": "MODERATE"
  },
  "details": "### Summary\nWhen `allowed_origins` is configured, `CheckAllowedOrigins` reduces URL-like values to their `host` component and accepts on host match alone. This makes exact origin policies impossible to express: scheme and port differences are silently ignored.\n\n### Details\n`CheckAllowedOrigins` stores each configured allowed origin as:\n\n```php\nparse_url($allowedOrigin)[\u0027host\u0027] ?? $allowedOrigin\n```\n\nand later reduces the received `clientDataJSON.origin` the same way:\n\n```php\nparse_url($C-\u003eorigin)[\u0027host\u0027] ?? $C-\u003eorigin\n```\n\nIf the reduced value matches, the method returns early. As a result, for the normal `allowed_origins` path, the later HTTPS check is not reached.\n\nThis differs from [WebAuthn Level 2](https://www.w3.org/TR/webauthn-2/), which requires verifying that `C.origin` matches the RP\u0027s origin (scheme + host + port), separately from verifying that `authData.rpIdHash` matches the expected RP ID.\n\n**Affected code:**\n- [CheckAllowedOrigins.php](https://github.com/web-auth/webauthn-framework/blob/d58906e/src/webauthn/src/CeremonyStep/CheckAllowedOrigins.php)\n\n**Spec references:**\n- [\u00a77.1 Registering a New Credential](https://www.w3.org/TR/webauthn-2/#sctn-registering-a-new-credential)\n- [\u00a77.2 Verifying an Authentication Assertion](https://www.w3.org/TR/webauthn-2/#sctn-verifying-assertion)\n- [CollectedClientData.origin](https://www.w3.org/TR/webauthn-2/#dom-collectedclientdata-origin)\n\n### PoC\nConfiguration:\n\n```yaml\nwebauthn:\n  allowed_origins:\n    - https://login.example.com:8443\n  allow_subdomains: false\n```\n\nSend a registration or authentication response whose `clientDataJSON.origin` is:\n\n```text\nhttps://login.example.com:9443\n```\n\n**Observed:** the response is accepted, because both values are reduced to `login.example.com`.\n\n**Expected:** the response should be rejected, because `https://login.example.com:8443` and `https://login.example.com:9443` are different origins.\n\n### Impact\nThis is an origin validation error (CWE-346) affecting deployments that use `allowed_origins`. The most practical browser-facing scenario is same-host / different-port origin confusion. In non-browser or custom clients, scheme confusion may also be relevant.\n\n### Fix\nFixed in version **5.2.4** by rewriting `CheckAllowedOrigins` to perform full origin comparison (scheme + host + port) as required by the WebAuthn spec:\n\n- Origins configured with a scheme (e.g. `https://example.com:8443`) are now stored and compared as full `scheme://host[:port]` values, with default port normalization (443 for HTTPS, 80 for HTTP).\n- Origins configured without a scheme are still matched by host only, for backward compatibility.\n- Subdomain matching now also verifies scheme and port consistency.\n\nSee commit [b4cd9a43](https://github.com/web-auth/webauthn-framework/commit/b4cd9a43).\n\n### Mitigation\nUpgrade to `web-auth/webauthn-framework` (or `web-auth/webauthn-lib` / `web-auth/webauthn-symfony-bundle`) **\u003e= 5.2.4**.",
  "id": "GHSA-f7pm-6hr8-7ggm",
  "modified": "2026-03-10T22:21:15Z",
  "published": "2026-03-10T01:19:46Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/web-auth/webauthn-framework/security/advisories/GHSA-f7pm-6hr8-7ggm"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-30964"
    },
    {
      "type": "WEB",
      "url": "https://github.com/web-auth/webauthn-framework/commit/535cc3c2dcbd9c3dfd5e00a254ad4a984e5e7839"
    },
    {
      "type": "WEB",
      "url": "https://github.com/web-auth/webauthn-framework/commit/b4cd9a4394c35fcac6080fd2f84f4f58a30abc01"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/web-auth/webauthn-framework"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Webauthn Framework: allowed_origins collapses URL-like origins to host-only values, bypassing exact origin validation"
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.

Loading…

Loading…

Loading…

Related by attack behaviour

Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.


Loading…