Closed Bug 90386 Opened 23 years ago Closed 23 years ago

about: document.writes userAgent without escaping

Categories

(Core :: Security, defect, P2)

x86
Windows NT
defect

Tracking

()

VERIFIED DUPLICATE of bug 95768
mozilla0.9.6

People

(Reporter: jruderman, Assigned: security-bugs)

References

()

Details

(Whiteboard: patch, PDT-)

Attachments

(1 file)

bbaetz noticed this bug, but I don't think he reported it yet.

about: document.writes userAgent without escaping it, and also document.writes
part of userAgent as the version number.  This is problematic for two reasons:

1. The user may have set Mozilla to spoof Internet Explorer's userAgent.  about:
will then report that Mozilla is Internet Explorer.

2. about: calls document.write directly on navigator.userAgent instead of
escaping the userAgent string first.  Thus, any HTML tags in the will be
interpreted as HTML rather than displayed as they are written in the userAgent.
 Worse, the URL about: is mapped to chrome URL, so any scripts in these tags
will run with chrome privileges.

I know of at least one current security hole that would allow a web page to
change the navigator.userAgent that about: sees. Also, if someone has write
access to prefs.js, they can change navigator.useragent.override, effectively
changing navigator.userAgent, and they can also change the home page to about:
to ensure that their code will be run.

I can fix (2) quickly by adding an htmlEscape function to about:.
Note that about.html is in the en-US directory, so this change might affect
internationalization, even though I didn't change any text.
Adding Frank Tang on the cc list.  Frank, how do we ensure that this fix applies
to about.html of all the various locales?

Marking nsBranch...
Keywords: nsBranch
Really adding Frank to the cc list.  Frank, how do we ensure that this fix 
applies to about.html of all the various locales?  Thanks for your help!
>I know of at least one current security hole that would allow a web page to
>change the navigator.userAgent that about: sees. Also, if someone has write
>access to prefs.js, they can change navigator.useragent.override, effectively
>changing navigator.userAgent, and they can also change the home page to about:
>to ensure that their code will be run.

Jesse, which security hole would allow a web page to change navigator.userAgent? 
 Shouldn't we try to fix that security hole?

Also, presumably, only the user of a machine has write access to the prefs.js on 
that machine.  Is there any way that the setting of navigator.useragent.override 
and the resetting of the home page can happen as a user is browsing the web?  If 
not, then these two attacks are not ship stoppers, right?
Priority: -- → P2
Target Milestone: --- → mozilla0.9.3
We have a couple of attacks with fixes pending that allow an attacker to set
properties of a window in another domain, like "about:". The attacker could
redefine navigator.userAgent via the DOM. This doesn't require write access to
prefs.js at all. So in answer to your first question, we are fixing those other
holes we know of, but there may be more. By itself, being able to set a property
in another domain is a pretty serious exploit, but combined with this bug, it
becomes a complete system compromise exploit. We hope we've fixed all
same-domain exploits, but we should also prevent any undiscovered same-domain
exploits from becoming full-compromise exploits by fixing this bug.
approved the change to about.html, we will update the file in the localized
builds as usual. Copying mcarlson and danielmc
r=mstoltz.
sr=blake
Crap, my patch doesn't fix the security hole.  An attacker with a cross-domain
exploit could set navigator.userAgent to an Object instead of a string, and have
the object define .replace and .toString in such a way that htmlEscape returns a
string containing chars such as <>&.

I asked Phil how to get around that problem, and he suggested using the String
constructor: 
s = String(s);

That worked for about 30 minutes until I realized that all the attacker would
have to do to get around that is to redefine "String" to be the identity
function at the same time they redefined "navigator.userAgent" to be the evil
object.

cc brendan and phil.  Any ideas?
I have spoken to Jesse about this issue. My only suggestion was that
functionality like String() (which can be altered) might be put as a
read-only property of some security object. That way, one could use it 
without worrying if it had been altered by the attacker - 

Jesse pointed out that getters/setters on it would need to be guarded
against, as well - 
See also bug 88087, about: shouldn't have chrome privs.
Why should scripts be able to redefine navigator.userAgent (or any other
navigator. property)? In 4.x these were all read-only properties and I see no
good reason to allow them to be set.
Until recently, there was a bug that web pages could change the
navigator.userAgent seen by about: (bug 87389).  But even without that bug,
Mozilla lets users change their UA string, and that shouldn't affect the
information shown in about:.
well you could hardcode the version into about.html (and maybe pickup the Gecko 
builddate which is compiled-in IIRC), but then we've got yet another thing 
someone has to remember to change for each milestone release.

We could preface the user agent display with a label saying "Current user 
agent:" -- then if the user has a spoofed UA you call it a service letting 
them know how they appear to the 'net, and for the vast majority of people it's 
the correct current version.
why should we care if we display what someone has set the user agent to vs what
the standard shipping browser displays as useragent?  I would think that we want
to display the useragent in the about page as whatever it's set to, otherwise
how would people know what user agent their browser is using?

I also was under the impression that navigator.useragent was read-only (with the
exception of people customizing it themselves).

Yes, we could hard code the user agent information in the about page, but the
whole reason we went dynamic was because it was always out of date.  So if we go
back to hard coding for security reasons, know that the price will be never
having an up to date user agent string.
Instwad of changing the way the useragent string is displayed, let's try not
using the system principal for the about: page. This may break something, but
it's worth a try and would make things a lot safer.
Target Milestone: mozilla0.9.3 → mozilla0.9.4
Let's check in the htmlEscape fix anyway.  At least it makes us display the
right thing (and not be vulnerable to a security hole) when the user agent is
set to some wacky value via prefs.js.
See bug 94551 for another about: page that needs to escape text.
nsbranch+ per pdt triage
it would be good to get it if we can find a fix within next two weeks
assigning to mstoltz 
Assignee: jruderman → mstoltz
Keywords: nsbranchnsbranch+
I'll take this, to make sure it gets done for the Netscape branch.
Keywords: nsbranch+nsbranch
Keywords: nsbranchnsbranch+
0.9.4 is out the door.
Target Milestone: mozilla0.9.4 → mozilla0.9.5
mitch - still important for the branch?
QA Contact: ckritzer → bsharma
I don't think this is important for the branch; there's no security risk at this
point. I'll check it in on the trunk.
Status: NEW → ASSIGNED
Keywords: nsbranch+
Whiteboard: patch
PDT- for the branch according to Mitch's comments. 
Whiteboard: patch → patch, PDT-
time marches on...retargeting to 0.9.6
Target Milestone: mozilla0.9.5 → mozilla0.9.6
I were doing a rewrite of about: in XHTML (bug 95768). And I just noticed this bug.

To make the page a correct working XML document I changed the javascript code to
the following:

<td id="mozver">
<h1>
<a id="mozlink" href="http://www.mozilla.org/releases/">Mozilla </a>
</h1>
<script type="application/x-javascript">
 
document.getElementById("mozlink").firstChild.appendData(navigator.userAgent.match(/rv:([^;)]+)/)[1]);
 
document.getElementById("mozver").appendChild(document.createTextNode(navigator.userAgent));
</script>
</td>


Can this code be an alternative solution to the problem, since the userAgent
string is put directly into DOM Text object?
Can the contents of a Text object still become another elements/objects?
Looks like a viable alternative solution to me, but I'm not sure. Jesse? jst?
I've attached a patch in bug 95768 which incorporates the above changes and
removes the previous fix of this bug.

You are welcome to review it. :o)
Looks reasonable to me too.
I'd like to hear from Jesse before we check this in, as he's got a good eye for
how things can be subverted.

*** This bug has been marked as a duplicate of 95768 ***
Status: ASSIGNED → RESOLVED
Closed: 23 years ago
Resolution: --- → DUPLICATE
vrfy
Status: RESOLVED → VERIFIED
Do we really want the version shown by About to depend on the
User Agent?  I noticed this when I changed my UserAgent to
spoof Netscape 6.2 to verify sniffing in conjunction with
bug 111026.  I changed the UA string, and whammo, Mozilla
0.9.6 became Mozilla 0.9.4, as far as About was concerned.
  
It doesn't seem so wrong that the User Agent string shown 
in the fine print, but it would be nice if the version shown 
in the header were accurate.  That may, however, require 
backend support, or else need to be changed in the About
html each version.  Say, can the build process write it 
into the html at compile time?

In any event, bug 95768 has apparently been resolved 
without changing this.  Are we getting lost in the
shuffle here, or am I totally misunderstanding what
this bug is about?

I do, how else do we remind users that they're actively forging their 
useragent?
> how else do we remind users that they're actively forging 

This might be an issue if there were a UI for changing such
things, but with it being restricted to only users who edit
prefs.js by hand, I expect just about everyone who is 
spoofing knows he is spoofing.  

Anyway, just having the entire UA string shown in About
is no problem as far as I'm concerned.  It's that the
about box in Mozilla 0.9.6 says "Mozilla 0.9.4" in
enormous print and *doesn't say 0.9.6 anyplace*, that's 
what bothers me.  As it stands now, the only way to 
determine the actual version, short of removing the 
spoofing, is to use the build number, but that doesn't 
carry trunk/branch information and so is not a complete 
answer.  So the only real way to find out which version 
you are using is to edit prefs.js, but that requires
exiting Mozilla -- this is a very real problem for users 
who have multiple versions installed for one reason or 
another.  

I don't mind that the spoofed info is shown in About; 
what I do mind is that the truth is not also  shown along 
with it.  The user needs to be able to get this information, 
preferably without editing prefs.js every time.

Websites don't actually need to know what browser the 
user is using.  The user does need to know that.
no, we are not making the mozilla about page static again.  The reason it's
dynamic is so that you don't have to change it every 5 weeks for a new release.
 If you're running multiple versions of mozilla and savvy enough to spoof user
agents then you have to be savvy enough to remember it later.  If you want to
find out what version you're really running, you can go in and unspoof your ua,
and it will tell you.
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: