Hacker News new | past | comments | ask | show | jobs | submit login
A timing attack with CSS selectors and JavaScript (sheddow.xyz)
104 points by mhasbini on Oct 7, 2018 | hide | past | favorite | 38 comments



> Have you ever encountered a website that runs jQuery(location.hash)?

No. Actually I have never seen a website do that. What sites do that? What is the actual use of grabbing an element that has an ID that matches the URL hash?

And this attack will only work on those sites.

This is just one more variation of the best practice: don't trust user/client supplied data.

Edit: Though academically I actually find how this was implemented to be really interesting. I'm just not sure what uses it would have in the wild.


> What is the actual use of grabbing an element that has an ID that matches the URL hash

Well normally when you load such a page the browser will scroll down to that element. Perhaps this JavaScript wants to do something like highlight the section or extract the heading to send to some analytics?


I use it for linking to comments on my site. Users can copy a link to a particular comment, and the link directs people to the appropriate topic and location on the page.

I'm assuming that using X-Frame-Options to prevent the page from appearing in a frame prevents this type of attack.


> I use it for linking to comments on my site. Users can copy a link to a particular comment, and the link directs people to the appropriate topic and location on the page.

That works out of the box, it's a native HTML/browser feature.

Why do you pass location.hash to jQuery?


Sometimes, due to your in-page navigation or some other fixed position element, you need to actually scroll to a point before the actual element, so that it doesn’t get covered. The native behavior would not give it the lead space and you’d see some of the element’s content covered by a static element.

In scenarios where you can’t redesign the html structure or css to give the element more padding, you pretty much have to use javascript to get the window-x position of the element.


Oh, my mistake, it's been a while since I wrote the code. I use it to style the linked comment. So, the browser automatically scrolls to the appropriate location, and then jQuery adds a style to that comment so the user can easily locate it, or refind it if they scroll up and down the page.


In modern browsers, you can sometimes achieve this effect with `:target`. (https://developer.mozilla.org/en-US/docs/Web/CSS/:target)


I’m not 100% sure but the first thought I had when reading it are the SPA routers that start with # by default?

I only read it on my phone without following along but if that’s the case then the text seems to hint at potentially brute forcing the authentication tokens? At least judging from the variable names.


Yes, it happens. It happens enough that jquery has fixed several times previous bugs that let you get immediate xss out of this. But yea, devs still need to also validate their input.


> What is the actual use of grabbing an element that has an ID that matches the URL hash?

Ha! Browsers do that by default. On page load, they scroll to an anchor tag with the id of the URL fragment.

I could imagine some JS-driven dynamic loading/scrolling using the same convention.


Browser do it based on name="" on anchor tags not ID. And if you are implementing your own version you should probably also be using name not ID. Best practice is t use JS to progressively enhance the page not reinvent the wheel so name is the logical choice.

Edit: Also, word of advise. Lose the "Ha!"... it could potentially make your comment come across as arrogant.

Edit 2: Leaving my original comment intact even though I was wrong. Apparently my knowledge is out of date on this one. Thank you "re" for correcting me.


> Browser do it based on name="" on anchor tags not ID

Fragment identifiers can refer to elements by ID; this has been supported by browsers for over a decade and is the preferred way to specify a target: https://www.w3.org/TR/html4/struct/links.html#h-12.2.3

In fact, `<a name="">` is now considered obsolete: https://www.w3.org/TR/html5/obsolete.html#obsolete


Thank you. That is good to know. I really appreciate this info and the links. I'll file it under "things I learned 20 years ago that are now obsolete :("


I don't understand the point of this. What elements will a timing attack work against that you can't read the value from directly? I didn't notice any discussion of this in the article.

Edit: I see how this works. It will allow you to exfiltrate data from 3rd party websites that pass the URL hash into jQuery. An interesting idea but limited in scope.


I still don't get it.

How are you getting a successful request and a page render for the 3rd party site, but not able to query the 3rd party DOM?

If you phished someone, there's probably better things you can do to lead to a fuller compromise.


It's described right in the article: embed the victim page in an iframe. Because of the same-origin policy you shouldn't be able to access its DOM, but with this trick, you can.


Shouldn't X-Frame-Options header fix this?


Assuming you don't want your page to be embedded, sure. But what if you do?


True, but that's rather uncommon nowadays.


Cool hack.

May be it is time for browsers to disable iframes by default and ask the end user if they want to run them via the standard browser confirmation mechanisms site by site.


And then you have a confirmation on almost every page, and then you run into dialog box fatigue where users will blindly click through them, and you've gained nothing.


Sites can already send an 'X-Frame-Options: deny' header to prevent being framed.


Or use CSPv2's frame-ancestors.


There are so many individual pieces of HTML and JS that I wish I could do this with. Mostly web APIs. On a URL-by-URL basis.


you all should install uMatrix webextension and stop just "wishing". the future is now :)


Does uMatrix let me block specific JS web APIs and HTML elements like iframes? It never could in the past.


yes. I block iframes globally and the web never been better.

it will show a checkered pattern with a link to open the frame in another window. so you don't even have to whitelist sites or anything. if you care about the frame, like for a embedded video, just open it on its own tab with a single click


uMatrix can block frames and js requests on a domain/sub-domain level. afaik, it can't block at url level, if that's what you meant.

That said, uMatrix, from what I remember, uses the webRequest api which does work from urls. So if you know JS, you can always create an extension and add your own filter.


To be clear, on the JS side I'm talking about providing whitelist-only access to things like the ambient light level, which is provided through a standardized browser API.


Did they fix the problem where disabling javascript didn't enable the `<noscript>` tag?


I would have thought Chrome's site isolation would prevent this. Not enabled in the author's chromium build, or not helping for some reason?


Chrome isolation is partial. Several unrelated tabs can share the same process.


"Site Isolation" is the name of a specific feature. As of Chrome 67, Site Isolation is enabled by default on desktop, so only tabs from the same (scheme, eTLD+1) can share processes, and cross-origin iframes are moved out-of-process based on the same rule.

See https://security.googleblog.com/2018/07/mitigating-spectre-w...


This is a good time to shill NoScript. If your browser runs JavaScript automatically, then you are putting your privacy and safety at risk.


Why does the RSS link on that website link to feedly.com instead of the feed directly? Weird.


Metrics collection.


Could you elaborate?


Probably something like this: https://blog.feedly.com/sort-by-popularity/




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: