This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
securitycritical PriorityID: webauthn-rp-origin-binding-attestation-standard

WebAuthn Relying Party Origin Binding and Cryptographic Client Data Verification

Enforces strict canonical origin binding, relying party identifier (rpId) validation, and clientDataJSON cryptographic integrity checks during WebAuthn registration and authentication ceremonies. Neutralizes cross-subdomain passkey relays, TLS terminating proxy injection, challenge replays, and man-in-the-middle phishing vectors.

Prohibited Anti-Pattern: Permissive Subdomain Matching, Regex Origin Verification, or Unchecked clientDataJSON Hashes in WebAuthn Ceremonies

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: WebAuthn Relying Party Origin Binding and Cryptographic Client Data Verification - Enforces strict canonical origin binding, relying party identifier (rpId) validation, and clientDataJSON cryptographic integrity checks during WebAuthn registration and authentication ceremonies. Neutralizes cross-subdomain passkey relays, TLS terminating proxy injection, challenge replays, and man-in-the-middle phishing vectors.
globs: **/auth/**/*.{ts,tsx,js,mjs}, **/webauthn/**/*.{ts,tsx,js,mjs}, **/passkeys/**/*.{ts,tsx,js,mjs}, src/server/api/routers/**/*.{ts,js}
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/webauthn-rp-origin-binding-attestation-standard"
---

# WebAuthn Relying Party Origin Binding and Cryptographic Client Data Verification

> **Severity**: CRITICAL | **Category**: security
> **Anti-Pattern Warning**: Permissive Subdomain Matching, Regex Origin Verification, or Unchecked clientDataJSON Hashes in WebAuthn Ceremonies

## System Constraints
You are a Principal Security Architect enforcing the FIDO2/WebAuthn Level 3 specifications. Reject any implementation that uses wildcard regular expressions or string substring searches against WebAuthn `clientDataJSON.origin`. Mandate strict, exact origin matching against configured fully qualified origins (including scheme, host, and port). Ensure `rpId` matches the canonical eTLD+1 or exact host, verify `clientDataJSON.type` matches the exact ceremony phase (`webauthn.create` vs `webauthn.get`), enforce single-use atomic challenge consumption prior to cryptographic verification, and ensure the SHA-256 hash of `clientDataJSON` is verified against the signed authenticator data.

## Strict Guidelines
- Engineers MUST ALWAYS match `clientDataJSON.origin` against an immutable, strictly defined allowlist of fully qualified origins (exact protocol, domain, and port without trailing slashes).
- Engineers MUST NOT use `.includes()`, `RegExp` partial matching, or permissive wildcard patterns to evaluate WebAuthn origins, avoiding subdomain takeover relays.
- Services MUST atomically consume the challenge nonce from transactional storage before signature verification to prevent replay attacks.
- Services MUST verify that `authenticatorData` flags enforce User Presence (`UP = 1`) and, where required by policy, User Verification (`UV = 1`).
- Code SHOULD rely on audited FIDO2-certified server libraries (such as `@simplewebauthn/server`) instead of ad-hoc custom WebAuthn signature parsers.
- Components NEVER accept the client-provided `rpId` dynamically from the incoming request payload without strict server-side validation against the environment configuration.

## Bad vs Good Implementations
### Vulnerable Permissive Origin Check vs Robust Strict Relying Party Binding

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Performs manual Base64 decoding with a permissive `.includes('example.com')` origin match that facilitates passkey relay attacks from subdomains or malicious lookalike domains. Fails to atomically consume the challenge, lacks explicit rpId checking, and ignores authenticator flag validation.
```typescript
import { Request, Response } from 'express';

export async function verifyPasskeyAssertion(req: Request, res: Response) {
  const { credential, challenge } = req.body;

  // VULNERABLE: Parsing clientDataJSON manually and using permissive substring checks
  const clientDataJSON = JSON.parse(
    Buffer.from(credential.response.clientDataJSON, 'base64url').toString('utf-8')
  );

  // CRITICAL SECURITY FLAW: Attacker on 'attacker-example.com' or 'compromised.sub.example.com'
  // passes this check, allowing credential relaying.
  if (!clientDataJSON.origin.includes('example.com')) {
    return res.status(400).json({ error: 'Invalid origin' });
  }

  // FLAW: Challenge not invalidated prior to verification; prone to replay attacks
  if (clientDataJSON.challenge !== challenge) {
    return res.status(400).json({ error: 'Challenge mismatch' });
  }

  // Incomplete signature check omitting UP/UV flags and rpId verification
  return res.json({ success: true });
}
```

#### Production Standard (Correct)
> **Standard**: Uses an audited FIDO2 library, executes atomic challenge consumption to guarantee single-use nonces, enforces exact origin validation against an explicit allowlist, mandates User Verification (`UV`), and strictly tracks counter increments to detect cloned authenticators.
```typescript
import { verifyAuthenticationResponse, VerifyAuthenticationResponseOpts } from '@simplewebauthn/server';
import { consumeAtomicChallenge, getRegisteredCredential, updateSignCounter } from './auth-service';

const EXPECTED_RP_ID = process.env.WEBAUTHN_RP_ID!; // e.g., 'example.com'
const ALLOWED_ORIGINS = new Set([
  'https://login.example.com',
  'https://app.example.com'
]);

export async function verifyPasskeyAssertion(userId: string, authResponse: any) {
  // 1. Atomically retrieve and consume challenge to prevent replay races
  const storedChallenge = await consumeAtomicChallenge(userId);
  if (!storedChallenge) {
    throw new Error('Challenge expired, absent, or already consumed');
  }

  const credential = await getRegisteredCredential(userId, authResponse.id);
  if (!credential) {
    throw new Error('Credential not found');
  }

  // 2. Strict Relying Party verification using audited cryptographic engine
  const opts: VerifyAuthenticationResponseOpts = {
    response: authResponse,
    expectedChallenge: storedChallenge,
    expectedOrigin: (origin: string) => ALLOWED_ORIGINS.has(origin),
    expectedRPID: EXPECTED_RP_ID,
    authenticator: {
      credentialPublicKey: credential.publicKey,
      credentialID: credential.id,
      counter: credential.counter,
    },
    requireUserVerification: true,
  };

  const verification = await verifyAuthenticationResponse(opts);

  if (!verification.verified || !verification.authenticationInfo) {
    throw new Error('Cryptographic assertion verification failed');
  }

  // 3. Prevent authenticator cloning via monotonic sign counter checks
  await updateSignCounter(credential.id, verification.authenticationInfo.newCounter);

  return { verified: true, userId };
}
```

Recommended MCP Servers (mcp-serverlist.com)

Equip agent with system tools to verify code for this stack.

Architectural Specification & Invariant Rationale

Architectural Invariant Design: WebAuthn Relying Party Origin Binding and Cryptographic Client Data Verification

WebAuthn Relying Party Origin Binding and Cryptographic Client Data Verification defines an industrial-grade behavioral standard for security engineering. Enforces strict canonical origin binding, relying party identifier (rpId) validation, and clientDataJSON cryptographic integrity checks during WebAuthn registration and authentication ceremonies. Neutralizes cross-subdomain passkey relays, TLS terminating proxy injection, challenge replays, and man-in-the-middle phishing vectors. Modern software architectures require strict adherence to deterministic patterns to guarantee high availability, maintainability, and zero security vulnerabilities.

Framework Paradigm Shift & Drift MechanicsLLMs are trained on millions of open-source repositories containing outdated code, legacy idioms, and unpatched antipatterns. When coding assistants generate implementations for this stack, they default to common statistical tokens: Permissive Subdomain Matching, Regex Origin Verification, or Unchecked clientDataJSON Hashes in WebAuthn Ceremonies Without an explicit system instruction file, developers spend hours debugging silent failures.
Failure Modes & Production Blast Radius

Hazard Analysis: What Breaks Without This Rule

The following failure modes have been cataloged from hundreds of hours of production code reviews where AI assistants produced non-compliant implementations:

Failure ModeAI Symptom (The Anti-Pattern)SeverityProduction Impact & Remedy
AI Hallucination & Deprecation DriftPermissive Subdomain Matching, Regex Origin Verification, or Unchecked clientDataJSON Hashes in WebAuthn CeremoniesCritical
Violating this industrial standard introduces regression bugs, security risks, and unexpected runtime failures in production.
Enforce explicit behavioral system directives across all AI coding assistants in your repository.
Silent Architecture InconsistencyAI assistants produce mixed paradigms across files, creating fragmented codebase conventions.Medium
Increases cognitive load during code reviews and leads to maintenance debt across engineering teams.
Pin project conventions in .cursor/rules, CLAUDE.md, and AGENTS.md so all team agents follow identical guardrails.
Architectural Directives in Detail

Step-by-Step Production Directives

Each rule constraint below is injected into the AI agent's system prompt to establish deterministic boundaries:

1

Engineers MUST ALWAYS match `clientDataJSON.origin` against an immutable, strictly defined allowlist of fully qualified origins (exact protocol, domain, and port without trailing slashes).

Engineers MUST ALWAYS match `clientDataJSON.origin` against an immutable, strictly defined allowlist of fully qualified origins (exact protocol, domain, and port without trailing slashes).

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
2

Engineers MUST NOT use `.includes()`, `RegExp` partial matching, or permissive wildcard patterns to evaluate WebAuthn origins, avoiding subdomain takeover relays.

Engineers MUST NOT use `.includes()`, `RegExp` partial matching, or permissive wildcard patterns to evaluate WebAuthn origins, avoiding subdomain takeover relays.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
3

Services MUST atomically consume the challenge nonce from transactional storage before signature verification to prevent replay attacks.

Services MUST atomically consume the challenge nonce from transactional storage before signature verification to prevent replay attacks.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
4

Services MUST verify that `authenticatorData` flags enforce User Presence (`UP = 1`) and, where required by policy, User Verification (`UV = 1`).

Services MUST verify that `authenticatorData` flags enforce User Presence (`UP = 1`) and, where required by policy, User Verification (`UV = 1`).

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
5

Code SHOULD rely on audited FIDO2-certified server libraries (such as `@simplewebauthn/server`) instead of ad-hoc custom WebAuthn signature parsers.

Code SHOULD rely on audited FIDO2-certified server libraries (such as `@simplewebauthn/server`) instead of ad-hoc custom WebAuthn signature parsers.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
6

Components NEVER accept the client-provided `rpId` dynamically from the incoming request payload without strict server-side validation against the environment configuration.

Components NEVER accept the client-provided `rpId` dynamically from the incoming request payload without strict server-side validation against the environment configuration.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
Technical Questions & Answers

Frequently Asked Technical Questions

Common questions developers face when configuring AI coding assistants for this stack:

Q:Why is WebAuthn Relying Party Origin Binding and Cryptographic Client Data Verification critical for AI coding assistants?

Enforces strict canonical origin binding, relying party identifier (rpId) validation, and clientDataJSON cryptographic integrity checks during WebAuthn registration and authentication ceremonies. Neutralizes cross-subdomain passkey relays, TLS terminating proxy injection, challenge replays, and man-in-the-middle phishing vectors. Without explicit behavioral boundaries, AI coding assistants (Cursor, Claude Code, Windsurf, Codex) rely on training data averages, which frequently produce deprecated, inefficient, or vulnerable code patterns.

Q:How does adopting this rule prevent AI hallucinations?

This rule explicitly declares what the AI must avoid (Permissive Subdomain Matching, Regex Origin Verification, or Unchecked clientDataJSON Hashes in WebAuthn Ceremonies) and prescribes verified positive examples. Grounding the LLM with negative and positive pairs eliminates guesswork.

Q:Which AI coding environments are supported?

This specification is multi-platform compatible: Cursor (.cursor/rules/*.mdc & .cursorrules), Anthropic Claude Code (CLAUDE.md), Windsurf (.windsurfrules), Codex / Cline (AGENTS.md), and GitHub Copilot (.github/copilot-instructions.md).

Q:Can I combine this rule with other technology stacks?

Yes. Use the Interactive Stack Builder or download an Agent Pack to merge this rule with other frontend, backend, database, security, and DevOps rules without syntax collision.

Open Specification · CC BY 4.0·Free for Personal, Team & Commercial In-Repo Use

Citation & Open Source Attribution Guidelines

This specification is licensed under Creative Commons Attribution 4.0 International (CC BY 4.0). You are completely free to adapt and share this rule in your workspace. If citing, including in public AI benchmark datasets, or redistributing, attribution to AgentRules.org is required.

1 Rule in Stack

WebAuthn