Open Bug 1266960 Opened 8 years ago Updated 8 months ago

Extensions can not load file: URLs

Categories

(WebExtensions :: General, defect, P3)

48 Branch
defect

Tracking

(Not tracked)

People

(Reporter: dw-dev, Unassigned)

References

(Blocks 1 open bug)

Details

(Whiteboard: [UX needed possibly] triaged )

Attachments

(1 file, 1 obsolete file)

User Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0
Build ID: 20160422030223

Steps to reproduce:

I have migrated one of add-ons (Navigate Up) to use the WebExtensions API.

Everything works fine, except that calls to 'chrome.tabs.update' fail if the URL is a file URL.




Actual results:

Both of these calls fail:

- chrome.tabs.update(tab.id, { url: "file:///D:/Temp/Google.html" });

- chrome.tabs.update(tab.id, { url: "file:///D:/Temp" });

The error messages are:

- Unchecked lastError value: Error: URL not allowed: file:///D:/Temp/Google.html

- Unchecked lastError value: Error: URL not allowed: file:///D:/Temp


Expected results:

The browser should navigate to the new URL, even if the new URL is a file URL.

Note, this works in Chrome, providing the "Allow access to file URLs" checkbox has been enabled for the particular add-on.
Component: Untriaged → WebExtensions
Product: Firefox → Toolkit
If you enable the "activeTab" permission, you can achieve this using `browser.tabs.executeScript` to set the `window.location` property in the content window.
Status: UNCONFIRMED → NEW
Ever confirmed: true
Summary: chrome.tabs.update throws an error if URL is a file URL → Extensions can not to load file: URLs
Thanks for quick reply.  I had fogotten about the "activeTab" permission.  It works fine.
would at least need to talk to UX on how to handle - chrome does by checking a check box in UX
Priority: -- → P3
Whiteboard: [UX needed possibly] triaged
Something in Nightly has changed for the worse!

This code was working until a couple of days ago:

    chrome.commands.onCommand.addListener(
    function(command)
    {
        chrome.tabs.query({ currentWindow: true, active: true },
        function(tabs)
        {
            chrome.tabs.executeScript(tabs[0].id,{ code: "window.location.href = '" + url + "';" });
        });
    });

BUT now fails with the error message "No matching window".

However, the following code still works:

    chrome.contextMenus.onClicked.addListener(
    function(info,tab)
    {
        chrome.tabs.query({ currentWindow: true, active: true },
        function(tabs)
        {
            chrome.tabs.executeScript(tabs[0].id,{ code: "window.location.href = '" + url + "';" });
        });
    });

So the problem is something to do with the calling context of executeScript - in the working case chrome.contextMenus.onClicked - but in the failing case chrome.commands.onCommand.
Depends on: 1270306
webextensions: --- → ?
Seeing what chrome does it seems to me they decided file access (and incognito access) is more dangerous (or private) than other permissions and require involved, conscious decision by the user.
https://www.dropbox.com/s/cysqquj6hrlj2ip/Screenshot%202017-02-21%2008.58.57.png?dl=0

Before we can decide how to surface the option to allow file access to a WebExtension in Firefox I'd like to get input from @dveditz (security) around how dangerous that access is, compared to other WebExtension permissions.

Based on such input we can see where we place it in the UI. (permission, optional permission, about:addons ... or somewhere else)
Flags: needinfo?(dveditz)
These are probably two separate questions.

Incognito Mode
--------------
In theory a well-written add-on can check the system info to see if it's running in an Incognito window and then behave appropriately. That assumes many things that fail in practice: that the extension will bother to check, that the extension's interpretation of what can or can't get stored during incognito matches ours or the users, that it's not buggy. We're in a similar boat with old-style add-ons. I think we've had some problems, but not many. Then again it could be something we explicitly review for and I'm just not aware of all the rejected submissions.

Apparently Google has decided extensions shouldn't run in Incognito mode with explicit user opt-in. I'm not sure if it's a permissions the extension can request; seems to be something the user can edit in the chrome equivalent of about:addons. Seems like a reasonable default position, but there may be a small handful of security-and-privacy extensions where it might be harmful to a user who thought they were protected by it in an incognito window when they weren't (e.g. "HTTPS Everywhere" would be wanted in private browsing). Could we have both an explicit permission the extension could request as well as a user opt-in for "normal" extensions?

This is primarily a privacy issue so bumping needinfo? to Tanvi for her feedback.

File:// access
--------------
file:/// URLs can read all the sensitive data in your profile (auth cookies, passwords, history) so it's equivalent to the permissions to read all of those things. It can read all your downloaded files and your http cache so it's also sort of like the "global XHR" permission. Extensions should definitely NOT have file:/// access by default.

We've tried to create reasonable substitutes for many reasons an extension would need such access (both with web externsion APIs and similarly back when we were inventing b2g app apis). We have ways for them to store default data, maybe access to well-defined locations on a machine like your pictures and music folders (which all OS's seem to have these days). But still, there will be some extensions that might need more arbitrary access and the utility outweighs the abusability for a trusted author. It would probably help to see some examples (from the Chrome store?) of extensions that needed that functionality to guess whether it should be a requestable permission or a manual user opt-in. The original request here from dw-dev is not enlightening about why this is useful or needed.
Flags: needinfo?(dveditz) → needinfo?(tanvi)
We've got some other comments on other bugs the big one being bug 1246236. Certainly something there's a lot of noise other and a lot of wariness from us on implementing.
(In reply to Daniel Veditz [:dveditz] from comment #10)
> File:// access
> --------------
> It would probably help to see some examples (from the Chrome store?) of extensions that needed
> that functionality to guess whether it should be a requestable permission or
> a manual user opt-in.

In general every extension which is written to display a special content type and gives the user the possibility to view locally stored files needs this functionality. A good exmaple is this pdf reader: https://chrome.google.com/webstore/detail/pdf-viewer/oemmndcbldboiebfnladdacbdfmadadm. Another example would be every ebook reader extension which displays the content of epub files. For instance I'm trying to port my Add-on EPUBReader (https://addons.mozilla.org/firefox/addon/epubreader/) to WebExtensions and would need this functionality, so users can read their locally stored ebooks.

In Chrome these ebook readers are currently apps and not extensions, for that reason they use the FileSystem api to access local files. But because Google will drop support for apps and the FileSystem api, they will convert their apps to extensions and would need this functionality too.

Another example I found in the Chrome webstore is the Evernote Web Clipper: https://chrome.google.com/webstore/detail/evernote-web-clipper/pioclpoplcdbaefihamjohnefbikjilc. But I must admit, I don't know why they need this functionality as I don't know how this extension works. Evernote Web Clipper seems to be a popular Firefox Add-on too, so it's very likely they will need this functionality if they want to run their WebExtensions version in Firefox.
Any news here?
(In reply to testit from comment #12)
> (In reply to Daniel Veditz [:dveditz] from comment #10)
> > File:// access
> > --------------
> > It would probably help to see some examples (from the Chrome store?) of extensions that needed
> > that functionality to guess whether it should be a requestable permission or
> > a manual user opt-in.
> 
> In general every extension which is written to display a special content
> type and gives the user the possibility to view locally stored files needs
> this functionality.

Another example for this is viewing SQLite databases, both generally and also specifically to look at the various databases in Firefox's browser profile. For Firefox there is https://addons.mozilla.org/firefox/addon/sqlite-manager/, whereas for Chrome I've found https://chrome.google.com/webstore/detail/sqlite-viewer-with-google/aaeojgplhedihcdhfcgodiepddeecepl, although that one seems to be an app as well and not an extension.
> file:/// URLs can read all the sensitive data in your profile (auth cookies, passwords, history) so it's equivalent to the permissions to read all of those things. It can read all your downloaded files and your http cache so it's also sort of like the "global XHR" permission. Extensions should definitely NOT have file:/// access by default.

The filesystem access posses the same or similar risk as nativeMessaging which is implemented. In fact nativeMessaging in combination of website listeners pose a greater security risk as web site are given permission to communicate and run functions on users' operating system without users' knowledge or permission via addons. A point that I have strongly made previously but it was overruled.
webextensions: ? → ---
See Also: → 1341341
Summary: Extensions can not to load file: URLs → Extensions can not load file: URLs
Putting away Chrome implementation, maybe good solution will be something similar to Flatpak Portals?

https://github.com/flatpak/flatpak/wiki/Portals
This is another BIG REGRESSION for users of my add-on New Tab Override (more than 110,000 users). I know that a lot of my users use local files as new tab page. Some time ago I had a version with broken support for local files and I got dozens of support e-mails because of that (and at that point the add-on only had the half of the users).

Firefox DOES allow to open local files via the location bar. What is the difference from a security point of view? In both case the user *wants* to open a local file.

(In reply to Kris Maglione [:kmag] from comment #1)
> If you enable the "activeTab" permission, you can achieve this using
> `browser.tabs.executeScript` to set the `window.location` property in the
> content window.

This is not working:

> Error: Access to 'file:///Users/username/Desktop/test.html' from script denied

Since there is no activity on this ticket since a few months and it's an important feature of my add-on NI :kmag for a current statement. Could you please clarify *if* there will be a solution at all? Do I have to tell my users that this won't be possible with the next update of my add-on or can I say this will be possible again in the future? Or is there already a *working* workaround for this use case?

Thank you in advance!
Flags: needinfo?(kmaglione+bmo)
(In reply to Sören Hentzschel from comment #18)
> This is another BIG REGRESSION for users of my add-on New Tab Override (more
> than 110,000 users). I know that a lot of my users use local files as new
> tab page. Some time ago I had a version with broken support for local files
> and I got dozens of support e-mails because of that (and at that point the
> add-on only had the half of the users).

I'm also very unhappy with the situation. For my add-on EPUBReader (> 280,000 users) it's essential, that users can open local ebooks by doubleclicking in the file explorer. I already switched to WebExtensions and received many negative reviews and complaints because of this regression, not to mention the decreasing user number. Now users can open ebooks only via file selector, which is not that much fun.

I've already talked with Andy McKay about this topic. He redirected me to this page: https://wiki.mozilla.org/WebExtensions/RoadMapFirefox57#Filesystem_Access. As you can see, it's not planned to give WebExtensions local file access until FF57. In general there seem to be security concerns concerning this topic, so for me it sounds this will not be available soon if ever.

It would be nice to hear, what exactly the security concerns are.
> It's not planned to give WebExtensions local file access until FF57

Clarification: until *after* Fx 57, if at all
> It would probably help to see some examples (from the Chrome store?) of extensions that needed that functionality to guess whether it should be a requestable permission or a manual user opt-in.

uBlock Origin allows users to import "file:///[path]" URL as custom local filter list, this is something that was often requested by users, and eventually I added the "file:///*" permission[1]. Advanced users may also provide a "file:///" URL to import their own custom sriptlets -- something I use myself as a filter list maintainer.[2]

[1] https://github.com/gorhill/uBlock/issues/1971
[2] https://github.com/gorhill/uBlock/issues/2267
> It would probably help to see some examples (from the Chrome store?) of extensions that needed that functionality to guess whether it should be a requestable permission or a manual user opt-in.
New Tab Tweaker [1][2] could use this to read wallpapers from disk instead of
* having to use a HTTP File Server like HFS [3][4]
* having to use a native application (and communicate between the extension and the application)

[1]: https://github.com/rharel/webext-new-tab-tweaker/
[2]: https://addons.mozilla.org/en-US/firefox/addon/new-tab-tweaker/
[3]: http://www.rejetto.com/hfs/
[4]: https://github.com/rharel/webext-new-tab-tweaker/issues/3#issuecomment-323801431
My use case:
I have extension which manages my opened tabs. It saves tabs in the current window, so I can close it and move on, and later reopen them. Also, often a lot of my tabs are "file:///" urls, because I just drop the images from my current project (I'm an illustrator) and use them as references. So, with previous pre-web-ext version everything was fine. But with new api browser denies me to open a set of urls, because some of them are "file:///" urls.
I think it just unreasoned, because I even don't need the read/write access to open a tab with "file:///", and the browser itself opens such urls.
I think restricting methods such as "browser.tab.executeScript" will make more sense, rather than tabooing "file:///" at a whole.
As I wrote in 1401121 (sorry for the duplicate, but the bugzilla search is really not great), chrome.tabs.update(tab.id, { url: "file:///D:/Temp" }); works in Chrome, even without "allow access to file URL" ticked. As it should, because it's not actually granting access to the file system to the user, it's just telling the browser to load a URL. Actually reading things from disk is a whole different story and not at all what the original problem of this ticket (or mine) is about.
I don't think the use case described by sblask requires UX work. Can this part of the bug be split and triaged if the rest of the work is blocked?

This bug is relevant to my project[1] and I am willing to work on it (and it's probably easier to ship than the keyboard API :)

[1]: https://github.com/cmcaine/tridactyl/pull/8#issuecomment-333365259
Flags: needinfo?(cneiman)
Needinfo'ing Andy on this -- Andy, does Colin's suggestion above sound good?
Flags: needinfo?(cneiman) → needinfo?(amckay)
Sure, but it will still have to be passed off to the security team for a security review.
Flags: needinfo?(amckay)
I see two approaches to solving this issue:

Either way `ExtensionUtils.jsm::checkLoadURL(url, principal, options)` starts checking for `options.allowFile`

 1. I add a new flag to `nsScriptSecurityManager.h` called ALLOW_FILE,
    modify the `nsScriptSecurityManager::checkLoadURI` functions to use it,
    if `options.allowFile` pass the `ssm.ALLOW_FILE` flag.
 2. if `options.allowFile`, verify the url in js, then set the ssm.ALLOW_CHROME url.

Option 1 seems a lot more sensible unless there's an issue with some flags coding for a subsets of other flags' capabilities.

Also, Services.jsm includes this fragment:

XPCOMUtils.defineLazyGetter(Services, "io", () => {
  return Cc["@mozilla.org/network/io-service;1"]
           .getService(Ci.nsIIOService2)
           .QueryInterface(Ci.nsISpeculativeConnect);
});

Where do I find the file that provides e.g. Services.io.newURI()?
Blocks: 1396485
Another use case:
It's pretty much impossible to do real local development of user scripts (i.e. scripts run via the Tampermonkey add-on) at present in Firefox. With Greasemonkey (now legacy), I could just edit the file in place, but I totally understand that those days are gone. With Tampermonkey in chrome, I can at least reinstall the script from my local file system (file: URL) whenever I make changes. I'd be happy with that, but it's not currently possible in Firefox.
(In reply to James Teh [:Jamie] from comment #31)
> Another use case:
> It's pretty much impossible to do real local development of user scripts
> (i.e. scripts run via the Tampermonkey add-on) at present in Firefox. With
> Greasemonkey (now legacy), I could just edit the file in place, but I
> totally understand that those days are gone. With Tampermonkey in chrome, I
> can at least reinstall the script from my local file system (file: URL)
> whenever I make changes. I'd be happy with that, but it's not currently
> possible in Firefox.

https://violentmonkey.github.io/2017/03/14/How-to-edit-scripts-with-your-favorite-editor/
Extra privilege consequences of tabs API being able to open or update to file urls:

Interesting:

 - Test for the existence and type of files by examining the tab titles and favicons with tabs.query()
 - Open a file and search it for a string with find API (useful for getting the values of e.g. boolean config options)

Uninteresting:

 - Read the titles of some files on the system (e.g. HTML files)
 - Change the atime of files
 - Possible DoS attacks on firefox or the system (opening many files at once, very large files, etc)

I don't think any of these are a big deal. Have I missed anything?
(In reply to YF (Yang) from comment #32)
> (In reply to James Teh [:Jamie] from comment #31)
> > Another use case:
> > It's pretty much impossible to do real local development of user scripts
> > (i.e. scripts run via the Tampermonkey add-on) at present in Firefox. With
> > Greasemonkey (now legacy), I could just edit the file in place, but I
> > totally understand that those days are gone. With Tampermonkey in chrome, I
> > can at least reinstall the script from my local file system (file: URL)
> > whenever I make changes. I'd be happy with that, but it's not currently
> > possible in Firefox.
> 
> https://violentmonkey.github.io/2017/03/14/How-to-edit-scripts-with-your-
> favorite-editor/

From that page:

> Known issues
> 
> This won’t work on Firefox due to the strict limitation on access to local files.

And it links to this exact issue (which is amusing).
(In reply to Daniel Veditz [:dveditz] from comment #10)
> These are probably two separate questions.
> 
> Incognito Mode
> --------------
> In theory a well-written add-on can check the system info to see if it's
> running in an Incognito window and then behave appropriately. That assumes
> many things that fail in practice: that the extension will bother to check,
> that the extension's interpretation of what can or can't get stored during
> incognito matches ours or the users, that it's not buggy. We're in a similar
> boat with old-style add-ons. I think we've had some problems, but not many.
> Then again it could be something we explicitly review for and I'm just not
> aware of all the rejected submissions.
> 
> Apparently Google has decided extensions shouldn't run in Incognito mode
> with explicit user opt-in. I'm not sure if it's a permissions the extension
> can request; seems to be something the user can edit in the chrome
> equivalent of about:addons. Seems like a reasonable default position, but
> there may be a small handful of security-and-privacy extensions where it
> might be harmful to a user who thought they were protected by it in an
> incognito window when they weren't (e.g. "HTTPS Everywhere" would be wanted
> in private browsing). Could we have both an explicit permission the
> extension could request as well as a user opt-in for "normal" extensions?
> 
> This is primarily a privacy issue so bumping needinfo? to Tanvi for her
> feedback.
> 

Does Firefox have the capability to disable extensions in private browsing mode?  Or would that be very difficult to implement?  I believe this is easier for Chrome because private mode is more like a separate profile.  In our case, it is a boolean or Origin Attribute.  I'm not sure how many places in the codebase we'd have to touch to turn off extensions while the user is operating in private mode, or if that is even a possibility given our architecture.

Adding Jonathan and Christoph if they want to followup on this as part of the Web Extensions security reviews.
Flags: needinfo?(tanvi)
> Apparently Google has decided extensions shouldn't run in Incognito mode
> with explicit user opt-in. I'm not sure if it's a permissions the extension
> can request

Chrome extensions cannot request access to incognito. It was requested at https://crbug.com/55058 but shut down.
There is not even an enterprise configuration option to enable extensions in incognito mode - https://crbug.com/173640


(In reply to Tanvi Vyas[:tanvi] from comment #35)
> Does Firefox have the capability to disable extensions in private browsing
> mode?

Technically it should be possible.
Many APIs (e.g. webNavigation, webRequest, windows, cookies, content scripts, ...) recognize the status of private browsing (e.g. through the "incognito" / "cookieStoreId" properties).
Adding a check to filter out private browsing contexts is doable.
Product: Toolkit → WebExtensions
Bulk move of bugs per https://bugzilla.mozilla.org/show_bug.cgi?id=1483958
Component: Untriaged → General
Here's a patch that solves the issue until a more permanent fix can trickle down to ESR. It allows access to the file: scheme to a webextension that is granted the '<all_urls>' or 'file:///*' permission.

Applies to 60.3.0ESR.

It seems that Chrome now adds the incognito-mode checkbox to all extensions, and the file URLs checkbox to anything that asks for '<all_urls>' or anything starting with 'file://'. At least, that's the impression I get from the documentation at https://developer.chrome.com/extensions/permission_warnings.

Apparently they also have methods to check these settings at extension.isAllowedFileSchemeAccess() and extension.isAllowedIncognitoAccess(), presumably so that extensions can alert users that certain things won't work, for example, if it's a request blocker intended to improve privacy.

Actually, MDN claims Firefox implements both methods already:

(It does not, however, state that Firefox's implementation of either one does anything more complicated than returning a hard-coded value.)

(In reply to Samuel Bronson from comment #41)

Unrelated to file access, but available starting with 67.

Refreshing patch for 68ESR.

Attachment #9026082 - Attachment is obsolete: true

I have a suggestion.

Let WebExtension not be able to read the contents of the tab "file: // *", let it not be possible to check the status like "no file", "loading", "tab loaded" etc.
But let it be able to open "file: // *" at all without waiting for any permissions.

Now in Firefox you can not even assign such permissions, and I think they are even unnecessary. I believe it is possible to be able to open a tab with "file: // *" without permission by simply blocking the reading of any data about that tab, except that it is just in the list of tabs.

I don't see why the type of scheme is important anyway: surely any valid URI should be accepted, whether it be file:, ftp:, http:, https:, webdav:, or about:?

Severity: normal → S3

The severity field for this bug is relatively low, S3. However, the bug has 7 duplicates, 40 votes and 66 CCs.
:robwu, could you consider increasing the bug severity?

For more information, please visit auto_nag documentation.

Flags: needinfo?(rob)

The last needinfo from me was triggered in error by recent activity on the bug. I'm clearing the needinfo since this is a very old bug and I don't know if it's still relevant.

Flags: needinfo?(rob)
See Also: → 1807608

Clearing the needinfo request I requested six years ago.

Flags: needinfo?(kmaglione+bmo)
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: