Closed Bug 479943 (CVE-2009-1839) Opened 15 years ago Closed 15 years ago

Restrictions on file-URL-to-file-URL scripting don't appear to be working properly

Categories

(Core :: Security: CAPS, defect)

defect
Not set
normal

Tracking

()

RESOLVED FIXED

People

(Reporter: abarth-mozilla, Assigned: bzbarsky)

References

(Depends on 1 open bug)

Details

(Keywords: fixed1.9.1, verified1.9.0.11, Whiteboard: [sg:moderate])

Attachments

(3 files)

Collin and I were experimenting with the restrictions on file-URL-to-file-URL scripting and found some strange behavior.  Imagine you have the following files on your local file system:

/foo/bar/target.html (contains some text)
/foo/bar/child/index.html (contains an iframe to /foo/bar/target.html)

Steps to reproduce:

1) Type "file:///foo/bar/child/index.html" in the location bar and hit enter.
2) Notice that /foo/bar/child/index.html cannot access /foo/bar/target.html
3) Type "file:///foo/bar/target.html" in the location bar and hit enter.
4) Type "file:///foo/bar/child/index.html" in the location bar and hit enter.
5) Notice that /foo/bar/child/index.html *can* access /foo/bar/target.html

Bizarre, no?
Attached file part one of test case
Attached file part two of test case
I'm seeing different behavior than in your STR:

> 1) Type "file:///foo/bar/child/index.html" in the location bar and hit enter.
> 2) Notice that /foo/bar/child/index.html cannot access /foo/bar/target.html

I have /home/brandon/Desktop/child/index.html and
/home/brandon/Desktop/target.html

and when I load child/index.html the contents of target.html are visible in the iframe.  I cleared my cache before loading the child page.

> 3) Type "file:///foo/bar/target.html" in the location bar and hit enter.
> 4) Type "file:///foo/bar/child/index.html" in the location bar and hit enter.
> 5) Notice that /foo/bar/child/index.html *can* access /foo/bar/target.html

It could see target.html before, but I can see why that would be strange if you weren't seeing the parent in step 1.  Can someone else confirm the behavior?
> and when I load child/index.html the contents of target.html are visible in the
> iframe.

Sorry, my description wasn't clear.  Try clicking the button that says "Go!".  The first time through, the outer page can read the contents of the inner page (its HTML shows up in the alert) but the second time through it can't.
> Bizarre, no?

Bizarre yes, but as intended for better or worse.

The first efforts at tightening up the same-origin policy ("same directory only") broke too many real-world use cases (e.g. on-disk reference material). Allowing parents to reach into sub-directories but not vice-versa created asymmetric permission checks which isn't a good idea in our codebase (bug 402983) and still managed to break a few real-world cases that have wide distribution such as Sun's Java documentation. Making it blindly symmetric meant a file could open a guessed root document (C:\boot.ini on windows?), and then inject script into that document that could spider down elsewhere making all the checks moot.

The current behavior is that files are only same-origin only if they have exactly the same principal, but when a file opens another file in the same directory or a subdirectory it bestows it's own principal on that file. If a file opens a file in a parent or sibling directory it gets its own principal, and the two cannot access each others content. This does lead to the odd order dependency you noted, where if the child is opened by the parent they access each other but if the parent is opened by the child they can't.

When opening a file the new file's location is compared against the principal of the opener and not the actual location (again, in an attempt to not break real-world documents). So if you have
    docs/parent.html
    docs/chap1/section1-1.html
    docs/chap2/section2-1.html
then if parent.html opens section1-1.html, either parent or section1-1 can open section2-1 and all three can interact.

In no case are files allowed to read the contents of a file: URI that is a directory listing, even a subdirectory listing, to prevent spidering.

I'm unhiding this bug because this behavior should be documented, and as written probably INVALID. However it is quirky enough that there might be unintended misbehaviors worth investigating.
Group: core-security
I would think that the principal shouldn't inherit across loads via the url bar.  This bug says that it does, right?
rehiding. Files opened via the URL bar should get a fresh start. Is that what Adam is saying?
Group: core-security
Whiteboard: [sg:investigate]
(In reply to comment #7)
> rehiding. Files opened via the URL bar should get a fresh start. Is that what
> Adam is saying?

Yes.
Yeah, so nsDocShell::InternalLoad will use the current document's principal as the owner if no owner is provided and a file:, data:, or javascript: URI is being loaded, and DoURILoad will use the owner if loading a file URI if the owner passes the CheckMayLoad() check.

Is there a reason we're getting an owner in InternalLoad in the file case?  I thought location sets and link clicks always passed in an owner directly, no?
Whiteboard: [sg:investigate] → [sg:moderate]
Attached patch Proposed fixSplinter Review
With this change we actually do pass the principal in for link clicks and form submission.  Subframe loads and location sets were already doing it.  This lets us remove the "inherit the owner" flag from this case, and to stop inheriting the owner for file:// URIs in all cases.

I did check that <a href="someOtherFile.html" target="_blank"> works to give the new page the same principal as the old one if the new page is in the same dir or a subdir.  We really need file:// mochitests.  :(
Assignee: dveditz → bzbarsky
Status: NEW → ASSIGNED
Attachment #369787 - Flags: superreview?(jst)
Attachment #369787 - Flags: review?(dveditz)
Attachment #369787 - Flags: superreview?(jst) → superreview+
Flags: blocking1.9.1?
Flags: blocking1.9.0.10?
Comment on attachment 369787 [details] [diff] [review]
Proposed fix

r=dveditz

I was waiting for a chance to test this, but for now I'll take bz's assurance that link navigation preserves the correct owner.
Attachment #369787 - Flags: review?(dveditz) → review+
Tested and it works as I'd expect.
Pushed http://hg.mozilla.org/mozilla-central/rev/354f5ac7485d

Tests will have to wait on bug 424484.
Status: ASSIGNED → RESOLVED
Closed: 15 years ago
Depends on: 424484
Flags: in-testsuite?
Resolution: --- → FIXED
Comment on attachment 369787 [details] [diff] [review]
Proposed fix

We should take this on branches too.  This should be reasonably safe, I hope, but some baking is definitely needed.  The fact that we have no automated tests for this set of codepaths (nor a test infrastructure that could run them) makes things a bit worse than they should be.
Attachment #369787 - Flags: approval1.9.1?
Attachment #369787 - Flags: approval1.9.0.10?
Not blocking for now, please renom after baking. We'll look at the approval request anyway.
Flags: blocking1.9.0.10? → wanted1.9.0.x+
Whiteboard: [sg:moderate] → [sg:moderate] needs 1.9.1 approval and landing
Attachment #369787 - Flags: approval1.9.1? → approval1.9.1+
Comment on attachment 369787 [details] [diff] [review]
Proposed fix

Looks worth taking for 1.9.1.
Flags: blocking1.9.1? → blocking1.9.1-
Whiteboard: [sg:moderate] needs 1.9.1 approval and landing → [sg:moderate] needs 1.9.1 landing
Pushed http://hg.mozilla.org/releases/mozilla-1.9.1/rev/38b8a7bc6130
Flags: blocking1.9.1- → blocking1.9.1?
Keywords: fixed1.9.1
Whiteboard: [sg:moderate] needs 1.9.1 landing → [sg:moderate]
Flags: blocking1.9.1?
Comment on attachment 369787 [details] [diff] [review]
Proposed fix

Approved for 1.9.0.10, a=dveditz for release-drivers
Attachment #369787 - Flags: approval1.9.0.10? → approval1.9.0.10+
Checked into CVS.
Keywords: fixed1.9.0.10
I notice that I can no longer get the alert when I load the child directory case in Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.0.11pre) Gecko/2009051111 GranParadiso/3.0.11pre. I also see:

JavaScript error: file:///Users/abillings/Desktop/child/index.html, line 1: Permission denied to get property Window.document

Is this really enough to validate this fix?
Sounds like correct behavior, yes. Compare to the behavior before this patch landed.
I did compare the behavior. That's why I know about the alert. :-)

Following the steps in comment 0 with Firefox 3.0.10 and you will get the alert on the final step. Doing the same with 3.0.11, you do not get the alert.

Marking verified for 1.9.0.11.
Irrelevant to the 1.8 branch where we let any file:/// document open any other file:/// document.
Flags: wanted1.8.1.x-
Group: core-security
Alias: CVE-2009-1839
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: