Webextensions can access local files
Categories
(WebExtensions :: General, defect, P1)
Tracking
(firefox-esr68 wontfix, firefox72 wontfix, firefox73 wontfix, firefox74 verified)
People
(Reporter: jan, Assigned: robwu, Mentored)
References
Details
(Keywords: sec-moderate, Whiteboard: webext-sec [post-critsmash-triage][adv-main74+])
Attachments
(6 files)
Comment 1•7 years ago
|
||
Comment 2•7 years ago
|
||
Comment 4•7 years ago
|
||
Comment 6•7 years ago
|
||
Comment 7•7 years ago
|
||
Comment 8•7 years ago
|
||
Updated•7 years ago
|
Comment 10•7 years ago
|
||
Comment 12•7 years ago
|
||
![]() |
||
Updated•7 years ago
|
Comment 14•7 years ago
|
||
Comment 15•7 years ago
|
||
Comment 16•7 years ago
|
||
Comment 17•7 years ago
|
||
Comment 18•7 years ago
|
||
Updated•7 years ago
|
Comment 19•7 years ago
|
||
Comment 20•7 years ago
|
||
Comment 21•7 years ago
|
||
Comment 22•7 years ago
|
||
Comment 23•7 years ago
|
||
Comment 24•7 years ago
|
||
Updated•7 years ago
|
Comment 25•7 years ago
|
||
Comment 26•7 years ago
|
||
![]() |
||
Comment 27•7 years ago
|
||
Comment 29•7 years ago
|
||
Comment 30•7 years ago
|
||
Comment 31•7 years ago
|
||
Reporter | ||
Updated•7 years ago
|
Comment 33•7 years ago
|
||
Comment 34•7 years ago
|
||
Comment 35•7 years ago
|
||
Comment 36•7 years ago
|
||
Updated•7 years ago
|
Updated•7 years ago
|
Updated•7 years ago
|
Comment 39•7 years ago
|
||
Reporter | ||
Comment 40•7 years ago
|
||
Updated•6 years ago
|
Updated•6 years ago
|
Comment 41•6 years ago
|
||
Comment 42•6 years ago
|
||
Comment 44•6 years ago
|
||
Comment 45•6 years ago
|
||
ni? to Kris and Mike for what to do with already installed extensions here (comment 41), similar to the situation about private browsing being solved right now.
Updated•6 years ago
|
Comment 46•6 years ago
|
||
(In reply to Tomislav Jovanovic :zombie from comment #45)
ni? to Kris and Mike for what to do with already installed extensions here (comment 41), similar to the situation about private browsing being solved right now.
This particular question is being rolled up into a larger discussion around exactly how/when extensions can access local files.
Comment 47•6 years ago
|
||
I'm confused by this bug; the docs describe a function to check this capability: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/extension/isAllowedFileSchemeAccess and describe "the user-controlled 'Allow access to File URLs' checkbox" (on https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/extension#getURL() )
Are the docs incorrect or has much of what has been discussed in this bug been implemented?
Comment 48•6 years ago
|
||
(In reply to Tom Ritter [:tjr] from comment #47)
I'm confused by this bug; the docs describe a function to check this capability: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/extension/isAllowedFileSchemeAccess and describe "the user-controlled 'Allow access to File URLs' checkbox" (on https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/extension#getURL() )
Are the docs incorrect or has much of what has been discussed in this bug been implemented?
That currently only applies to Chrome, who we inherited this API from.
![]() |
||
Updated•6 years ago
|
![]() |
||
Updated•5 years ago
|
Comment 49•5 years ago
|
||
Assignee | ||
Comment 50•5 years ago
|
||
I can still reproduce on Linux with Nightly 72.0a1, buildID 20191021215155 .
- manifest.json with
"name": "Extension with file access",
"version": "1",
"manifest_version": 2,
"background": {"scripts": ["bg.js"]},
"permissions": ["file:///*"]
}
- bg.js
async function test() {
let r = await fetch('file:///etc/passwd', {mode:'same-origin'});
let t = await r.text();
console.log(t)
}
test();
Result: The content of /etc/passwd
.
Comment 51•5 years ago
|
||
If I add a catch on the fetch, I get "TypeError: NetworkError when attempting to fetch resource.".
Nightly OSX 10.14
Comment 52•5 years ago
|
||
So, I am still unable to reproduce this on osx regardless of the privacy.file_unique_origin value. However, on a fresh profile, same extension, I can reproduce this on linux. Either it is unrelated to file_unique_origin or it is linux specific. Due to this, I'll set my vm to dealing with windows for the rest of the afternoon.
Comment 53•5 years ago
|
||
This xpi does two fetches, one that is just normal (was making sure I didn't have some stupid problem) and one that does a file fetch. This same xpi fails to fetch the file on osx, but works fine on linux.
![]() |
||
Comment 54•5 years ago
|
||
How do I check whether I'm reproducing with that extension? I installed the extension, started the browser, loaded example.com, but I don't know which console it's logging to and hence whether it's managing to do the fetches...
![]() |
||
Comment 55•5 years ago
|
||
Ah, nevermind. If I add some dump()
calls I can see it running at startup. Poking at things...
Comment 56•5 years ago
|
||
This reproduces on Windows 10 and latest Nightly 72 from today.
![]() |
||
Comment 57•5 years ago
|
||
So the fetch('file:///etc/passwd')
call happens in a content process. The triggering principal (and loading principal) for the fetch is a ContentPrincipal with the URI "moz-extension://01cf4af3-f9f4-4f63-8222-1f2c1db5bffb/_generated_background_page.html"
.
We end up in ContentPrincipal::MayLoadInternal
and the AddonAllowsLoad
call there returns true, because the WebExtensionPolicy::CanAccessURI
call returns true. Given the manifest claims "file:///*"
in the permissions this doesn't seem surprising, right? Anyway, that means BasePrincipal::CheckMayLoad
returns true, and that's our general "Should this principal be considered same-origin with this URI?" method. So we consider this a same-origin load (e.g. NS_HasBeenCrossOrigin
returns false, so DoSOPChecks
returns success, so nsContentSecurityManager::CheckChannel
returns success, so the load is allowed.
After things things Just Work: the fetch successfully opens the FileChannelChild
channel, that remotes the actual filesystem access to the parent process (which is why sandboxing is nor relevant), etc.
Is there some expectation that given our current code this should not work?
Assignee | ||
Comment 58•5 years ago
|
||
fetch('file:///etc/passwd');
does not load the resource (and neither does XMLHttpRequest
) - this is desired as explained below.
fetch('file:///etc/passwd', {mode:'same-origin'});
does load the resource.
They should behave consistently.
file:///*
is automatically granted when the <all_urls>
permission is requested, which is very common.
Most of the extensions that request <all_urls>
don't really need file access.
I'd like to block file access by default unless a user explicitly consented, to protect the general population whose add-ons don't need to access files.
(FWIW, in Chrome <all_urls>
also includes file:///*
, but access is withheld until the user manually grants access at the extension management page.)
Assignee | ||
Updated•5 years ago
|
Assignee | ||
Comment 59•5 years ago
|
||
Next week (or maybe the week after, at the start of release cycle of 73), I intend to land a patch that closes this hole.
The hole does already not work on macOS (comment 49), and starting with my patch, it won't work either on Linux, Windows and Android.
Assignee | ||
Comment 60•5 years ago
|
||
Assignee | ||
Comment 61•5 years ago
|
||
Content scripts are allowed to run on file:-URLs, but other forms of
file access from extensions are not allowed. This has been the behavior
for a while, but there were no tests. This commit adds tests to ensure
that the functionality continues to work as intended.
Assignee | ||
Comment 62•5 years ago
|
||
Assignee | ||
Comment 63•5 years ago
|
||
- comment 60 is a fix for this bug and bug 1487353 (a unit test is attached in that other bug).
- comment 61 is a set of unit tests that already pass, independently of the bugfix. These tests were added to make sure that content scripts for files do not regress.
- comment 61 is a regression test for this bug, and should land in the future, when this bug becomes public.
Comment 64•5 years ago
|
||
The patch in comment 60 seems fine, but I want to understand answers to a few questions beforehand:
-
This proposed fix is different than the agreed consensus in most of this bug, up to and including your second-to-last comment 58, which was putting this access behind a special permission prompt/checkbox. Why did you change your approach? Given recent urgency in bug 1598946, should we bundle the two bugs together, behind the same optional permission?
-
Why doesn't this work on MacOS? Is it a recent "regression", or some configuration/platform difference?
-
I'm looking up code related to comment 23, perhaps this cross-origin check should be lower in the chain to cover more than just addons usecase.
Assignee | ||
Comment 65•5 years ago
|
||
(In reply to :Tomislav Jovanovic :zombie from comment #64)
The patch in comment 60 seems fine, but I want to understand answers to a few questions beforehand:
- This proposed fix is different than the agreed consensus in most of this bug, up to and including your second-to-last comment 58, which was putting this access behind a special permission prompt/checkbox. Why did you change your approach? Given recent urgency in bug 1598946, should we bundle the two bugs together, behind the same optional permission?
I implemented it like this because it fixes file:-access related bugs without breaking known supported cases.
We probably still want to support a prompt/checkbox, but that requires more efforts and review/feedback cycles. That fits better in bug 1598946 or a follow-up to that bug (and some of the ideas expressed here already align with the tentative plan).
- Why doesn't this work on MacOS? Is it a recent "regression", or some configuration/platform difference?
The paths that we tested were blocked by the sandbox on macOS. If I choose a whitelisted location, e.g. file:///usr/share/
, then the load is still accepted.
- I'm looking up code related to comment 23, perhaps this cross-origin check should be lower in the chain to cover more than just addons usecase.
I'm not aware of any other generic file:-whitelisting other than extensions. Judged by extension permissions only, file:
-access should have been allowed (and is so, according to WebExtensionPolicy::CanAccessURI
). But we don't have a separate permission warning or any other obvious indication that an extension is allowed access to local files, so it was a nice "feature" that file:
-URLs were somehow already blocked access (through fetch
/ XMLHttpRequest
) despite being allowed by CanAccessURI
. The patch changes the implementation of CanAccessURI
to match the current default behavior for cors-fetches, and does it at that place to cover most scenarios (without affecting content scripts, for which we want to continue supporting access). If we ever decide to open up file:-access (rather than restricting it), then we probably need to revisit the implementation, but until then, I'd rather be on the safe side.
I think that file:-access to extensions can be a useful feature in some cases, but it should by no means be the silent default behavior.
Assignee | ||
Comment 66•5 years ago
|
||
What's your advice on landing the patches?
I want to land two patches, the fix itself, and unit tests that verifies that the supported behaviors are still working as intended.
Do you think that it is fine to land the following at the same time:
- https://phabricator.services.mozilla.com/D54541 (tests that already passed before the fix)
- https://phabricator.services.mozilla.com/D54540 (fix itself)
(and the regression test in the future - https://phabricator.services.mozilla.com/D54543 ).
... or should I only land the fix now, and land the tests later?
One interesting point to consider is that the bug itself has been public for over two years by now:
https://stackoverflow.com/questions/42108782/firefox-webextensions-get-local-files-content-by-path/44516256#44516256
Comment 67•5 years ago
|
||
Given the public stackoverflow item I'm fine with you landing all of it at once, including D54543.
![]() |
||
Comment 68•5 years ago
|
||
https://hg.mozilla.org/integration/autoland/rev/b4cc65a4d11e4569ea64670d24e38ef6c88a075e
https://hg.mozilla.org/mozilla-central/rev/b4cc65a4d11e
Assignee | ||
Comment 69•5 years ago
|
||
I've only landed the already-passing tests; I'll land the other parts once I've verified that the impact on extensions is minimal.
Updated•5 years ago
|
Assignee | ||
Comment 70•5 years ago
|
||
I checked all public add-ons on AMO, and the following add-ons are relying on this bug / "feature". I've listed the number of users and the use cases:
- https://addons.mozilla.org/en-US/firefox/addon/tampermonkey/ 323k users
- To import local files in scripts: https://github.com/Tampermonkey/tampermonkey/issues/347
- https://addons.mozilla.org/en-US/firefox/addon/s3download-statusbar/ 82k users (recommended badge)
- To read files for checksum calculations and image preview.
- https://addons.mozilla.org/en-US/firefox/addon/styl-us/ 77k users (recommended badge)
- To support installation of local user styles: https://github.com/openstyles/stylus/pull/134
- https://addons.mozilla.org/en-US/firefox/addon/exif-viewer/ 35k users
- Used to view metadata of local files.
- https://addons.mozilla.org/en-US/firefox/addon/foxreplace/ 7k users
- Used to automatically update by reading from a local file.
- https://addons.mozilla.org/en-US/firefox/addon/surfingkeys_ff/ (version <= 0.9.41) 1k users
- Used to read settings from a local file: https://github.com/brookhong/Surfingkeys/pull/891
- Author removed the code in the latest versions (including 0.9.57) when they discovered that the functionality does not work on macOS.
- and a couple of smaller ones.
The total number of users is about 500k. Since the functionality is already not working on macOS, and the loss of use cases is not extremely critical, I'll land the patch that disables local file access, next week.
Comment 71•5 years ago
|
||
Many of those affected addons would be better served with <input type=file>
, it seems.
![]() |
||
Comment 72•5 years ago
|
||
https://hg.mozilla.org/integration/autoland/rev/a32b39b12097218637d33cb0f6ac86e8d93366aa
https://hg.mozilla.org/mozilla-central/rev/a32b39b12097
Comment 73•5 years ago
|
||
Doesn't feel like the kind of change we'd want to land on an ESR branch, but should we consider uplifting this to Beta for Fx73?
Assignee | ||
Comment 74•5 years ago
|
||
This vulnerability has been public for multiple years, and consequently some extensions rely on it for legitimate reasons. I want to let it ride the trains to give add-on developers the opportunity to work with the limitations.
Updated•5 years ago
|
Updated•5 years ago
|
Comment 75•5 years ago
|
||
Verified fixed using the fileaccess.xpi extension provided in comment 53 On Windows 10 Pro 64-bit, MacOS Catalina 10.15 and Ubuntu 16.04 LTS on FF 74.0a1 (20200121215203).
Checked through loading the extension from about debugging and inspecting it on a fixed version and also installing it (after setting xpinstall.signatures.required to false) in about:addons on a Nightly build from before the push and then upgrading the browser.
A security error declaring that data may not be loaded from "file:///etc/passwd" is logged in the extension console log after the fix.
Updated•5 years ago
|
Comment 76•5 years ago
|
||
Updated•5 years ago
|
![]() |
||
Comment 77•5 years ago
|
||
Test for same-origin file requests:
https://hg.mozilla.org/integration/autoland/rev/823481edb95885927d150b4584ecfe639022830b
https://hg.mozilla.org/mozilla-central/rev/823481edb958
Updated•4 years ago
|
Description
•