Closed Bug 1342678 Opened 7 years ago Closed 5 years ago

same origin policy implementation allows reading directory of a local file

Categories

(Core :: Security: CAPS, defect)

51 Branch
defect
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla69
Tracking Status
firefox-esr68 68+ fixed

People

(Reporter: tim, Assigned: baku)

References

Details

(Keywords: sec-moderate, Whiteboard: [fixed by bug 1500453])

Attachments

(1 file)

Attached file file_sop_test.zip
User Agent: Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:51.0) Gecko/20100101 Firefox/51.0
Build ID: 20170126153103

Steps to reproduce:

I have created a file that loads another file or directory in an iframe, and tries to read the contentDocument's innerHTML/innerText, to demonstrate how the same origin policy for file:// URIs works. Load the soptest.html file that is in the attached archive, enter the name of the file or directory to load into the textbox, press the 'load source' button, then press the 'steal source' button. Do this for the directory '.' (current directory).

Firefox version 51.0.1 (64-bit) on Fedora fc25


Actual results:

When loading the document's directory (.) in the iframe, the directory contents is copied out of the iframe and accessible through JavaScript (see screenshot in attached file).
An attacker that has a victim save an HTML file locally (typically in the Downloads folder), can see the files in that folder and thus read all of these files.


Expected results:

According to the SOP for "file:" URIs, this should not be allowed: "Directories cannot be loaded this way" (see 
https://developer.mozilla.org/en-US/docs/Same-origin_policy_for_file:_URIs )
I don't know why MDN says directory listings can't be read this way (I didn't think we had specific restrictions for them) and/or if this is just a regression. Dan?
Flags: needinfo?(dveditz)
If you try to read the directory listing of a subdirectory below the current directory, this is not allowed. That would indicate to me that the spec on MDN has been implemented partially.

I can think of a security reason for not allowing to read directories. If directory reading were allowed, an attacker could traverse the current directory and anything below it from the current directory. Therefore it would make sense to forbid this.
Here are some more details, that may reduce the likelihood of this being exploited.
I opened the file directly in a fresh browser and tried to load the listing of the current directory from JavaScript. This was _blocked_.

Then I opened the directory itself, and clicked on the file soptest.html. Then loading the listing of the current directory was _not_blocked_.

I have tried to see if this behaviour occured when trying to load other directories, but it did not.
Group: firefox-core-security → dom-core-security
Component: Untriaged → Security: CAPS
Product: Firefox → Core
Flags: sec-bounty?
(In reply to :Gijs from comment #1)
> I don't know why MDN says directory listings can't be read this way (I
> didn't think we had specific restrictions for them) and/or if this is just a
> regression. Dan?

We allow a file to load a "sibling" file in the same directory because some content broke when we restricted it to strict sub-directories. Chrome and Safari are now even stricter (we were the first mover in no longer considering all file:/// urls as same-origin so we were a bit more permissive than we'd like) and we are considering following suit in other bugs.

We restricted directory reading because downloading all your unrelated files into the same download folder is the default behavior. Loading a known sibling file is one thing, allowing a file to read the directory and then know what's available to be snarfed up is something else. Reading directories could also allow a local PoC to defeat the random bit in profile names, making it easier to steal cookies and passwords, etc. Usually profiles are not subdirectories of the default download directory, but just in case...

I cannot reproduce this on Mac or Windows -- the PoC hits a security restriction trying to read the directory (as it should). Is isDirectory() broken on Linux? Are we checking for a trailing '/' to determine whether something's a directory, and Linux doesn't normalize directory names the same way as mac and windows?
Flags: needinfo?(dveditz)
Blocks: 1477067
bug 1477067 might hold the clue -- if you first open a file:// url for the directory containing the test file, then open the test by clicking the link then you can read the parent directory because it inherits that origin across the navigation (it shouldn't). Is that part of the STR for you here? if so we're working on the bogus inheritance in another bug (it's a regression from a while back).
Flags: needinfo?(tim)
Hi Daniel, I am not authorized to see bug 1477067, but this would explain the behaviour that I observed.
Without opening the file:// url for the directory first, the directory listing is not accessible from JavaScript.
So yes, it is part of the steps to reproduce and would also need to be part of an actual exploit.
Flags: needinfo?(tim)
Status: UNCONFIRMED → NEW
Ever confirmed: true
Flags: sec-bounty? → sec-bounty+
Status: NEW → RESOLVED
Closed: 5 years ago
Resolution: --- → FIXED
Whiteboard: [fixed by bug 1500453]
Target Milestone: --- → mozilla68
Assignee: nobody → amarchesini
Group: dom-core-security → core-security-release
Target Milestone: mozilla68 → mozilla69
Group: core-security-release
Depends on: 1500453
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: