Issue metadata
Sign in to add a comment
|
Security: Visited Links Leak
Reported by
va...@marylab.com,
Oct 3
|
||||||||||||||||||||||||
Issue descriptionVULNERABILITY DETAILS By applyng linear-gradient or radial-gradient to the "a" element, javascript can determine whether a given URL has been visited or not by evaluating the speed of rendering single color gradient vs multiple colors gradient when one is used for not visited URL and another for visited. The method is almost 100% efficient, but it can be tweaked for a specific platform and CPU. VERSION Chrome Version: 69.0.3497.100 (Official Build) (64-bit) [stable] and 71.0.3569.0 (Official Build) canary (64-bit) Operating System: macOS 10.13.6, MacBook Pro (Retina, 15-inch, Mid 2015), 2,2 GHz Intel Core i7 Chrome Version: 69.0.3497.100 (Official Build) (32-bit) [stable] Operating System: Windows 8.1 Chrome Version: 69.0.3497.100 Operating System: Android 5.1.1; Nexus 4 REPRODUCTION CASE See attached .html file. Also attaching a screenshot with the results.
,
Oct 4
Thank you! 1. Sorry, my next testings show that even without gradients visited links are rendered slower than not visited. Gradients helped to slow down rendering and get better results. So the cause of slow down is not gradient itself. 2. I think there are many ways to make this faster, its run slow because of the slow creation of nodes, I speed it up a little bit (in bb2.html), and can try to search ways to make it faster (maybe reuse of nodes). See attached bb2.html file.
,
Oct 4
,
Oct 4
FYI, attaching the rendered version for visited (repeating gradient block, red/blue) vs. not visited (solid red block) links.
The relevant style is
a {
font-size: 98px;
display: inline-block;
color: red;
background: repeating-linear-gradient(red 3%, currentColor 6%);
}
a:visited {
color: blue;
}
,
Oct 4
+more paint folks In general, gradients will always render slower than solid colors. In this particular case, the solid block is still defined as a repeating gradient (red, red) though. At some level we must be optimizing that away and taking a more efficient draw-solid-red code path. So one option would be to chase down and disable that optimization. Not 100% sure that's a good idea in general. Another option might be to restrict this at the CSS level (e.g. currentColor could ignore the :visited selector) to avoid discriminating visited/not-visited for certain properties. I believe we already do this to some degree (e.g. 'background' on :visited appears to be ignored).
,
Oct 4
I agree that locking this down at the css layer seems like the best choice. @Chrishtr, there was some discussion about finally fixing this whole class of issues by restricting visited link information to the current origin. Did that go anywhere?
,
Oct 4
,
Oct 4
I wrote in my second commend that is not about gradients. Visited and not visited links are rendered at a different speed, even without any style applied to "a" element. Check my attached bb3.html. I do not know why gradients help only for the first run when is calculated initial information about timing.
,
Oct 4
Re c#8: are you getting stable numbers? What platform are you testing on? On my desktop, timings without gradient are noisy/inconsistent: bb3.html:29 Without gradient bb3.html:86 26.10000013373792 "test known URL to calculate visited timing" bb3.html:92 22.200000006705523 "test known URL to calculate NOT visited timing" bb3.html:86 21.499999798834324 "test known URL to calculate visited timing" bb3.html:92 23.099999874830246 "test known URL to calculate NOT visited timing" bb3.html:86 20.400000037625432 "test known URL to calculate visited timing" bb3.html:92 23.000000044703484 "test known URL to calculate NOT visited timing" bb3.html:86 21.19999984279275 "test known URL to calculate visited timing" bb3.html:92 22.70000008866191 "test known URL to calculate NOT visited timing" bb3.html:86 23.000000044703484 "test known URL to calculate visited timing" bb3.html:92 21.99999988079071 "test known URL to calculate NOT visited timing"
,
Oct 4
Re c#9: I think is inconsistent because tested visited URL is empty href (<a href="">) but for real URL it's working. The second method is to uncomment "a" style from html and results will be consistent.
,
Oct 4
Re comment 6: no it did not go anywhere (yet). See also CSSWG issue 3012 for recent discussion.
,
Oct 5
Re c#10: if I plug a non-empty visited link for calibration, I do get a consistent bias:
34.49999960139394 "test known URL to calculate visited timing"
21.000000182539225 "test known URL to calculate NOT visited timing"
28.200000058859587 "test known URL to calculate visited timing"
21.50000026449561 "test known URL to calculate NOT visited timing"
28.4000001847744 "test known URL to calculate visited timing"
22.59999979287386 "test known URL to calculate NOT visited timing"
27.10000006482005 "test known URL to calculate visited timing"
24.10000003874302 "test known URL to calculate NOT visited timing"
28.599999845027924 "test known URL to calculate visited timing"
19.79999989271164 "test known URL to calculate NOT visited timing"
The numbers are quite noisy and actual detection is unreliable, but the bias looks real and intriguing. Note that unlike your previous two examples, bb3.html does not actually render these links (missing <a> text node):
const newlink = document.createElement('a')
// missing: newlink.appendChild(document.createTextNode("This is new."))
newlink.setAttribute('href', notVisited)
container.appendChild(newlink)
So in this case the timing difference is not in rasterization -- I'm guessing style recalc?
Assigning to chrishtr@ for triage.
Chris, we may have two actionable issues here:
1) ability to pull the :visited color into an expensive gradient (as 'currentColor'), allowing rasterization timing attacks; see bb.html, bb2.html, c#4-6; probably best addressed with additional CSS/:visited restrictions.
2) looks like there's also a non-raster timing vector (style recalc?); see bb3.html, c#8-10.
,
Oct 5
,
Oct 5
,
Oct 5
Re c#12: Sure, in bb3.html is more noise because is just to check that links even without text and style are rendered at a different speed. In bb2.html are better results, there are links with text node and some styles. Also, N - the count of nodes matters a lot for less noise.
,
Oct 5
Re c#12: My results for bb2.html and I want to mention that there is not 'currentColor' in bb2, just some styles. For now, I'm not sure that 'currentColor' matter. 56.40000011771917 "test known URL to calculate visited timing" 26.199999963864684 "test known URL to calculate NOT visited timing" 58.39999997988343 "test known URL to calculate visited timing" 25.800000177696347 "test known URL to calculate NOT visited timing" 58.499999810010195 "test known URL to calculate visited timing" 25.800000177696347 "test known URL to calculate NOT visited timing" 65.89999981224537 "test known URL to calculate visited timing" 26.70000004582107 "test known URL to calculate NOT visited timing"
,
Oct 20
chrishtr: Uh oh! This issue still open and hasn't been updated in the last 14 days. This is a serious vulnerability, and we want to ensure that there's progress. Could you please leave an update with the current status and any potential blockers? If you're not the right owner for this issue, could you please remove yourself as soon as possible or help us find the right one? If the issue is fixed or you can't reproduce it, please close the bug. If you've started working on a fix, please set the status to Started. Thanks for your time! To disable nags, add the Disable-Nags label. For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
,
Oct 20
My final thoughts. Not visited link retrieves the internal representation of css styles much faster than visited. So when browser shows a link it made request (select) to "css store" and this store works faster for not visited links. I made a file with aprox. 40 css styles for <a>. Some styles add a bigger difference to render speed, some less. I attach final.html and screenshot for N = 6000 and N = 10000. For N = 6000 visited links are rendered ~ 15ms and not v. ~ 49ms. For N = 10000 v. speed ~ 27ms and not v. ~ 150ms. I used requestAnimationFrame method to calculate render speed, it's not very good because, I think, it works with 15ms steps. But, I guess, in future will be better API to calculate render speed, and then will be easier to find more subtle differences.
,
Oct 24
New Update: I made PoC to runs much faster. 1. <a> contains many <div> 2. Many styles are applied to <div> When each <div> styles need to be calculated, the process goes to slow visited or fast not visited parent link. The difference is very big when are many nodes with many styles inside parent <a>. (So for more/less noise you can add/sub child <div>s.) 3. window.getComputedStyle(el).color instead of requestAnimationFrame or setTimeout
,
Oct 24
And more, I deleted unused code. Now it's really fast, 106 links in 90ms total to check all of them.
,
Nov 3
chrishtr: Uh oh! This issue still open and hasn't been updated in the last 28 days. This is a serious vulnerability, and we want to ensure that there's progress. Could you please leave an update with the current status and any potential blockers? If you're not the right owner for this issue, could you please remove yourself as soon as possible or help us find the right one? If the issue is fixed or you can't reproduce it, please close the bug. If you've started working on a fix, please set the status to Started. Thanks for your time! To disable nags, add the Disable-Nags label. For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
,
Nov 9
This bugs looks the same to me as issue 835590. chrishtr or pdr: Do you see anything unique here, compared to that?
,
Nov 24
Don't think there is anything unique, except perhaps a different vector. Duplicating.
,
Nov 29
Request for disclosure. Issue 835590 was open more than 7 months ago! This is not reasonable timescale
,
Jan 9
,
Jan 15
Hi vadim@, I am making this issue public, thanks! |
|||||||||||||||||||||||||
►
Sign in to add a comment |
|||||||||||||||||||||||||
Comment 1 by mea...@chromium.org
, Oct 3Labels: Security_Severity-Medium Security_Impact-Stable OS-Android OS-Chrome OS-Fuchsia OS-Linux OS-Mac OS-Windows
Owner: fmalita@chromium.org
Status: Assigned (was: Unconfirmed)