New issue
Advanced search Search tips

Issue 688390 link

Starred by 3 users

Issue metadata

Status: Available
Owner: ----
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: All
Pri: 2
Type: Bug



Sign in to add a comment

Opening filesystem:// link to HTML file in new tab allows access to cookies / localStorage etc

Reported by igor.bea...@gmail.com, Feb 3 2017

Issue description

UserAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/602.4.8 (KHTML, like Gecko) Version/10.0.3 Safari/602.4.8

Steps to reproduce the problem:
1. Create some HTML file with javascript, accessing document.cookie (XSS) (e.g. alert(document.domain))
2. Save HTML file to webkitFilesystem fileEntry
3. Create URL with .toURL() method
4. Download the file by URL (via click on <a href="..." download="file.html">...</a>)
5. Go to Downloads ("Show all" button)
6. You will see the filesystem:// URL in the list, open it
7. The page will alert original page domain

What is the expected behavior?
The filesystem:// link should not be exposed to end user in downloads. Or it should not have access to cookies / storages.

What went wrong?
If the app uses webkitFilesystem to store/cache UGC files (including HTML) and allows to download them, attacker can add XSS to the HTML file and ask to make some manipulations to get user's cookies.

Did this work before? N/A 

Does this work in other browsers? Yes (other browser don't have fileSystem API)

Chrome version: 55.0.2883.95 (Official Build) (64-bit)  Channel: n/a
OS Version: OS X 10.12.3
Flash Version: 24.0.0.194

The issue was originally reported by Mohammed Fayez to Telegram Team regarding Telegram Web App: https://web.telegram.org.

Here is the video demo by the user:
https://www.youtube.com/watch?v=5ahpJ7oYMJs

Also here is the test case on Codepen in case it's more easy: http://codepen.io/anon/pen/ggzvwa
 
Don't see the original zip-file with test case (it's the same on as on codepen). Here it is just in case.
codepen_ggzvwa.zip
1.6 KB Download

Comment 2 by phistuck@gmail.com, Feb 3 2017

I am not sure I agree this is a bug. This sounds like a failure of the web application to store files securely in its file system. It does not sanitize them before it stores them.

filesystem:// is not really a protocol, those files are considered as some part of the web application, just like localStorage. If you do not sanitize a string you put in your localStorage and later run it using eval() it, it will have the same access to sensitive stuff.

I am also not sure filesystem:// URLs should not be exposed in the downloads screen. As long as the application or the user did not delete those files, they are accessible from that URL and the user did download it from that URL. What do you expect it to show? "(Generated content)"? "(No URL)"?

In my opinion, there is nothing to fix here except the web application itself.
Components: -Blink>FileAPI UI>Browser>Downloads Blink>SecurityFeature Blink>Storage>FileSystem
Labels: -Hotlist-Interop -OS-Mac OS-All
Thanks for the response.

>filesystem:// is not really a protocol, those files are considered as some part of the web application, just like localStorage.

This is totally unexpected behaviour for me. Is there any more info/docs on this topic?


>If you do not sanitize a string you put in your localStorage and later run it using eval() it, it will have the same access to sensitive stuff.

The point is that I do not call eval() here. I just want to be able to store any file and then be able to download it. I don't want the browser to execute this file in website domain scope in it's own UI (!).

Sanitize is not an option since we can't modify files at all. It's just users' files. It's OK for them to access cookies / storages (since users might need to access those on their own websites e.g.). We just want to transfer these files between users. 

The same way we could host these UGC files via HTTP on our own servers with the same domain name, without any sanitization, and use 'Content-Disposition: attachment; filename="file.html"'. But filesystem API has no such feature and opens file by default.


>I am also not sure filesystem:// URLs should not be exposed in the downloads screen. As long as the application or the user did not delete those files, they are accessible from that URL and the user did download it from that URL. What do you expect it to show? "(Generated content)"? "(No URL)"?

Click on this link from Downloads could force file to be re-downloaded and not opened in new tab. I think this is the expected behaviour in "Downloads" section.

Comment 5 by phistuck@gmail.com, Feb 3 2017

>Thanks for the response.

>>filesystem:// is not really a protocol, those files are considered as some part of the web application, just like localStorage.

>This is totally unexpected behaviour for me. Is there any more info/docs on this topic?

Sorry, I probably came across educated - I am not, this is just my perspective. It might be a normal protocol, but I do not think so.

>>If you do not sanitize a string you put in your localStorage and later run it using eval() it, it will have the same access to sensitive stuff.

>The point is that I do not call eval() here. I just want to be able to store any file and then be able to download it. I don't want the browser to execute this file in website domain scope in it's own UI (!).

I think (I am not too familiar with the APIs, sorry) you can define the MIME type when storing a file using the file system APIs, so you can store the file with a MIME type that is not viewable (not text/html and friends), which would probably make the browser download it on every access instead of browsing to it. Have you tried that?

>Sanitize is not an option since we can't modify files at all. It's just users' files. It's OK for them to access cookies / storages (since users might need to access those on their own websites e.g.). We just want to transfer these files between users.

Then I guess my suggestion above would mitigate that.

>The same way we could host these UGC files via HTTP on our own servers with the same domain name, without any sanitization, and use 'Content-Disposition: attachment; filename="file.html"'. But filesystem API has no such feature and opens file by default.

And this as well. :)

>>I am also not sure filesystem:// URLs should not be exposed in the downloads screen. As long as the application or the user did not delete those files, they are accessible from that URL and the user did download it from that URL. What do you expect it to show? "(Generated content)"? "(No URL)"?

>Click on this link from Downloads could force file to be re-downloaded and not opened in new tab. I think this is the expected behaviour in "Downloads" section.

And this as well. :)
Though I am not sure you expected behavior is necessarily the intended behavior. I mean, what if the URL has changed its response and no longer downloads but instead views the content? Also, with <a download>, any viewable file can be downloaded by a regular click and show its URL which, when it is clicked, would browse to it rather than download it.
Cc: jsb...@chromium.org pwnall@chromium.org
Status: Available (was: Unconfirmed)
OP: You should consider using URL.createObjectURL() [1], which has more cross-browser support than the fileystem API. We'd like to eventually deprecate and remove filesystem, as it hasn't gained traction with the other vendors.

That being said, blob: URLs seem to behave in the same way regarding document.domain, so this bug is still valid.

jsbell: Is anyone else looking into origins for blob: and filesystem:, or should I take a look at fixing this?

[1] https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL
>>I think (I am not too familiar with the APIs, sorry) you can define the MIME type when storing a file using the file system APIs, so you can store the file with a MIME type that is not viewable (not text/html and friends), which would probably make the browser download it on every access instead of browsing to it. Have you tried that?

I tried this for sure. I tried setting mime to different values, e.g. 'application/octet-stream', doesn't help. Here is another pen btw: http://codepen.io/anon/pen/GWEOVz
It seems that it only depends on file extension. Which I can change of course. But then  when user right-clicks image / video / link and choose "Save as.." he will have invalid extension for file in his Downloads, and will not be able to open it.

>OP: You should consider using URL.createObjectURL() [1], which has more cross-browser support than the fileystem API. We'd like to eventually deprecate and remove filesystem, as it hasn't gained traction with the other vendors.


Sure, we also have a fallback to IDB, but prefer FileSystem API when available, since it allows to resume downloads and some other stuff.

Comment 8 by phistuck@gmail.com, Mar 13 2017

Huh, the fact that MIME type does not work looks pretty buggy to me...
You may want to file an issue for that.

Comment 9 by est...@chromium.org, Nov 10 2017

Labels: Hotlist-EnamelAndFriendsFixIt
Labels: -Hotlist-EnamelAndFriendsFixIt

Sign in to add a comment