13 ms·
Crooked Style Sheeding – Webpage tracking using only CSS
- lozzo 9y agovery good. I wonder if somebody really needs this.
- petercooper 9y agoI'm surprised browsers wouldn't prefetch stuff like this given it's an easy performance win. Which would then also make these stats useless.
- jwilk 9y agoWhat's "sheeding"?
- jwilk 9y agoApparently a typo: https://github.com/jbtronics/CrookedStyleSheets/commit/c5d599f025f2222e077fce3d87afddbe5c4ee088 https://github.com/jbtronics/CrookedStyleSheets/commit/c5d59...
- Trufa 9y agoVery interesting, it's always intriguing to see how much of a cat and mouse game this privacy stuff is. I'm always thinking that this needs an overhaul and slightly different approach altogether, sadly I can't produce any viable solutions. With this huge and complex kind of issues I don't think we have to find one solution but rather point in the right direction, but I'm not even sure we're doing that.
- tqkxzugoaupvwqr 9y agoIn my opinion the new approach should be: Let websites deliver content and let the user’s website reader interpret the markup / content description and style the page according to the user’s preferences. Websites shouldn’t be able to style and script themselves any longer. The website should load more content when the user scrolled to the bottom? Let the website reader retrieve the content itself. The website wants to know the dimensions of the viewport to load the appropriately sized image or change the layout? Tough luck, this is none of the website’s business! Let the user’s website reader handle this.
- en-us 9y agoWell this is depressing.
- Angostura 9y agoWhose going to be first to make the 'I always browse the Web with CSS disabled' post?
- avian 9y agoA more interesting question would be if it is possible to disable the "dynamic" part of the CSS in any browser. Things like ":hover", ":active" that this proof of concept abuses and leave just the more benign static styling rules.
- Tepix 9y agoPerhaps preventing the loading of URLs in the dynamic parts would be enough?
- Klathmon 9y agoProbably not, you'd also need to disable a lot of other optimizations. For example, a browser will not load an image if it's set to `display: none` in CSS (at least not right away). That could be abused to then trigger the download when CSS changes without a URL needing to be on the CSS at any point.
- vnchr 9y agoBlind users can’t be seen.
- robin_reala 9y agoScreen readers interface with normal browsers, so JS and CSS will be loaded as per usual (unless the user has gone to the trouble of turning them off).
- shirian 9y agoOr, at least, disabling `url()` in CSS.
- 9y ago
- SimeVidas 9y agoBut how many users disable JavaScript in their browser to prevent tracking? And is the fact that a website can track all your clicks and mouse movements a privacy/security issue to begin with? Isn’t it by design that the website you’re visiting can track you?
- oneeyedpigeon 9y ago> by design By design, the web is a "1. send me the document <-> 2. here it is" transaction, not a series of many small notifications. By design, the url() property almost certainly wasn't intended to be dynamic. This is clearly 'bending the established rules' — cleverly, admittedly.
- dahart 9y ago> By design, the web is a "1. send me the document <-> 2. here it is" transaction, not a series of many small notifications. That was true in 1998, but most of the web has been turning, by design, into what you might call a series of many small notifications ever since then. Gmail's been doing it since 2004. Today, almost all large sites are running Google Analytics or something like it, which track everything this article discusses, and operates on constant micro transactions. All web apps are built on many small notifications, and many of them even use websockets which was explicitly, by design, built for streams of micro transactions. > By design, the url() property almost certainly wasn't intended to be dynamic. This is clearly 'bending the established rules' There was never a rule against, even if dynamic usage wasn't expected or imagined (which I find unlikely). CSS allows it, therefore it's allowed by design.
- kowdermeister 9y agoWishful thinking, but today the web is clearly, obviously not a simple document retrieval system. It's now an application platform regardless you like it or not.
- SimeVidas 9y agoThe `url()` function wasn’t intended for tracking, sure. But my point is that it doesn’t matter, since it is accepted that the website you’re on can track you to begin with. I don’t think anyone in the standards bodies is trying to prevent that.
- shove 9y agoReminds me of similar techniques that could be used several years ago to sniff browser history via a collection of a:visited rules.
- avian 9y ago> However using my method, its only possible to track, when a user visits a link the first time This suggests that browser history sniffing is still possible - as long as you make the user click the link (in contrast to the old a:visited method where this could be done with no user interaction)
- andrewmcwatters 9y agoAny part of a browser that can make a request can be used to do this sort of thing. Any part of a browser that can alter the view and its related DOM attributes can cause a user to interact with it and give up data involuntarily. Turn off JavaScript and CSS media queries can cause resources to load based on a number of parameters. Have canvas enabled and you can be fingerprinted. Use one browser over another and get feature detected. Anchor states give away browsing history. Hell even your IP address sacrifices privacy, and that's before the page gets rendered. So with that being said, if you're browsing the web, you're giving up information.
- kodablah 9y agoIf you're concerned as a user of a malicious site: * Link click tracking - So what, the site could route you through a server side proxy anyways * Hover tracking - Can track movements of course, but doesn't really help fingerprinting. This is still annoying though and not an easy fix * Media query - So what, user agent gives this away mostly anyways * Font checking - Can help fingerprinting...browsers need to start restricting this list better IMO (not familiar w/ current tech, but would hope we could get it down to OS-specific at the most) If you're concerned as a site owner that allows third party CSS: * You should have stopped allowing this a long time ago (good on you, Reddit [0] though things like this weren't one of the stated reasons) * You have your Content-Security-Policy header set anyways, right? Really though, is there an extension that has a checkbox that says "no interactive CSS URLs"? I might make one, though still figuring out how I might detect/squash such a thing. EDIT: I figure just blocking url() for content and @font-face.src would be a good compromise not to break all sorts of background images for now. 0 - https://www.reddit.com/r/modnews/comments/66q4is/the_web_redesign_css_and_mod_tools/ https://www.reddit.com/r/modnews/comments/66q4is/the_web_red...
- gsnedders 9y ago> * Media query - So what, user agent gives this away mostly anyways It doesn't; without media queries you can't detect thing like browser window size or screen pixel density. > * Font checking - Can help fingerprinting...browsers need to start restricting this list better IMO (not familiar w/ current tech, but would hope we could get it down to OS-specific at the most) There's a lot of trade-offs here. Plenty of people have fonts installed for various reasons (some because none of the system fonts cover a script they want, some because they're using fonts designed to mitigate some issues caused by dyslexia, etc.), and breaking it for those people would not be good.
- kodablah 9y ago> It doesn't; without media queries you can't detect thing like browser window size or screen pixel density. Sorry if I wasn't clear. I shouldn't have said media queries, I should have said "CSS property queries". What CSS properties you have doesn't leak any more than your UA I would guess. > There's a lot of trade-offs here [...] I'll take it as an option to have a strict subset (though would prefer it as opt-out to discourage font-list-based fingerprinting as a practice, though metric-based may never leave). With downloadable fonts, I don't really like the "script they want" excuse. For accessibility reasons, I am admittedly naive, but I would assume it would be a substitute for an existing font name. Unique font names per user seem unnecessary.
- asadlionpk 9y agoInteresting trick. But I think adBlockers block requests to entire tracking domains. So even css calls would be blocked?
- oneeyedpigeon 9y agoThat's a good point, if you're only concerned with tracking from a specific set of domains.
- AntonyGarand 9y agoNot if you're hosting your own tracking information, on your own domain
- ppeetteerr 9y agoMost trackers are built by third parties. This is true for analytics tracking and for ad tracking. Few companies ought to track their own impressions for many, many reasons.
- beckler 9y agohonestly, I don't care if you use your own tracking solution on your own domain, as long as it's not passing the data to a third-party. I get that some of that data is genuinely useful in determining what parts of an app are popular and what is not. Even though I don't like being tracked for dumb shit like ads, it does have valid uses.
- cheschire 9y agoIt’s pretty trivial to make server side calls to google analytics [0] passing lots of different data using async commands so the user doesn’t even feel the hit. Additionally you could queue these stats messages and send in bulk when your server load falls below a certain threshold. I’m not talking hours, just seconds. Like a workflow engine. 0: https://developers.google.com/analytics/solutions/experiments-server-side https://developers.google.com/analytics/solutions/experiment...
- flukus 9y agoWhy do you think it's mostly advertisers building CDN's? It's not because they really wanted to make the web faster. These are typically let through by ad blockers.
- JepZ 9y agoWow, CSS is the new JS :D
- bradyholt 9y agoNice POC! I love the project name :)
- nukeop 9y agoThe obvious solution is to block the server-side pages that the CSS elements link to. This kind of tracking can be mitigated the same way any other kind of tracking is already handled by uBlock or uMatrix.
- supermdguy 9y agoWouldn't that require a separate blacklist for each site?
- nukeop 9y agoProbably not everyone would be willing to create their own user tracking solutions, most websites use third party analytics, which can be handled by generalized rules. For those that do roll their own solutions, per-website block lists would be needed, but that's how site-specific adblocking already works. The lists are maintained by the community and updated very frequently.
- supermdguy 9y agoOh, that's true. I wasn't really thinking about third party solutions.
- ams6110 9y agouBlock and a hosts file are standard on every computer I own.
- kalcode 9y agouBlock can't block manual tracking...just third-party scripts that do it. Example: You visit example-site.com example-site.com is the php server that sends you the html. It also the site that does the tracking. So when you click something it sends that data to example-site.com and then it can forward the data to a third-party tracking service. If you blocked or used host files on the server-side pages then the site example-site.com would be completely blocked too. Ultimately if everyone uses ad-blocks to block tracking script they can be added to the back end. If you block the back-end you effectively block the website you are accessing in the first place.
- expertentipp 9y agoThis is where the talent, funds, and resources will go as ads and marketing are industries with lots of funding available. Even more tracking and of even more pervasive kind. We hate tracking while we bet our time and money on it. The web is cancelled, go back home everyone.
- keypress 9y agoHow does 'check spelling as you type' work, via a dictionary that is previously downloaded, or is this an online service that leaks all/or some of your key presses?
- deleted 9y ago[deleted]
- Tepix 9y agoDo browsers really need to allow fetching URLs in the "after" event of a link?
- flooq 9y agoIt's not after event, the "after" is for inserting a pseudo-element. That then sits inside the original link element and hits the tracking URL by trying to load a resource from it when the link is active.
- korzun 9y agoWhat is the actual use case here? We can track the links without JS or CSS. Font checking doesn't solve any problems, etc.
- Raphmedia 9y agoAlright lads, let's all go back to RSS feeds and scrap that whole "browser" experiment.
- kowdermeister 9y agoI'd suggest telex, your downloaded content is automatically backed up on paper. :)
- tqkxzugoaupvwqr 9y agoI seriously think we need an alternative to HTML that axes styling and scripting and concentrates solely on the markup / content description. Websites would use a certain set of elements/descriptors to describe the content they contain. The user’s website reader would parse the markup / content description and display a page how it thinks it should be displayed (according to the user’s preferences). All websites would have the same styling – the one chosen by the user. This HTML alternative could provide an API that makes it possible to have dynamic websites but still prevents scripting and fingerprinting.
- Crespyl 9y agoSomething like a schema for a restricted subset of XHTML?
- aendruk 9y agoA nice start would be browser support for Content-Type: text/markdown.
- farnsworthy 9y agoSounds like HTML, and a browser. (Sad.) Perhaps Firefox's Reader View would be suitable, when activated.
- j_s 9y agoAgainst an Increasingly User-Hostile Web | https://news.ycombinator.com/item?id=15611122 https://news.ycombinator.com/item?id=15611122 (2017Nov:1307 points, 502 comments) #oneofus https://hn.algolia.com/?query=13226170&type=comment https://hn.algolia.com/?query=13226170&type=comment (click a 'comments' link on the search results, then 'parent') I've connected similar sentiment here for about a year now; I've appreciated mention of several helpful tools in this thread.
- mistersquid 9y agoAt least in Safari 11.0.2 (macOS 10.12.6) link tracking does not work. The selector #link2:active::after appears to always exist in Safari 11.0.2 ("active" is being disregarded). I clicked on none of those links, I have never visited google.de, but results.php page told me all 3 links had been clicked. EDIT: formatting, remove word.
- akvadrako 9y agoYou should let somebody know: http://bugreport.apple.com http://bugreport.apple.com The demo site correctly tracks me in Safari 11.0.1 (macOS 10.13.1)
- throwawazqq 9y agoA lot of css is fluff masking low information content. Turning off css helps me not have to page down x times to see a noncathartic one-liner.
- talmand 9y agoThis is an interesting concept, but I'm not seeing anything that couldn't already be done with a properly set up website and server logging. Things like "@supports (-webkit-appearance:none)" doesn't give you chrome detection. It gives you webkit detection, which is a rather large subset of the whole. Plus some of the other browsers started supporting webkit prefixes.
- claar 9y ago> doesn't give you chrome detection Checking every possible prefix should distinguish most versions of most rendering engines -- still not bad.
- talmand 9y agoIt would only, at best, give you outdated browser versions. Unless you are going to create a huge set of rules checking certain properties against other properties. Plus it doesn't tell you which browser, only maybe which webkit engine version. Which tells you next to nothing.
- globuous 9y agoVery smart! This is a few line of code away from a css class based mini tracking framework... Aside from the obvious, this could also be used as a fallback (restricted) A/B testing for no js users ? I'm thinking data about just what was hovered, clicked, and media query allows for some basic UI testing of responsive websites.
- rhn_mk1 9y agoIs there a way to turn off CSS media queries in Firefox, or fake their conditions? Apart from the security issues, it's plain annoying when the page layout will change completely because a few pixels of window size are missing for the perfect experience.
- chatmasta 9y agoI don't see what's problematic about this. The tracking is not really done in CSS, so much as on the server. You could accomplish the same thing with 1x1 images, or loading any remote resource. Effectively the only difference is you're loading the URL conditionally via CSS, as opposed to within a `<script>` or `<img>` tag. Furthermore, this can be blocked in the same way as any tracking URL. I concede this is a novel way of fingerprinting the browser from within the client, without using JS. However, I think a better way to describe this would be "initiating tracking on the frontend without the use of javascript."
- Osmose 9y agoThe difference is that CSS can trigger remote resource loads in response to post-pageload user behavior, which intuitively seems like a JS-only thing. For example, tracking where the mouse has moved, as mentioned in the readme. I wouldn't say it's some sudden, alarming capability, but it is distinctly more capable than <img> tags.
- AgentME 9y agoThis stuff is relevant for sites that allow users to upload CSS to be used by other people. If I can make a subreddit or a social media page on a site and upload custom CSS for it, then I can make the CSS trigger requests to my own personal server on certain events and track the people who visit my subreddit/page. (Reddit adds certain restrictions to CSS that can be uploaded to it to defend against this.)
- runeks 9y agoThink about people using extensions like NoScript to block JS because it offers this functionality. This is fairly relevant to these people, as they clearly also need a “NoCSS” extension.
- madez 9y agoThe demo shows that this technique doesn't work for "Privacy Browser" on Android. It can be obtained from F-Droid.
- secdewd11 9y agoThis doesn’t mention my personally favorite css tracking trick, timing attacks that can be used to detect what sites you have loaded. This can be done by interweaving requests to a remote URL (say background-image) with requests to your server script, which times these differences.
- ubernostrum 9y agoThe fanciest tracking trick is the HSTS supercookie. You use a bunch of subdomains -- a.example.com, b.example.com, etc. -- each configured so that a particular URL (call it the 'set' URL) sends an HSTS header. A different URL (the 'get' URL) doesn't. You generate an ID for the user, and encode it as a bit pattern using the subdomains to indicate positions of '1' digits. Say your ID is 101001 -- you serve a page which includes images loaded from the 'set' URLs for subdomains a, c, and f. On later page loads, you serve a page including images loaded from the 'get' URLs of every subdomain, and you pay attention to which ones are requested via HTTPS. Since the 'set' URL sent an HSTS header, subdomains a, c, and f get requested over HTTPS, and now you reconstruct the ID from that: 101001.
- j_s 9y ago> The fanciest tracking trick is I feel like this changes all the time; I was recently surprised to discover 'TLS Client Channel ID' (my nomenclature is a bit fuzzy - an RFC for automatic client certs "for security") and would love to learn more about the extent of its current implementation in Chrome. https://news.ycombinator.com/item?id=15753648 https://news.ycombinator.com/item?id=15753648 >londons_explore: In Chrome, it also uses the TLS Client Channel ID, which is a persistent unique identifier established between a browser and a server which (on capable platforms) is derived from a key stored in a hardware security module, making it hard to steal. Ie. if you clone the hard drive of a computer, when you use the clone, Google will know you are a suspicious person, even though you have all the right cookies. https://en.wikipedia.org/wiki/Transport_Layer_Security_Channel_ID https://en.wikipedia.org/wiki/Transport_Layer_Security_Chann... http://www.browserauth.net/channel-bound-cookies http://www.browserauth.net/channel-bound-cookies
- EldonMcGuinness 9y agoCall me naive but, as a dev, I don't see why this would be any better than using JS. The group of people that block JS is likely to do the same for this and, as mentioned by others, common sources of such mucking are blocked by a good ad blocker. Then, there is the whole, "how could it be integrated into an existing site with minimal fuss" issue. With JS you can specify targets and the like for actions and observations, the only comparable thing would be to offer sass / less integration so that it works with clients that disable or block JS, which is arguably much more difficult. While it is definitely clever, I just don't see a practical use for it. It would really only benefit those willing to put the work into using it and only work so long as their logging URL is available and not blocked. I just don't see the real value.
- r3bl 9y agoDoes it need to be practical? It's just a proof of concept, as is displayed in the very first sentence in the README file. This seems to me more like "wow, something cool has been done in an unusual way" material, rather than "this is something you should consider using".
- john-aj 9y agoThis could easily be stopped by a change in browser behavior. If web browsers downloaded contacted every address specified with `url()` automatically on page load, without considering the conditions, this type of conditional requests would be impossible. Conceivably, you could solve it through a simple browser extension that looks through all of the page’s stylesheets and calls all URLs present in the CSS before the page is rendered. In an ideal implementation, though, URLs dependant on “static”, non-identifiable conditions, such as an image with `display: none`, would be left alone.
- fixermark 9y agoThat's likely to have unfortunate performance implications, particularly on mobile or low-bandwidth connections.
- Quagga 9y agoI think it is time to split the web into: * user and machine readable content (text with hyperlinks, pictures, audio, video, rest) * universal app store (javascript, css, intents, permissions...) Every user could consume or style content as he wishes. If my IDE has dark theme, I want all web pages to have dark theme. Why do I need javascript to read news or browse pictures. If user wants to installs app from app store he should accept software license and give permissions to that application.
- Someone 9y ago”Interesting is, that this resource is only loaded when it is needed (for example when a link is clicked).” The resource is retrieved using GET, so I wouldn’t think that is required by the http standard. If so, browsers can mitigate this kind of attack by pre-fetching these resources (even pre-fetching a fraction at random already might be enough) It is a neat hack, though.
- daxaxelrod 9y agoTracking seems to only really be server side. The css just dispatches requests with qs params. Probably not an ideal production tracking solution as it severely limits the data you can send back for better analytics
- antibland 9y agoAbout 8 years ago, a colleague and I interviewed a nervous kid fresh from undergrad. He was applying for a junior front-end position at our fast-growing startup. Dressed in a shiny, double-breasted suit and wingtip shoes, he followed us into a tiny office (space was so limited) where we conducted interviews. "Tell us about your CSS experience," we asked him. "Ah, yes. I, well, haha, of course. The CSS is where you make your calls, to the database, ah, server, ah, of course." Unsurprisingly, we did not hire the applicant, though his answer to our question lived on in infamy for many years. But all that changed, today, reading this. The joke was on us. That kid was clearly from a future of which we had no awareness. Starting today, I'll always trust programmer applicants donning double-breasted suits.