This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
securitycritical PriorityID: webauthn-l3-hybrid-transport-attestation-validation

WebAuthn Level 3 Hybrid Transport Attestation and Proximity Validation

Enforces strict validation of WebAuthn Level 3 hybrid transport (caBLE) parameters and authenticators during passkey registration and cross-device assertions. Prevents cross-device passkey relay attacks and adversary-in-the-middle (AiTM) exploitation by cryptographically binding origin, RP ID, client data hash, and proximity-bound hybrid transport hints at identity verification boundaries.

Prohibited Anti-Pattern: Trusting Client-Reported Transports Without Origin Pinning, Nonce Verification, or Hybrid Transport Validation

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: WebAuthn Level 3 Hybrid Transport Attestation and Proximity Validation - Enforces strict validation of WebAuthn Level 3 hybrid transport (caBLE) parameters and authenticators during passkey registration and cross-device assertions. Prevents cross-device passkey relay attacks and adversary-in-the-middle (AiTM) exploitation by cryptographically binding origin, RP ID, client data hash, and proximity-bound hybrid transport hints at identity verification boundaries.
globs: src/auth/**/*.{ts,tsx}, src/server/auth/**/*.{ts,tsx}, src/services/identity/**/*.{ts,tsx}, src/api/webauthn/**/*.{ts,tsx}
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/webauthn-l3-hybrid-transport-attestation-validation"
---

# WebAuthn Level 3 Hybrid Transport Attestation and Proximity Validation

> **Severity**: CRITICAL | **Category**: security
> **Anti-Pattern Warning**: Trusting Client-Reported Transports Without Origin Pinning, Nonce Verification, or Hybrid Transport Validation

## System Constraints
You are a Principal Security Architect enforcing FIDO2/WebAuthn Level 3 specifications. You must reject any WebAuthn registration or authentication implementation that does not strictly validate the clientDataJSON, cryptographic challenge replay protection, RP ID hashing, user verification (UV) flags, and authenticator transport enumerations for hybrid cross-device flows.

## Strict Guidelines
- Engineers MUST ALWAYS verify that clientDataJSON.type corresponds strictly to 'webauthn.create' (registration) or 'webauthn.get' (assertion) and matches the exact challenge generated server-side within the active session TTL.
- Engineers MUST ALWAYS validate that clientDataJSON.origin matches the fully qualified, scheme-enforced relying party origin (preventing AiTM proxying and reverse proxy spoofing).
- Services MUST verify the SHA-256 hash of the RP ID against the authenticatorData rpIdHash bytes and NEVER accept an arbitrary or unhashed RP ID string from the client.
- Engineers MUST ensure that when 'hybrid' transport is declared in response.response.getTransports() or attestation statements, user verification (UV flag in authenticatorData) is asserted (uv = 1) if elevated step-up or proximity guarantees are required.
- Services MUST persistently store authenticators' supported transports alongside the credential ID and reject cross-device hybrid assertions if the credential was explicitly registered under internal/platform-only boundaries without hybrid support.
- Components NEVER store or reuse challenges across authentication attempts; every challenge MUST be single-use, cryptographically pseudorandom (minimum 32 bytes), and bound to the ephemeral session context.

## Bad vs Good Implementations
### Flawed WebAuthn Assertion Verification (Relay Vulnerable)

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Fails to enforce origin validation, does not compute rpIdHash over authenticatorData, fails to inspect User Verification (UV) flags, omits hybrid transport validation, and leaves the door open to AiTM passkey relay attacks.
```typescript
import { Request, Response } from 'express';

interface StoredChallenge {
  challenge: string;
}

export async function verifyAssertion(req: Request, res: Response, userSession: { challenge?: string }) {
  const { id, rawId, response } = req.body;

  // BAD: Parsing clientDataJSON without validating the expected origin or exact challenge equality
  const clientData = JSON.parse(Buffer.from(response.clientDataJSON, 'base64url').toString('utf8'));

  if (clientData.type !== 'webauthn.get') {
    return res.status(400).json({ error: 'Invalid operation' });
  }

  // BAD: Challenge comparison without constant-time check or single-use consumption
  if (clientData.challenge !== userSession.challenge) {
    return res.status(401).json({ error: 'Challenge mismatch' });
  }

  // BAD: Ignoring transports, authenticatorData flags (UV/UP), and rpIdHash binding
  // Allows relay attacks across disparate origins and proxies
  return res.status(200).json({ status: 'authenticated', credentialId: id });
}
```

#### Production Standard (Correct)
> **Standard**: Implements full Level 3 invariant checks: single-use challenge consumption with constant-time comparison, strict origin pinning, SHA-256 RP ID validation, strict User Verification (UV) checking, and cross-device hybrid transport profile enforcement.
```typescript
import { Request, Response } from 'express';
import crypto from 'node:crypto';

interface ValidatedCredential {
  credentialId: string;
  userId: string;
  publicKey: Buffer;
  transports: AuthenticatorTransport[];
}

const EXPECTED_RP_ID = 'auth.internal.enterprise.com';
const EXPECTED_ORIGIN = 'https://auth.internal.enterprise.com';

export async function verifyAssertionProduction(
  req: Request,
  res: Response,
  consumeSessionChallenge: (req: Request) => Promise<string | null>,
  lookupCredential: (id: string) => Promise<ValidatedCredential | null>
) {
  const expectedChallenge = await consumeSessionChallenge(req);
  if (!expectedChallenge) {
    return res.status(401).json({ error: 'Missing or expired challenge.' });
  }

  const { id, response } = req.body;
  const clientDataJSON = Buffer.from(response.clientDataJSON, 'base64url');
  const clientData = JSON.parse(clientDataJSON.toString('utf8'));

  // 1. Validate operation type and cryptographically compare single-use challenge
  if (clientData.type !== 'webauthn.get') {
    return res.status(400).json({ error: 'Invalid clientData type' });
  }

  const challengeMatches = crypto.timingSafeEqual(
    Buffer.from(clientData.challenge),
    Buffer.from(expectedChallenge)
  );
  if (!challengeMatches) {
    return res.status(401).json({ error: 'Challenge mismatch or expired' });
  }

  // 2. Validate Origin boundary
  if (clientData.origin !== EXPECTED_ORIGIN) {
    return res.status(403).json({ error: 'Origin mismatch: Possible AiTM relay' });
  }

  // 3. Authenticator Data parsing and verification
  const authData = Buffer.from(response.authenticatorData, 'base64url');
  if (authData.length < 37) {
    return res.status(400).json({ error: 'Malformed authenticatorData' });
  }

  const rpIdHash = authData.subarray(0, 32);
  const expectedRpIdHash = crypto.createHash('sha256').update(EXPECTED_RP_ID).digest();
  if (!crypto.timingSafeEqual(rpIdHash, expectedRpIdHash)) {
    return res.status(403).json({ error: 'rpIdHash mismatch: Scope boundary violated' });
  }

  const flags = authData[32];
  const upFlag = (flags & 0x01) !== 0; // User Present
  const uvFlag = (flags & 0x04) !== 0; // User Verified

  if (!upFlag || !uvFlag) {
    return res.status(403).json({ error: 'User Presence and User Verification (UV) are mandatory' });
  }

  // 4. Hybrid Transport Binding Guardrail
  const clientTransports: AuthenticatorTransport[] = response.transports || [];
  const credential = await lookupCredential(id);
  if (!credential) {
    return res.status(404).json({ error: 'Credential not found' });
  }

  if (clientTransports.includes('hybrid') && !credential.transports.includes('hybrid')) {
    // Log security telemetry: potential cross-device relay of platform-bound credential
    return res.status(403).json({ error: 'Hybrid transport not permitted for registered credential profile' });
  }

  return res.status(200).json({ status: 'authenticated', credentialId: id });
}
```

Architectural Specification & Invariant Rationale

Architectural Invariant Design: WebAuthn Level 3 Hybrid Transport Attestation and Proximity Validation

WebAuthn Level 3 Hybrid Transport Attestation and Proximity Validation defines an industrial-grade behavioral standard for security engineering. Enforces strict validation of WebAuthn Level 3 hybrid transport (caBLE) parameters and authenticators during passkey registration and cross-device assertions. Prevents cross-device passkey relay attacks and adversary-in-the-middle (AiTM) exploitation by cryptographically binding origin, RP ID, client data hash, and proximity-bound hybrid transport hints at identity verification boundaries. 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: Trusting Client-Reported Transports Without Origin Pinning, Nonce Verification, or Hybrid Transport Validation 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 DriftTrusting Client-Reported Transports Without Origin Pinning, Nonce Verification, or Hybrid Transport ValidationCritical
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 verify that clientDataJSON.type corresponds strictly to 'webauthn.create' (registration) or 'webauthn.get' (assertion) and matches the exact challenge generated server-side within the active session TTL.

Engineers MUST ALWAYS verify that clientDataJSON.type corresponds strictly to 'webauthn.create' (registration) or 'webauthn.get' (assertion) and matches the exact challenge generated server-side within the active session TTL.

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 ALWAYS validate that clientDataJSON.origin matches the fully qualified, scheme-enforced relying party origin (preventing AiTM proxying and reverse proxy spoofing).

Engineers MUST ALWAYS validate that clientDataJSON.origin matches the fully qualified, scheme-enforced relying party origin (preventing AiTM proxying and reverse proxy spoofing).

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 verify the SHA-256 hash of the RP ID against the authenticatorData rpIdHash bytes and NEVER accept an arbitrary or unhashed RP ID string from the client.

Services MUST verify the SHA-256 hash of the RP ID against the authenticatorData rpIdHash bytes and NEVER accept an arbitrary or unhashed RP ID string from the client.

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

Engineers MUST ensure that when 'hybrid' transport is declared in response.response.getTransports() or attestation statements, user verification (UV flag in authenticatorData) is asserted (uv = 1) if elevated step-up or proximity guarantees are required.

Engineers MUST ensure that when 'hybrid' transport is declared in response.response.getTransports() or attestation statements, user verification (UV flag in authenticatorData) is asserted (uv = 1) if elevated step-up or proximity guarantees are required.

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

Services MUST persistently store authenticators' supported transports alongside the credential ID and reject cross-device hybrid assertions if the credential was explicitly registered under internal/platform-only boundaries without hybrid support.

Services MUST persistently store authenticators' supported transports alongside the credential ID and reject cross-device hybrid assertions if the credential was explicitly registered under internal/platform-only boundaries without hybrid support.

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 store or reuse challenges across authentication attempts

Components NEVER store or reuse challenges across authentication attempts; every challenge MUST be single-use, cryptographically pseudorandom (minimum 32 bytes), and bound to the ephemeral session context.

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 Level 3 Hybrid Transport Attestation and Proximity Validation critical for AI coding assistants?

Enforces strict validation of WebAuthn Level 3 hybrid transport (caBLE) parameters and authenticators during passkey registration and cross-device assertions. Prevents cross-device passkey relay attacks and adversary-in-the-middle (AiTM) exploitation by cryptographically binding origin, RP ID, client data hash, and proximity-bound hybrid transport hints at identity verification boundaries. 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 (Trusting Client-Reported Transports Without Origin Pinning, Nonce Verification, or Hybrid Transport Validation) 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