Skip to content

Cross origin authentication

Please refer to this page to know more about the Cross Origin Authentication.

Configuration

The configuration of the allowed domains can be done as follows.

config/packages/webauthn.yaml
webauthn:
    allowed_origins:
        - 'https://acme.com'
        - 'https://acme.fr'
        - 'android:apk-key-hash://your-app-hash'
        - 'ios:bundle-id://your.bundle.id'
    allow_subdomains: true

Info

Changed in v5.3.3: entries that are not URLs, such as android:apk-key-hash:<base64>, are compared verbatim with the origin sent by the client. Entries made of a host only are normalized to https://.

Ceremony origin pinning

Info

New in v5.4.0

The allow list is checked against the union of its entries: any origin it contains is accepted for any ceremony. Origins sharing a Relying Party ID rarely share a trust level though, and an assertion obtained on the lowest-trust one (an XSS on a marketing site, a customer-provisioned subdomain) is replayable against the highest-trust one.

Ceremony origin pinning closes that window. The options request records the origin it was served on next to the challenge, and the response is then required to come from that very origin:

config/packages/webauthn.yaml
webauthn:
    ceremony_origin_pinning: true

The option is the application-wide default of WebauthnAttestationVerifier::withCeremonyOriginPinning() and WebauthnAssertionVerifier::withCeremonyOriginPinning(), so a single endpoint can opt in or out. See the Verification Helpers page.

The check is additive: the allow list still runs first, so pinning only narrows what is accepted.

Warning

Pinning fails closed, which is why it is opt-in and defaults to false. A ceremony stored without an origin is rejected, which covers the options generated by a previous version of the bundle and still held in the cache during a deployment. Keep it disabled for native application facets (android:apk-key-hash:...) and for any flow whose options request and ceremony do not share an origin.

Choosing what to put in the allow list

  • List only the origins that share the trust level of the endpoint, and prefer several narrow lists, per controller or per verifier through the helpers, over a single broad one.
  • Keep allow_subdomains to false whenever a subdomain can be controlled by a third party (customer-provisioned hostnames, user content, staging hosts). An assertion obtained on such a subdomain would otherwise be accepted on the high-trust origin.

Top origin validation (cross-origin iframes)

When the ceremony runs in a cross-origin iframe, the client data contains the origin of the embedding page in a topOrigin field.

Danger

Changed in v5.3.4: such a response is rejected unless a top origin validator is configured. Applications that do not use iframes are not affected, as a same-origin ceremony carries no topOrigin.

Write a service implementing Webauthn\CeremonyStep\TopOriginValidator:

src/Security/MyTopOriginValidator.php
<?php

declare(strict_types=1);

namespace App\Security;

use Webauthn\CeremonyStep\TopOriginValidator;
use Webauthn\Exception\AuthenticatorResponseVerificationException;

final readonly class MyTopOriginValidator implements TopOriginValidator
{
    public function validate(string $topOrigin): void
    {
        $allowed = [
            'https://app.example.com',
            'https://dashboard.example.com',
        ];
        if (!in_array($topOrigin, $allowed, true)) {
            throw AuthenticatorResponseVerificationException::create(
                'The top origin is not allowed.'
            );
        }
    }
}

Then declare it with the top_origin_validator option:

config/packages/webauthn.yaml
webauthn:
    top_origin_validator: 'App\Security\MyTopOriginValidator'

Info

The option is an alias to your service. A service registered under the Webauthn\CeremonyStep\TopOriginValidator identifier, which autowiring does by default when a single implementation exists, is picked up without any configuration. The validator applies to both the creation and the request ceremonies.

See the pure PHP documentation for the built-in HostTopOriginValidator and more details.

Allowed origins endpoint

When the allowed_origins parameter is set, the path /.well-known/webauthn is enabled. This path returns a JSON object with allowed domains.