Note: There are a few cases of duplicates in user autocompletion which are being worked on.
Bug 408329 (CVE-2008-2806)

Mac OS X Java Plugin (JEP) - LiveConnect can still use document.domain bypass to create arbitrary socket connections

VERIFIED FIXED

Status

()

Core
Plug-ins
P5
normal
VERIFIED FIXED
10 years ago
9 years ago

People

(Reporter: Gregory Fleischer, Assigned: smichaud)

Tracking

({verified1.8.1.15})

Trunk
PowerPC
Mac OS X
verified1.8.1.15
Points:
---
Bug Flags:
blocking1.9 -
blocking1.8.1.12 -
blocking1.8.1.13 -
blocking1.8.1.15 +
wanted1.8.1.x +

Firefox Tracking Flags

(Not tracked)

Details

(Whiteboard: [sg:high] fixed by 413161, URL)

(Reporter)

Description

10 years ago
User-Agent:       Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11
Build Identifier: Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11

Apple has released Java for Mac OS X 10.4, Release 6  ( available from http://www.apple.com/support/downloads/javaformacosx104release6.html ).  The update appears to contain fixes for the DNS rebinding vulnerabilities discussed in bug #389625.  

Even though the Java runtime has been updated, the Firefox Mac OS X Java Plugin (MRJ Plugin) appears to remain vulnerable to the 'document.domain' bypass.  By using the document.domain exception to the same origin policy, LiveConnect can be used to create arbitrary socket connections.

Sun Java Runtime Environment fixes for Windows and Linux were released at the beginning of October.  With the Sun JRE updates, the Firefox Java plugins on these platforms are no longer vulnerable to the document.domain bypass.

A demo showing how connections can be made to a localhost web server via the loopback device is available from the URL above.


Reproducible: Always
(Reporter)

Comment 1

10 years ago
I marked this bug as security-sensitive, but the general issue so well known that may be pointless.

Also, my previous comment wasn't entirely clear.  The URL of the demo is http://b64.localhost.pseudo-flaw.net/mrj-plugin-test.html

Component: Security → Plug-ins
Product: Firefox → Core
QA Contact: firefox → plugins
(Assignee)

Comment 2

10 years ago
I've confirmed this, both on OS X 10.4.11 with Apple's new Java for
Mac OS X Release 6, and on OS X 10.5.1 (whose JVM already contained
the updates that are new in 10.4's Java Release 6).

(Background:  Mozilla.org distros on the Mac that can use Java have
for some time bundled the Java Embedding Plugin
(http://javaplugin.sorceforge.net/), which allows non-WebKit browsers
to use current Java versions on OS X.  The JEP's binaries are two
plugins -- JavaEmbeddingPlugin.bundle (the main part of the program)
and MRJPlugin.plugin (a forked descendent of Mozilla.org's MRJ Plugin
Carbon, adapted for use with JavaEmbeddingPlugin.bundle and containing
many additional bugfixes, which I now call the MRJ Plugin JEP).  I'm
the JEP's author.)

Most of the JEP's implementation of LiveConnect is in the JEP's
MRJPlugin.plugin, and is (basically) entirely separate from Apple's
own LiveConnect implementation.  So it's not entirely surprising that
Apple's changes didn't fix this problem in the JEP.

The problem could (conceivably) be addressed in the JEP.  But the JEP
(the MRJ Plugin JEP) gets the applet's host's hostname from the
browser (via a call to
nsIScriptSecurityManager::GetSubjectPrincipal()).  So I think it's
more appropriate to address this problem in the browser.

I don't know if the patch for bug 389625 (attachment 279764 [details] [diff] [review]) will also
fix this problem.  I'll try it and let you know my results.

By the way, does this problem still effect Flash, or other kinds of
plugins?

The MRJ Plugin JEP's call to
nsIScriptSecurityManager::GetSubjectPrincipal() happens in
CSecureEnv.cpp's CSecureEnv::sendMessageToJava() method.
Status: UNCONFIRMED → NEW
Ever confirmed: true
(Assignee)

Comment 3

10 years ago
> I don't know if the patch for bug 389625 (attachment 279764 [details] [diff] [review]
> [details]) will also fix this problem.  I'll try it and let you know
> my results.

I haven't tried it ... but I know that it won't work --
PR_GetHostByName() is never called while loading this bug's test case.

I'll be looking for some other way to change the browser to fix this
bug.
(Assignee)

Comment 4

10 years ago
The consequences of this bug seem to be the same as for bug 402995.
So I think this bug is pretty serious, and should be fixed soon (if
not right away).

Daniel and Jesse, what do you think?

I'm wondering if I should drop everything else and work on this.  And
in particular, I'm wondering if (assuming this won't be fixed in the
browser anytime soon) I should immediately start working on an update
to the JEP (which would take about a week).

I know Josh doesn't want me to :-)  And to be honest I've got plenty
of other stuff to do, and am not particularly eager myself.  But what
do you guys think?
The old MRJCarbon code appears to use nsIPrincipal::GetOrigin() which takes document.domain into account. This shouldn't be used for anything in Java which wants a much more strict same-origin policy.

This has bitten us several times. Short of dumping document.domain altogether (oh how I wish...) we need to rethink what nsIPrincipal offers. I think only caps itself cares about whether document.domain has been set or not, so maybe we can make GetDomain() return what GetOrigin() now does and GetOrigin() can return a cleaned-up scheme+host+port on the real origin URI. (plus some internal way for caps to see if domain is set).
(Assignee)

Comment 6

10 years ago
> The old MRJCarbon code appears to use nsIPrincipal::GetOrigin()

And so does the MRJ Plugin JEP.

How should I change this in the next version of the JEP (leaving
undecided exactly when that will happen)?
(Assignee)

Comment 7

10 years ago
>> The old MRJCarbon code appears to use nsIPrincipal::GetOrigin()
>
> And so does the MRJ Plugin JEP.

With this bug's testcase, nsIPrincipal::GetOrigin() returns
"http://localhost.pseudo-flaw.net".
(Assignee)

Comment 8

10 years ago
>> The old MRJCarbon code appears to use nsIPrincipal::GetOrigin()
>
> And so does the MRJ Plugin JEP.
>
> How should I change this in the next version of the JEP (leaving
> undecided exactly when that will happen)?

Or let me put this a different way:

Is there currently any (better) alternative (for the MRJ Plugin JEP)
to calling GetOrigin() on an nsIPrincipal() object returned by
nsIScriptSecurityManager::GetSubjectPrincipal()?

And if so what is it?
I don't know about "better", but what you need to do is drop any use of GetOrigin() for Java and use the principal's URI. To do that safely you'll have to duplicate GetOrigin's unwrapping of nested protocols, and you have to deal with the fact that it's a full URI and not just scheme+host+port.

That's why I suggested we should change nsIPrincipal to make this kind of thing easier. Make GetOrigin() reflect the real origin from the URI and a new GetOriginDomain() or whatever for browserish places that care about whether document.domain has been set.

Of course we could leave GetOrigin() alone and do a new GetStrictOrigin(), but I suspect more people will get it wrong in the future that way.
(Assignee)

Comment 10

10 years ago
> use the principal's URI

nsIPrincipal's URI attribute?

> To do that safely you'll have to duplicate GetOrigin's unwrapping of
> nested protocols, and you have to deal with the fact that it's a
> full URI and not just scheme+host+port.

Sounds awful :-(

I'm not at all sure I could get it right.

> That's why I suggested we should change nsIPrincipal to make this
> kind of thing easier. Make GetOrigin() reflect the real origin from
> the URI and a new GetOriginDomain() or whatever for browserish
> places that care about whether document.domain has been set.

This would be best (easiest) from my point of view (as the author of
the JEP).

> Of course we could leave GetOrigin() alone and do a new
> GetStrictOrigin()

This'd also work for me ... though it'd require me to do a new release
of the JEP.
I don't know how we can avoid that -- either way is an incompatible change to the interface.

In fact for the 1.8 branch we're constrained not to break those interfaces. We will have to create a nsIPrincipal_MOZILLA_1_8_BRANCH interface to hold the new entry points and you _will_ have to release a new JEP :-(
(Assignee)

Comment 12

10 years ago
> We will have to create a nsIPrincipal_MOZILLA_1_8_BRANCH interface
> to hold the new entry points and you _will_ have to release a new
> JEP :-(

OK (on the assumption that something in the new interface will
implement your ideas for a GetStrictOrigin()).

Now the question is, when should I do the release :-)

Of course, it'd _really_ be a lot more convenient if I could postpone
this until (say) January of next year.
(Assignee)

Updated

10 years ago
Summary: Mac OS X Java Plugin (MRJ Plugin) - LiveConnect can still use document.domain bypass to create arbitrary socket connections → Mac OS X Java Plugin (JEP) - LiveConnect can still use document.domain bypass to create arbitrary socket connections
(Assignee)

Comment 13

10 years ago
Dan, any news?
Sorry, Steven, I dropped the ball on this one. Let me see if I can make those principal changes on the branch that you'd need.
Flags: wanted1.8.1.x+
Flags: blocking1.9?
Flags: blocking1.8.1.12?
Priority: -- → P2
Whiteboard: [sg:high]
I'll file a separate bug assigned to me for the nsIPrincipal changes
Assignee: nobody → smichaud
Flags: blocking1.8.1.12? → blocking1.8.1.12+
(Assignee)

Comment 16

10 years ago
OK.

By the way, I may not have time to do a new JEP by the announced
Firefox 2.0.0.12 freeze date of Jan 25th.
Depends on: 413161
(Assignee)

Comment 17

10 years ago
Dan, could you cc me on bug 413161?

I currently don't have access.

Comment 18

10 years ago
We should get this in for FF3 for sure
Flags: blocking1.9? → blocking1.9+
Priority: P2 → P1
We won't be getting a new JEP in time for this release (and this is dependent on bug 413161 which is getting moved out), so pushing out.
Flags: blocking1.8.1.13+
Flags: blocking1.8.1.12-
Flags: blocking1.8.1.12+

Updated

10 years ago
Target Milestone: --- → mozilla1.9beta4

Updated

10 years ago
Priority: P1 → P2
Moving bugs that aren't beta 4 blockers to target final release.
Target Milestone: mozilla1.9beta4 → mozilla1.9

Updated

10 years ago
Flags: wanted1.9.0.x+
Flags: tracking1.9+
Flags: blocking1.9-
Target Milestone: mozilla1.9 → ---
Dan has a patch for bug 413161 coming soon, but we won't have time to get a new JEP baked and ready for branch. Pushing this bug out to the next branch release.

This *needs* to block the final 1.9 release as well.
Flags: blocking1.9?
Flags: blocking1.9-
Flags: blocking1.8.1.14+
Flags: blocking1.8.1.13-
Flags: blocking1.8.1.13+

Comment 22

10 years ago
Samuel, this is not an issue on trunk, as far as I know.  What needs to block, exactly?
(Assignee)

Comment 23

10 years ago
This should also effect the trunk ... but I'll retest to be sure.

Comment 24

10 years ago
Hmm...  Maybe I was thinking of a different problem.  This one does look like it should be an issue on the trunk, indeed.
(Assignee)

Comment 25

10 years ago
Turns out it _doesn't_ work on the trunk (testing with today's
Minefield nightly).

The demo URL still "works" fine with Firefox 2.0.0.12, though.

Boris, do you have any idea why it wouldn't work on the trunk?

And Gregory (if you're still listening to us after all this time), do
you have any idea why your demo URL would fail to work properly with
Minefield?  (One thing I did notice is that your test's log (which
appears in the browser page) says "Firefox _NOT_ detected ..." when
run on Minefield, but says "Firefox detected ..." when run on Firefox
2.0.0.12.  The rest of the log looks entirely plausible ... but this
makes me wonder.)

Finally (just to make sure we're all on the same page), you do need to
run a web browser locally, on port 80, before running this test.

Comment 26

10 years ago
> Boris, do you have any idea why it wouldn't work on the trunk?

Not offhand, no...
(Reporter)

Comment 27

10 years ago
(In reply to comment #25)
> 
> And Gregory (if you're still listening to us after all this time), do
> you have any idea why your demo URL would fail to work properly with
> Minefield?  (One thing I did notice is that your test's log (which
> appears in the browser page) says "Firefox _NOT_ detected ..." when
> run on Minefield, but says "Firefox detected ..." when run on Firefox
> 2.0.0.12.  The rest of the log looks entirely plausible ... but this
> makes me wonder.)

No, I don't know why it would fail.  It logs "Firefox _NOT_ detected" based on a simplistic user-agent check.

> 
> Finally (just to make sure we're all on the same page), you do need to
> run a web browser locally, on port 80, before running this test.
> 

Yes, local web server on port 80.

The demo does fail on the latest Minefield nightly, but for me, nothing from LiveConnect is working.  Applets seem to load, the top-level Java packages are visible from JavaScript/LiveConnect, but object creation simply hangs.  

Here are the log messages I got:
================
[*] user agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10.4; en-US; rv:1.9b4pre) Gecko/2008022904 Minefield/3.0b4pre
[!] Firefox _NOT_ detected ... this probably won't work
[*] Mac OS X detected
[*] Java is enabled
[*] LiveConnect present
[*] found Java plugin: Java Embedding Plugin 0.9.6.3 (MRJPlugin.plugin)
[*] found Java plugin: Java Plug-in (CFM) (Java Applet Plugin Enabler)
[*] found Java plugin: Java Plug-in (Java Applet.plugin)
[*] Java Plugin present
[+] domain set: localhost.pseudo-flaw.net
[*] attempting socket connection to localhost.pseudo-flaw.net:80
================

I re-ran the demo with a much older version of Minefield and it worked:
================
[*] user agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O 10.4; en-US; rv:1.9a9pre) Gecko/2007110504 Minefield/3.0a9pre
[!] Firefox _NOT_ detected ... this probably won't work
[*] Mac OS X detected
[*] Java is enabled
[*] LiveConnect present
[*] found Java plugin: Java Embedding Plugin 0.9.6.3 (MRJPlugin.plugin)
[*] found Java plugin: Java Plug-in (CFM) (Java Applet Plugin Enabler)
[*] found Java plugin: Java Plug-in (Java Applet.plugin)
[*] Java Plugin present
[+] domain set: localhost.pseudo-flaw.net
[*] attempting socket connection to localhost.pseudo-flaw.net:80
[*] got sockaddr local address: 127.0.0.1, localhost.pseudo-flaw.net
[*] connected to port 80
[*] socket closed
================

Maybe there is something else wrong.
(Assignee)

Comment 28

10 years ago
Ah, now I see it!

The nsIScriptSecurityManager interface has changed yet again, without
anyone telling me.  (This happened on 2008-01-04.)

This means that JavaScript-to-Java LiveConnect has been broken on the
trunk (on the Mac) since that date.

If you look in the Console log, you'll see the following message
repeated many times:

MRJ Plugin JEP: JavaScript-to-Java LiveConnect failed -- no security manager!

One more thing for me to fix in the new JEP :-(
There's no comment next to the uuid exhorting changers to also change the JS-to-Java LiveConnect code at the same time?

Comment 30

10 years ago
No, nor should there be.  There _should_ however be one exhorting changers to add their bug to the dep list of bug 293973.

Anyone object to me adding such a comment?
The JEP code can use the URI exposed by our principal objects rather than the string origin and that way fix this issue, right?

If so, that's probably the way to go for now, as it sounds like we need an updated JEP for trunk anyways.
Flags: blocking1.9? → blocking1.9+
(Assignee)

Comment 32

10 years ago
> The JEP code can use the URI exposed by our principal objects rather
> than the string origin and that way fix this issue, right?

That doesn't sound right to me ... but then I don't know a whole lot
about nsIPrincipal.

Dveditz, what do you say?
Dveditz still hasn't answered my question from comment #32 ...

But now I've updated the JEP to be aware of the most recent changes to
the nsIScriptSecurityManager interface, and am about to test if the
patch for bug 413161 has fixed this problem on the trunk.

However, now I find that I can no longer access this bug's testcase
(at http://b64.localhost.pseudo-flaw.net/mrj-plugin-test.html).  I get
the error "You don't have permission to access /mrj-plugin-test.html
on this server."

Gregory, I assume this is caused by a problem on the server.  Could
you fix it?

Thanks in advance!
(Following up comment #32)

Looking through the patch for bug 413161, I've formed the following
hypothesis.  Someone please tell me whether or not it's correct:

Among other things, the patch for bug 413161 changes the definition of
nsIPrincipal's "origin" attribute (on the trunk) from

  "the origin of this principal's domain, if non-null, or its codebase
  URI otherwise"

to

  "the origin of this principal's codebase URI"

This is enough, by itself, to fix this bug (bug 408329).

A change like this wouldn't be allowed on the 1.8 branch.

But nsIPrincipal's "URI" attribute is defined (on both the trunk and
the 1.8 branch) as "the codebase URI to which this principal
pertains".  (I assume "codebase" here means the same thing as it does
above.)

So it would also be possible to fix this bug, on both the trunk and
the 1.8 branch, by changing the JEP to use nsIPrincipal objects' "URI"
attributes (suitably translated into a string) instead of their
"origin" attributes.

Is this correct?
(Reporter)

Comment 35

9 years ago
(In reply to comment #33)
> 
> Gregory, I assume this is caused by a problem on the server.  Could
> you fix it?
> 

Should be fixed.
Thanks,	Gregory.  Your testcase is accessible again. 

And my results with it indicate that the patch for bug 413161 _has_
fixed this bug on the trunk.

On the trunk, the contents of "Java Console.log" indicate the "origin"
is now set to "b64.localhost.pseudo-flaw.net" (instead of
"localhost.pseudo-flaw.net" as on the branch).  And when (on the
trunk) the test applet tries to connect to 127.0.0.1:80, it now
triggers the following error:

java.security.AccessControlException:
  access denied (java.net.SocketPermission 127.0.0.1:80 connect,resolve)

Comment 37

9 years ago
> A change like this wouldn't be allowed on the 1.8 branch.

I suspect it might happen on branch, actually.
> So it would also be possible to fix this bug, on both the trunk and
> the 1.8 branch, by changing the JEP to use nsIPrincipal objects' "URI"
> attributes (suitably translated into a string) instead of their
> "origin" attributes.
> 
> Is this correct?

Yes, as I understand it.
Taking this off the blocker list since this should be fixed on trunk now, with the fix in bug 413161. Please renominate if that is not the case.
Flags: blocking1.9+ → blocking1.9-
I thought this was going to be easy to fix on both the trunk and the
1.8 branch (along the lines of what I said in comment #34), but that
turns out not to be the case.

The basic problem is that the JEP currently doesn't link in _anything_
from the Mozilla.org tree (all its interactions are done via pure
XPCOM), and I want to keep it that way.  But if I have to deal with an
nsIURI object (nsIPrincipal's "URI" attribute) instead of an ASCIIZ
string (nsIPrincipal's "origin" attribute), I'll either have to link
in Mozilla.org's string class implementation or roll my own copy of
it.  I don't want to do either of these.

So I need a simple change on the 1.8 branch -- either 1) change
nsIPrincipal's "origin" on the branch the same way it's already been
changed on the trunk, or 2) create a private interface to nsIPrincipal
that (in effect) allows me to access nsIPrincipal's "URI" attribute as
an ASCIIZ string.
By the way, this is quite urgent.  See bug 421855 comment #7.
Ok, lets get bug 413161 on the branch then.
I'm about to land JEP 0.9.6.4 on the 1.8 branch.  But this bug will remain unfixed on the branch even after I've done that, because bug 413161 isn't yet fixed on the 1.8 branch.

Updated

9 years ago
Priority: P2 → P5
Whiteboard: [sg:high] → [sg:high] fixed by 413161
Fix for bug 413161 checked in to the branch, this should be fixed now. We'll verify when we get nightlies.
Keywords: fixed1.8.1.15
Using today's 1.8 branch nightly (firefox-2008-06-07-03-mozilla1.8),
this bug's URL gives the correct results (when run on a machine where
a web server is running on localhost).

The testcase fails to connect:

  ...
  [+] domain set: localhost.pseudo-flaw.net
  [*] attempting socket connection to localhost.pseudo-flaw.net:80
  [*] got sockaddr local address: 127.0.0.1, localhost.pseudo-flaw.net
  [!] TypeError: socket has no properties

And the Java Console displays an AccessControlException error:

  <<< ProxyClassLoader: defined LiveConnectProxy class. >>>
  <<< Here're the permissions you've got: >>>
  <<< java.security.Permissions@1db6bb (
   (java.net.SocketPermission b64.localhost.pseudo-flaw.net
     connect,accept,resolve)
  )
   >>>
  java.security.AccessControlException: access denied
    (java.net.SocketPermission 127.0.0.1:80 connect,resolve)
  ...
Steven, this is fixed on trunk too, correct? Can we resolve this as FIXED now?
> Steven, this is fixed on trunk too, correct?

Yes (I just checked again to be sure, with RC2 and today's 1.9.0 branch nightly).

> Can we resolve this as FIXED now?

Sure.
Status: NEW → RESOLVED
Last Resolved: 9 years ago
Resolution: --- → FIXED
I verified this for 1.8.1.15 with Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1.15pre) Gecko/2008061004 BonEcho/2.0.0.15pre. I checked it against the Firefox 2.0.0.14 release, where it still reproduces.
Keywords: fixed1.8.1.15 → verified1.8.1.15
I verified this for Firefox 3 with RC3 (Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9) Gecko/2008061004 Firefox/3.0) as well.
Status: RESOLVED → VERIFIED
Alias: CVE-2008-2806
Version: unspecified → Trunk
Group: security
Flags: wanted1.9.0.x+
You need to log in before you can comment on or make changes to this bug.