CSS fingerprinting
CSS fingerprinting is a browser fingerprinting technique that allows a website to identify and track visitors using Cascading Style Sheets (CSS). CSS fingerprinting is stateless, that is, it does not require the computer system running the browser to remember information. It leverages differences across browsers, or CSS queries that allow programmers to target different systems, to infer information about a user's system. Since CSS is typically allowed in areas where JavaScript code execution is disabled, such as in email clients, it has a larger reach than most browser fingerprinting techniques, which typically rely on JavaScript code.
Background
Browser fingerprinting is a set of techniques that leverage a browser's unique characteristics and features to track a user. Unlike stateful tracking through the use of cookies, browser fingerprinting collects small inconsistencies and quirks in a particular browser's behavior, which are often a function of the hardware the browser is being run on and configurations that are being used on the browser. These inconsistencies are used to build a unique identifier for a particular user.[1] Typically this process requires the use of JavaScript code which subsequently calls a variety of HTML 5 APIs to generate a unique identifier.[2][1] As a result of this, modern fingerprinting defenses limit the amount and types of JavaScript code that a website can run. In certain cases, extensions like NoScript outright disallow the execution of JavaScript code.[3]
CSS fingerprinting allows a website to fingerprint a user without executing any JavaScript code, thus bypassing traditional fingerprinting defenses. Since style sheets are typically allowed in user-generated content, even where script-based JavaScript execution was disallowed (such as email clients), CSS fingerprinting has a larger reach than traditional browser fingerprinting.[3]
Example
The following example demonstrates how CSS fingerprinting could be used to infer information about a user's browser configuration.
@media (max-width: 600px) {
body { background-image: url("https://example.com/log?device=mobile"); }
}
@media (min-width: 601px) and (max-width: 1200px) {
body { background-image: url("https://example.com/log?device=tablet"); }
}
@media (min-width: 1201px) {
body { background-image: url("https://example.com/log?screen=laptop"); }
}
In the example, a set of CSS directives are declared that use media queries, a feature of CSS that allows users to conditionally declare styling given the result of a query of a user's browser environment. The CSS directives apply different types of backgrounds on to the body element depending on the result of queries on the width of a user's screen. The background in turn makes a request to a remote URL for that background image, with the choice of image conveying information about the type of device. The remote URL can now collect information on which device was used based on which image was requested.[2]
Techniques
CSS fingerprinting techniques are typically dependent on abusing specific features of CSS to detect attributes about the system that CSS would typically not have access to. The process usually two parts, the initial access of the information and the subsequent exfiltration. While there are many ways of gaining access to data through CSS fingerprinting, exfiltrating it purely through CSS is difficult since the browser does not allow the dynamic generation of URLs in CSS. As a result, CSS fingerprinting typically relies on making a conditional of a networking request, for example using a background image on a CSS selector, a font retrieval on a media query or using a conditional image-set
directive.[3]
One particular method of CSS-based fingerprinting is font fingerprinting, which focuses on detecting the presence of specific fonts on a user's system. By revealing the presence of certain fonts on a user's system a website can infer whether certain applications have been installed by the user. This involves the website loading a font using the @font-face
CSS directive or directly loading a CSS font by applying the font-family directive to a HTML element. By subsequently timing the amount of time, the particular resource takes to load or by measuring the size of the element when the font-family directive is applied directly, a website can infer the presence of system fonts and other applications.[4] Another similar attack proposed by Heiderich et al. in 2017 centered around loading specially prepared fonts where a set of letters had been swapped out the glyphs for zero-width characters. Once these fonts have loaded, an attacker can apply these fonts on an element containing data they want to leak. Using a series of CSS animations and height/width queries, the attacker can infer the heights of the characters which are not zero-width characters making it possible to leak the data contained in the element character by character.[3][5]
Media queries are a set of CSS directives that allow a website to query different properties about a screen such as the height, width or whether if the user is in a printing interface. Media queries allow websites to conditionally apply CSS styles if a particular set of conditions are met.[2][6] Other techniques include, using CSS's in-built calc()
functionality to perform calculations that reveal the instruction set and precision of the underlying operating system and using CSS's @supports
queries to check if a particular CSS features is present in a browser, which can be used to reveal which specific browser version a user is using. Other features available to CSS include the list of available fonts, whether or not JavaScript was enabled, and scrollbar settings, particularly on MacOS.[2][3]
Another technique that can be used to fingerprint users is extension detection. Extension detection is a technique that uses CSS queries to determine the presence or absence of specific attributes and elements injected by browser extensions. Certain extensions, such as Wikiwand, modify web pages by injecting CSS stylesheets and additional elements to alter their behavior. An attacker can exploit this by setting up a website that employs CSS container queries to detect these modifications. By analyzing the results of these queries and comparing them against a precompiled database of extension fingerprints, an attacker can identify which extensions a user has installed. This information can allow the attacker to uniquely identify users based on their installed extensions.[3][7]
CSS fingerprinting techniques can also be used to dynamically exfiltrate user-interactions. An attacker can craft code to register a CSS selector that only gets activated when a user hovers over, click on, types a specific string into an input field, areas that might reveal contextual information about the page where the CSS was loaded. The CSS selector subsequently embed a background-image on an element that is not-visible to the user, thus exfiltrating this data to the attacker. Depending on the amount of CSS being loaded the malicious CSS could also be used as a keylogger that returns back a user's keystrokes into specific sensitive fields.[1]
References
- ^ a b c Heiderich, Mario; Niemietz, Marcus; Schuster, Felix; Holz, Thorsten; Schwenk, Jörg (2012-10-16). "Scriptless attacks: stealing the pie without touching the sill". Proceedings of the 2012 ACM conference on Computer and communications security. CCS '12. New York, NY, USA: Association for Computing Machinery: 760–771. doi:10.1145/2382196.2382276. ISBN 978-1-4503-1651-4.
- ^ a b c d Lin, Xu; Araujo, Frederico; Taylor, Teryl; Jang, Jiyong; Polakis, Jason (2023-05-01). "Fashion Faux Pas: Implicit Stylistic Fingerprints for Bypassing Browsers' Anti-Fingerprinting Defenses". IEEE Symposium of Security and Privacy. IEEE: 987–1004. doi:10.1109/SP46215.2023.10179437. ISBN 978-1-6654-9336-9.
- ^ a b c d e f Trampert, Leon; Weber, Daniel; Gerlach, Lukas; Rossow, Christian; Schwarz, Michael (2025-02-02). "Cascading Spy Sheets: Exploiting the Complexity of Modern CSS for Email and Browser Fingerprinting". NDSS Symposium. doi:10.60882/cispa.27194472.v3.
- ^ Fifield, David; Egelman, Serge (2015). Böhme, Rainer; Okamoto, Tatsuaki (eds.). "Fingerprinting Web Users Through Font Metrics". Financial Cryptography and Data Security. Berlin, Heidelberg: Springer: 107–124. doi:10.1007/978-3-662-47854-7_7. ISBN 978-3-662-47854-7.
- ^ Heiderich, M.; Niemietz, M.; Schuster, F.; Holz, T.; Schwenk, J. (2014-04-23). Desmet, Lieven; Johns, Martin; Livshits, Benjamin; Sabelfeld, Andrei (eds.). "Scriptless attacks: Stealing more pie without touching the sill". Journal of Computer Security. 22 (4): 567–599. doi:10.3233/JCS-130494.
- ^ Takei, Naoki; Saito, Takamichi; Takasu, Ko; Yamada, Tomotaka (2015-11-01). "Web Browser Fingerprinting Using Only Cascading Style Sheets". 2015 10th International Conference on Broadband and Wireless Computing, Communication and Applications (BWCCA). IEEE: 57–63. doi:10.1109/BWCCA.2015.105. ISBN 978-1-4673-8315-8.
- ^ Laperdrix, Pierre; Starov, Oleksii; Chen, Quan; Kapravelos, Alexandros; Nikiforakis, Nick (2021). "Fingerprinting in Style: Detecting Browser Extensions via Injected Style Sheets". USENIX Security Symposium: 2507–2524. ISBN 978-1-939133-24-3.