Page cover

hammer-brushCSS Injection to Data Exfiltration

What Is CSS Injection?

CSS Injection occurs when an attacker can inject arbitrary Cascading Style Sheets into a web page. This usually happens when:

  • User input is reflected inside <style> tags

  • User-controlled data is used in inline styles

  • Dynamic theming or customization features lack proper sanitization

circle-info

“CSS Can’t Steal Data”… Right?

CSS cannot directly read cookies, localStorage, or DOM content like JavaScript can. But it can:

  • Make conditional network requests

  • React to DOM state and attribute values

  • Leak information character by character

CSS as Side-Channel:

CSS supports features that allow it to:

  • Match elements based on attributes ([value^="a"])

  • Load external resources (background-image: url(...))

  • React to user interaction (:hover, :focus, :checked)

Combine these features to create side-channel leaks.

Selectors:

Selectors + Load external resources:

If the selector matches, the browser makes a request to attacker.com.

Demo:

This application loads a stylesheet from an external domain and applies it during rendering.

The goal is to exfiltrate the _csrf token from the application.

circle-info

Substring matching attribute selectors

Three additional attribute selectors are provided for matching substrings in the value of an attribute:

[att^=val]Represents an element with the att attribute whose value begins with the prefix "val". If "val" is the empty string then the selector does not represent anything.[

att$=val]Represents an element with the att attribute whose value ends with the suffix "val". If "val" is the empty string then the selector does not represent anything.

[att*=val]Represents an element with the att attribute whose value contains at least one instance of the substring "val". If "val" is the empty string then the selector does not represent anything.

Reference : https://www.w3.org/TR/selectors-3/#attribute-selectorsarrow-up-right

The first character can be obtained using this payload. To retrieve the remaining characters, additional payloads need to be created.

The first character triggers a request to /?q=N, which is confirmed by inspecting the page source.

This confirms that the CSRF token starts with N.

We Successfully exfilitrated the token from the application.

Last updated