GithubHelp home page GithubHelp logo

jbtronics / crookedstylesheets Goto Github PK

View Code? Open in Web Editor NEW
3.3K 106.0 138.0 161 KB

Webpage tracking only using CSS (and no JS)

License: MIT License

HTML 20.00% CSS 48.85% PHP 31.15%
css css-tricks html5 web-tracking proof-of-concept

crookedstylesheets's Introduction

Here you can find a demo of the code in this repository.

中文翻译: README.cn.md

Crooked Style Sheets

Proof of concept for website tracking/analytics using only CSS and without JavaScript.

What we can do with this method

We can gather some basic information about the user, like the screen resolution (when the browser is maximized) and which browser (or engine) is used.

Further, we can detect if a user clicks a link or hovers with the mouse over an element. This can be used to track which (external) links a user visits using the hover method. It should even be possible to track how the user moved their mouse (using an invisible table of fields in the page background). However, using my method it's only possible to track when a user visits a link or hovers over a field for the first time. Maybe it's possible to modify the method so that it is possible to track every click.

Furthermore, it is possible to detect if a user has installed a specific font. Based on this information, it should be possible to detect the user's OS, because different operating systems ship different fonts, such as "Calibri" on Windows.

How it works

General idea

In CSS you can add an image from an external resource using the url("foo.bar"); property. Interestingly, this resource is only loaded when it's needed (for example, when a link is clicked).

So, we can create a selector in CSS that calls a particular URL when the user clicks a link:

#link2:active::after {
    content: url("track.php?action=link2_clicked");
}

On the server side a PHP script saves the timestamp when the URL is called.

Browser detection

Browser detection is based on @supports Media-Query, and we check for some browser specific CSS property like -webkit-appearance:

@supports (-webkit-appearance:none) and (not (-ms-ime-align:auto)){
    #chrome_detect::after {
        content: url("track.php?action=browser_chrome");
    }
}

Font detection

For font detection a new font family is defined. Then, a text is tried to style with the font that should be checked if it exists. When the browser does not find the font on the user's system, the defined font is used as a fallback. When this happens, the browser tries to load the font and calls the tracking script on the server.

/** Font detection **/
@font-face {
    font-family: Font1;
    src: url("track.php?action=font1");
}

#font_detection1 {
    font-family: Calibri, Font1;
}

Measurement of hover duration

For hover duration method (based on an idea by jeyroik), we define new animation keyframes that will request a URL every time a new keyframe is requested:

@keyframes pulsate {
    0% {background-image: url("track.php?duration=00")}
    20% {background-image: url("track.php?duration=20")}
    40% {background-image: url("track.php?duration=40")}
    60% {background-image: url("track.php?duration=60")}
    80% {background-image: url("track.php?duration=80")}
    100% {background-image: url("track.php?duration=100")}
}

Then, we define that the keyframes should be used as animation for the div. There can we choose the duration of the animation, which is the maximum time we can measure:

#duration:hover::after {
    -moz-animation: pulsate 5s infinite;
    -webkit-animation: pulsate 5s infinite;
    /*animation: pulsate 5s infinite;*/
    animation-name: pulsate;
    animation-duration: 10s;
    content: url("track.php?duration=-1");
}

The resolution of the duration measurement can be increased, by inserting more steps into the keyframes set.

Input detection

To detect if a user checks a checkbox we use the :selected Selector provided by CSS:

#checkbox:checked {
    content: url("track.php?action=checkbox");
}

For detection of the string "test" we combine the HTML pattern attribute, which can be used to build some basic input validation. In combination with the :valid selector, the browser will request our tracking site when the regex pattern is matched by the input:

<input type="text" id="text_input" pattern="^test$" required>
#text_input:valid {
    background: green;
    background-image: url("track.php?action=text_input");
}

Demo (currently unavailable)

Here you can find a demo of the files in this repository. The index.html is the file that is being tracked using this method. Visit the results.php for the results of the tracking.

If nothing or a PHP warning appears after a property, it means that the value of this property is false, or that the user has not visited the page or link yet (yeah, it's a bit dirty, but you can see the principle of the method).

Also, resolution detection doesn't work so well yet, because I only have detection for the most used screen widths. Further, it is a bit tricky to detect the real screen height of the user, because CSS uses the height of the browser window and stuff like the system panel/task bar makes the browser area smaller than the monitor.

The demo website is currently unavailable.

What you can do to prevent tracking with this method

CSS Exfil Protection is an extension that protects against this vulnerability.

Another way is to disable CSS for a web page completely, you can do this via browser settings or with plugins like uMatrix (currently unmaintained), CSS Toggler (currently unmaintained), Stylus or uBlock. Disabling CSS will make almost every modern web page look very ugly and often unusable.

A better solution would be if browsers didn't load the external content (referenced in CSS) when it´s needed, but when the site is loaded. Then it would be impossible to detect individual actions. This modification to content loading could be implemented by the browsers themselves, or maybe by a plugin (similar to NoScript or uMatrix)

The problem is that this solution might have an impact on performance, because the browser has to load a lot of content on initial site loading (and the browser might not use the content at all).

crookedstylesheets's People

Contributors

35609902357 avatar andrewducker avatar fdmarcin avatar fengshangwuqi avatar fridzema avatar jbtronics avatar jwilk avatar nicoder avatar pixnbits avatar vhag avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

crookedstylesheets's Issues

Comma Abuse

I don't mean this to be snarky or mean - Please consider revising the README without the rampant abuse of commas. Nearly every sentence has an unneeded pause introduced by a comma and it makes fluidly reading through your fascinating notes somewhat more difficult.

Use invisible css grid to track mouse movements

What if you created an invisible css grid on top of your whole webpage and tracked mouse movement that way. (Sounds way easier and more enjoyable than wrapping everything separately in your markup somehow...

Other solution

An other solution would be to block the ability to load dynamic content like php file.

You can try to empty the buffer

我通过观察发现,并不是在能拿到第一次的内容,当过了10分钟后,依然能拿到,所以我认为 可以在缓冲区这上面下手。
1d5aacf2-a7de-45bb-b323-1224f4292cd3

Keylogger using webfont with single character unicode-range

Sure, again just a single request per unique character during page visit could be sent, but besides that it seems to work as expected:

<!doctype html>
<title>css keylogger</title>
<style>
@font-face { font-family: x; src: url(./log?a), local(Impact); unicode-range: U+61; }
@font-face { font-family: x; src: url(./log?b), local(Impact); unicode-range: U+62; }
@font-face { font-family: x; src: url(./log?c), local(Impact); unicode-range: U+63; }
@font-face { font-family: x; src: url(./log?d), local(Impact); unicode-range: U+64; }
input { font-family: x, 'Comic sans ms'; }
</style>
<input value="a">type `bcd` and watch network log

Older Browsers Immune?

Hello, neat CSS trick; it works great on newer browsers that support the CSS methods used. Older browser versions — I tested Firefox v50 and Opera v12 — respond to font tracking only, no other results show; other than that, the CSS on the test page works as expected; i.e., color changes appropriately, etc.

So this is not really a bug…but may be helpful as a mitigation method under the README's prevention section?

Remark regarding Tor Browser

So, disabling CSS is not a real option, except when you are very worried about your privacy (for example, when you are using the Tor browser, you should maybe disable CSS).

Actually not required because things like user agent, screen resolution, fonts, etc. are already normalized and should be more or less identical for all users of TBB.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.