demo · v150

@font-face modifiers

Web fonts are high-value targets for supply chain attacks — a CDN serving a compromised font file can silently swap letterforms. Chrome 150 extends @font-face src to accept integrity() and cross-origin() modifiers, letting the browser verify a font's SRI hash before rendering any text with it.

Note: This demo simulates the @font-face modifier API. Actual cross-origin font loading with SRI requires a server that sends CORS headers (Access-Control-Allow-Origin). The interactive panels below show the API patterns and hash-verification logic.

Without integrity()

The plain url() form fetches and renders the font with no hash check. A CDN can serve any bytes.

@font-face { font-family: 'HeaderFont'; src: url("https://cdn.example/font.woff2") format("woff2"); font-display: swap; }
no integrity check CDN can tamper

With integrity() + cross-origin()

Chrome 150: add integrity() and cross-origin(anonymous) modifiers inside url(). Browser rejects the font if the hash mismatches.

@font-face { font-family: 'HeaderFont'; src: url("https://cdn.example/font.woff2" cross-origin(anonymous) integrity("sha384-…hash…")) format("woff2"); font-display: swap; }
SRI verified tamper blocked

Hash Verification Simulator

Simulate what the browser does when it checks an integrity() hash against font bytes. Enter a hash or use the "Tamper" button to see how a mismatch is caught.

Font file:
integrity():
Click "Verify" to simulate the browser's integrity check.

cross-origin() + referrer-policy() for Fonts

Three common @font-face patterns — their modifier usage, cookie/credentials behaviour, and referrer impact:

Pattern CSS Credentials Referer sent SRI check
Same-origin font, no modifiers url("font.woff2") included full URL none
CDN font, anonymous CORS url("…" cross-origin(anonymous)) omitted full URL none
CDN font with SRI + no-referrer url("…" cross-origin(anonymous) integrity("sha384-…") referrer-policy(no-referrer)) omitted none sha384 hash
Auth CDN, credentialed url("…" cross-origin(use-credentials) integrity("sha384-…")) included full URL sha384 hash
/* Chrome 150: @font-face with integrity() and cross-origin() */
@font-face {
  font-family: 'SecureHeadline';

  /* One source per format, each with its own hash */
  src:
    url("https://cdn.example/headline.woff2"
        cross-origin(anonymous)
        integrity("sha384-LqcFhBbq5oaI7c5VzqAqp3mYc9b5qW0oPzUHsM8zSb4=")
        referrer-policy(strict-origin-when-cross-origin))
    format("woff2"),

    url("https://cdn.example/headline.woff"
        cross-origin(anonymous)
        integrity("sha256-F4RJjUiGqUfR0iSQ0qF5A5JQYP0h0eRgkgG3M9N5K8="))
    format("woff");

  font-display: swap;
}

/* Without integrity() — vulnerable to CDN tampering */
@font-face {
  font-family: 'UnsafeFont';
  src: url("https://cdn.example/font.woff2") format("woff2"); /* ← no hash check */
}

see also

implementation reference

Need the exact API surface, compatibility boundaries, errors, lifecycle, and source links? Read the matching gendn reference ↗