From 0c537e0c3352660b2fecd00e7345996a053fa0ca Mon Sep 17 00:00:00 2001 From: Scott Helme Date: Fri, 27 Mar 2026 23:00:25 +0000 Subject: [PATCH] Reject cross-origin requests in processCreate and processGet MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per the proposed Level 3 spec (§7.1 Step 10, §7.2 Step 13), reject ceremonies where clientDataJSON.crossOrigin is true. This prevents an attacker from embedding a legitimate site's WebAuthn ceremony in a cross-origin iframe on a malicious domain. The check is backwards-compatible: crossOrigin is optional in the spec, so clients that don't send it are unaffected. Fixes lbuchs/WebAuthn#124 --- src/WebAuthn.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/WebAuthn.php b/src/WebAuthn.php index f2eb755..619aec7 100644 --- a/src/WebAuthn.php +++ b/src/WebAuthn.php @@ -357,6 +357,11 @@ public function processCreate($clientDataJSON, $attestationObject, $challenge, $ throw new WebAuthnException('invalid origin', WebAuthnException::INVALID_ORIGIN); } + // Reject cross-origin requests (proposed Level 3 spec §7.1 Step 10). + if (\property_exists($clientData, 'crossOrigin') && $clientData->crossOrigin === true) { + throw new WebAuthnException('cross-origin request not allowed', WebAuthnException::INVALID_ORIGIN); + } + // Attestation $attestationObject = new Attestation\AttestationObject($attestationObject, $this->_formats); @@ -475,6 +480,11 @@ public function processGet($clientDataJSON, $authenticatorData, $signature, $cre throw new WebAuthnException('invalid origin', WebAuthnException::INVALID_ORIGIN); } + // Reject cross-origin requests (proposed Level 3 spec §7.2 Step 13). + if (\property_exists($clientData, 'crossOrigin') && $clientData->crossOrigin === true) { + throw new WebAuthnException('cross-origin request not allowed', WebAuthnException::INVALID_ORIGIN); + } + // 11. Verify that the rpIdHash in authData is the SHA-256 hash of the RP ID expected by the Relying Party. if ($authenticatorObj->getRpIdHash() !== $this->_rpIdHash) { throw new WebAuthnException('invalid rpId hash', WebAuthnException::INVALID_RELYING_PARTY);