CSS Tricks

CSS Tricks

October 1, 2020
Abuse CSS
Category Attack
Defenses Framing Protections

CSS Tricks #

CSS can be used to trick a user into exposing information such as embedded pixel values by making visual changes that are affected by the embed.

Retrieving user’s history #

Using the CSS :visited selector, it’s possible to apply a different style for URLs that have been visited.
Previously it was possible to use getComputedStyle() to detect this difference, but now browsers prevent this by always returing values as if the link was visted and limiting what styles can be applyed using the selector. 1
So, it may be needed to trick the user into clicking an area that the CSS has affected. This can be done using mix-blend-mode. 2
There are also ways to do it without user interaction such as by abusing render timings. This works because it takes time to paint links a different color. 3
A PoC was provided on a chromium report that works by using multiple links to increase the time difference. 4

info

[^leak-1] shows an example of this attack using a whack a mole game to trick the user into clicking areas of the page. Multiple bugs were reported about this issue: ^bug-1, ^bug-2, ^bug-3

Evil Captcha #

Using CSS, it’s possible to take an embed out of context.
An example of this is pretending it’s a captcha as seen in 5
This works by setting the width and hight of an embed so that only the target characters are shown, this may use multiple embeds to change the order of the characters being displayed so that its harder for a user to know what infomation they’re providing.

Abusing autocomplete #

If a website uses text inputs and does not opt-out of autocomplete using autocomplete="off" it may be possible to leak data such as email addresses by tricking the user into pressing the keys to navigate the autocomplete UI for a javascript focused text input. For Chrome, this requires the user to be tricked into pressing the Up or Down arrow key which opens the dialog and selects a value, then by pressing Enter or Tab the value gets inserted into the page.

let input = document.createElement("input");
input.type = "email";
input.autocomplete = "email";
input.name = "email";
input.size = "1";
input.style = "position:absolute;right:-500px;bottom:-21.9px";
input.onkeypress = e => {
    e.preventDefault();
}
window.onmousedown = e => {
    // ignore mouse clicks
    e.preventDefault();
}
input.onchange = e => {
    alert(e.srcElement.value);
    e.srcElement.value = "";
}
document.body.appendChild(input);
setInterval(() => {
    input.focus({preventScroll: true});
}, 1000);

Custom cursor #

A custom cursor might not leak data directly but it may help trick the user, as a large cursor may overlay the autocomplete dialog and other native UI.

<style>
:root {
  cursor: url('https://www.google.com/favicon.ico'), auto;
}
</style>

Defense #

XFO prevents embeds from being attacked because there’s no visual difference as the content does not get shown. The Retrieving user’s history attack can only be prevented by the user. This can be done by disabling the browser history, or if on Firefox, by setting the option layout.css.visited_links_enabled to false in about:config panel.

SameSite Cookies (Lax)COOPFraming ProtectionsIsolation Policies
✔️

References #


  1. Privacy and the :visited selector, link ↩︎

  2. CSS mix-blend-mode is bad for your browsing history, link ↩︎

  3. Pixel Perfect Timing Attacks with HTML5, link ↩︎

  4. Visited links can be detected via redraw timing, link ↩︎

  5. The Human Side Channel, link ↩︎