Closed Bug 1346515 (CVE-2017-7821) Opened 8 years ago Closed 7 years ago

browser.downloads addon feature may be used for RCE

Categories

(WebExtensions :: Untriaged, defect)

55 Branch
defect
Not set
normal

Tracking

(firefox-esr52 unaffected, firefox55 wontfix, firefox56 fixed)

RESOLVED FIXED
mozilla56
Tracking Status
firefox-esr52 --- unaffected
firefox55 --- wontfix
firefox56 --- fixed

People

(Reporter: qab, Assigned: mstriemer, Mentored)

References

Details

(Keywords: reporter-external, sec-moderate, Whiteboard: [adv-main56+][post-critsmash-triage])

Attachments

(1 file)

Attached file poc.zip
User Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36 Steps to reproduce: I was fiddling with the download feature of webextensions and I noticed you can download and open any files. Of course, immediately I tried executables only to be hit with windows protection. However, it seems like JAR files have been overlooked. 1. Go to 'about:debugging' 2. Unpack attached PoC somewhere 3. Back in 'about:debugging' choose 'Load temp addon' and choose the poc 4. jar file is automatically downloaded and executed. Actual results: We are able to download and execute jar files automatically. As you can imagine this is not good. Expected results: Jar file should have been blocked from auto executing.
Component: Untriaged → WebExtensions: Untriaged
Product: Firefox → Toolkit
Flags: needinfo?(kmaglione+bmo)
Note there is an extra permission (downloads.open) that must be included in a webextension manifest to use the api that launches the native application for a downloaded file. We're not showing anything in the permissions dialogs for that permission but we easily could. I guess the challenge would be to accurately and succinctly describe the capability an extension gets when granted that permission.
Are there legitimate uses for running arbitrary executables? Perhaps those should have extra layers of security. I tried porting the PoC addon to chrome, and if I did that correctly, it looks like chrome will download but will not execute any of the files downloaded. Also, when downloading executables, chrome has an extra dialog 'Are you sure you want to keep this dangerous file..etc' which firefox doesn't. Not sure which browser is using latest standards but Firefox definitely looks more insecure.
(In reply to Abdulrahman Alqabandi from comment #2) > Are there legitimate uses for running arbitrary executables? Not really, but on Windows, it's not very easy to define what is and isn't an executable.
Flags: needinfo?(kmaglione+bmo)
(In reply to Kris Maglione [:kmag] from comment #3) > Not really, but on Windows, it's not very easy to define what is and isn't > an executable. Doesn't FireFox already know about most executables (if not all), as far as the download manager goes. I'm pretty sure jar files once downloaded do not offer an 'Open' option. So there has to be some way to determine that somewhere. See Bug 704622
Seems like two separate things: 1) description to the user that opening(==auto-launching) downloads is a granted permission Clearly Extensions can legitimately download and open files. Opening is potentially dangerous enough that a separate permission to flag this for reviewers is appropriate so I'm glad to see that. I'd argue randomly opening files would be surprising enough to users that we should add opening downloads to the permission prompt/notification. If it's an explicit download manager the user will say "oh, of course". If the "opening" goes through our external helper app dialog that lets the user select the appropriate associated app before launching a non-executable file, and gives them the ability to cancel that _might_ be OK without having to show the downloads.open permission on install. Even if the user has selected "always do this for this file type" to skip the prompt (showing they trust the app), as long as WebExtensions can't make that setting for the user. I'm pretty sure we should be showing this dialog regardless of what we do with the on-install prompt. 2) honor the platform blacklist of executable types We need to handle executable types separately, using the consistent IsExecutable() list we use elsewhere so we can maintain it in one place. Once we know a file is an executable what should we do? We could simply refuse to open it, and maybe add a "downloads.launch" permission and method in the future. That will make "Download Manager replacement" extensions unhappy, so an alternative is to always show our prompt before launching an executable file. If the existing external helper app dialog doesn't work then something that communicates "this file was downloaded from the internet, do you want to launch it" and puts the user in control. The downside to that is that users may get double-prompted for "true" executables like .exe/.com, but otherwise we might miss in-practice executables like .js (executed by Windows Scripting Host) or .jar (executed by Java if installed). As a first cut don't worry about double-prompting on Windows; later if it's too annoying we could try to make an exception for the one or two types we can count on Windows to fuss over.
Group: firefox-core-security
Keywords: sec-moderate
Group: toolkit-core-security
Note that this also works with .lnk files ( see Bug 1359661 ) though with my testing I get an initial 'unknown publisher' prompt before I can open. With certs leaking left and right im sure that dialog can be circumvented to achieve similar RCE flow as .jar.
I think we should check the incoming download against the IsExecutable() list dveditz mentioned and fail. We can return a fail to the promise so the developer can deal with that appropriately. Then we'll spin off a second bug asking for UX on what we do in this case.
Assignee: nobody → mstriemer
Mentor: aswan
(In reply to Daniel Veditz [:dveditz] from comment #5) > > 2) honor the platform blacklist of executable types > > We need to handle executable types separately, using the consistent > IsExecutable() list we use elsewhere so we can maintain it in one place. > Once we know a file is an executable what should we do? We could simply > refuse to open it, and maybe add a "downloads.launch" permission and method > in the future. That will make "Download Manager replacement" extensions > unhappy, so an alternative is to always show our prompt before launching an > executable file. If the existing external helper app dialog doesn't work > then something that communicates "this file was downloaded from the > internet, do you want to launch it" and puts the user in control. > > The downside to that is that users may get double-prompted for "true" > executables like .exe/.com, but otherwise we might miss in-practice > executables like .js (executed by Windows Scripting Host) or .jar (executed > by Java if installed). As a first cut don't worry about double-prompting on > Windows; later if it's too annoying we could try to make an exception for > the one or two types we can count on Windows to fuss over. The extension code is using the same code as the download manager. This checks if `file.isExecutable()` to show a dialog, but not on Windows. This means that clicking on a .jar from the download arrow in the chrome will open without prompting, while the .exe that I used to install Java will open the Windows prompt. We could update the code path through extensions to always prompt when opening an executable from an extension, but this seems like it should be prompting for a .jar from the built-in download manager as well. Running the POC on my Mac will generate a Mac dialog that prevents me from running the .jar, for what it's worth. @dvdeitz would you like me to go with double prompting when called by an extension and leave the built-in download manager as is for now? I'm guessing we don't want to double prompt from Firefox's download manager. This case also seems like something that Windows should be catching so I'm a bit surprised this happens.
Flags: needinfo?(dveditz)
Paolo might have some insight to answer comment 8. Opening a .jar without notification from Firefox or Windows that it's an executable seems bad, even from the download manager. How do you think we should solve that?
Flags: needinfo?(paolo.mozmail)
(In reply to Mark Striemer [:mstriemer] from comment #8) > We could update the code path through extensions to always prompt when > opening an executable from an extension, but this seems like it should be > prompting for a .jar from the built-in download manager as well. We should use the same code for both so the logic is in one place. Sounds like our current Download Manager has dangerous behavior as well. > @dvdeitz would you like me to go with double prompting when called by an > extension and leave the built-in download manager as is for now? I'm > guessing we don't want to double prompt from Firefox's download manager. I couldn't figure out where the windows special-casing code was. Is there commit history that explains why it's not doing the same checks as on the other platforms? Probably it's trying to avoid double-prompting for .exe types, but our concept of "executable" is broader than the narrow definition used by the OS (e.g. Java .jar files, which to Windows is just a data file processed by an application). Rather than skipping the check on Windows, we should make an exception for ".exe" specifically and still check and prompt for the others. Other executable types recognized by windows (e.g. .com) are rare enough that double-prompting won't hurt and might even wake someone up.
Flags: needinfo?(dveditz)
There are several related aspects to the issues being discussed, so it's worth summarizing everything again even if it is already clear to everyone here. On Windows, how the operating system deals with a file is determined only by its file extension. Some extensions like "exe" indicate files that are opened directly, while others like "txt", "vbs", and "jar" indicate files that are opened through helper applications like "notepad.exe". Both cases can execute arbitrary code on the user's computer using the logged on user's account. In the case of helper applications, this only happens if the application is designed to do so. Normally this is not the case for "txt" and "notepad.exe", but it is the case for "vbs" and "jar". While any application can be associated to any extension, we made a list of potentially executable file types based on common helper applications associated to common extensions, in addition to the executable files that are opened directly. For example, this list includes "exe", "vbs", and "jar": https://dxr.mozilla.org/mozilla-central/rev/85e5d15c31691c89b82d6068c26260416493071f/xpcom/io/nsLocalFileWin.cpp#3004-3079 Downloads can be started in different ways, but the most common is when the user follows a link to a web resource whose type cannot be handled internally by the browser. This is when we may offer a choice about how to handle the file, for example just save it to disk, open it with the default helper application, or open it with a manually chosen helper application. If we determined that the extension that the file will get locally is in the executable list, we only offer the option to save to disk, meaning that we will never take any action without further user interaction: https://dxr.mozilla.org/mozilla-central/rev/85e5d15c31691c89b82d6068c26260416493071f/toolkit/mozapps/downloads/nsHelperAppDlg.js#474-478 https://dxr.mozilla.org/mozilla-central/rev/85e5d15c31691c89b82d6068c26260416493071f/uriloader/exthandler/nsExternalHelperAppService.cpp#1781-1784 When the download is complete it can be opened with a single click from the Downloads Panel. The file can also be opened from the operating system's file manager, after finding it with the "open containing folder" icon. Assuming the operating system is configured with default security settings, on completion we will have marked any file whose URI the operating system regards as coming from the Internet zone, regardless of whether the extension is considered executable or whether the file will be opened by a helper application: https://dxr.mozilla.org/mozilla-central/rev/85e5d15c31691c89b82d6068c26260416493071f/toolkit/components/jsdownloads/src/DownloadIntegration.jsm#520-565 Typically, files created by WebExtensions come from "blob:" or "web-extension:" URIs, and they will be marked as well. This will cause the operating system to prompt before opening the file. This happens for standard executables like "exe" and also for scripts like "vbs" and "reg", which require a helper application. The prompt is shown before the helper application is invoked. For some reason that I cannot explain, the operating system does not prompt for "jar" files marked as coming from the Internet zone. This is what allows the POC in comment 0 to launch the Java file without prompting, and this behavior is different from all the other types I've tested on Windows 10, including "vbs" and "reg". It might be a special exception configured by the Java installer by default. End of part 1...
The behavior for platforms that are not Windows is different for some aspects, because of the different method that the operating system uses to launch files and mark them as executable, which influences which files can execute arbitrary code. On these platforms, we still show our own prompt when launching a file we consider executable from the Downloads Panel, because the operating system does not do this for us: https://dxr.mozilla.org/mozilla-central/rev/85e5d15c31691c89b82d6068c26260416493071f/toolkit/components/jsdownloads/src/DownloadIntegration.jsm#638-650 This prompt is inferior to the one provided by Windows because it has a generic look and doesn't use any of the meta-data of the file to inform the user. This is why we rely exclusively on the operating system's prompt on Windows. Note that we will show our prompt on Windows when the file is opened from the Downloads View in the Library, but this is just because the implementation hasn't been updated: https://dxr.mozilla.org/mozilla-central/rev/85e5d15c31691c89b82d6068c26260416493071f/browser/components/downloads/DownloadsCommon.jsm#425-434 End of part 2...
The discussion about WebExtension download permissions is broader than the specific security issue mentioned here. I would say that the interaction with the Downloads Panel and the Downloads View in the Library is in some way privileged, because we may be sure that the user has shown an intention to open that specific file. We don't need extra prompts, especially for files that are not executable. An extension could hovever call the "open" API at any time. Even if the file is not executable, a misbehaved extension can be annoying by launching external applications repeatedly. Even if we prompted, and extension could show multiple overlapping prompts, unless we add code to enqueue them. In my view, this is something that could be addressed by add-on review and testing. As already noted earlier, if the add-on is a download manager it may want to provide an experience that is not limited by extra prompts. But this might be worth discussing in a separate bug.
Flags: needinfo?(paolo.mozmail)
Looking at the code for when we prompt and based on dveditz's comment I think it makes sense to update both the Downloads Panel and the webextension based API to prompt on Windows for executables unless the file is a .exe. This will make our prompting on Windows consistent with the other platforms for all cases except for .exe where we will delegate to the native Windows dialog. While double prompting on Windows for certain file types can be annoying, I think that's better than having Windows being less secure than other platforms.
See Also: → 1367529
So the POC doesn't work in Chrome since they require a user interaction for downloads.open(). I filed bug 1367529 so we can enforce a similar policy. This still leaves the case where there is user interaction and the user is not warned that a .jar can execute code on Windows, like they are on Mac and Linux. @paolo I can update the Windows check in DownloadIntegration.jsm to prompt for everything but .exe if this is something you'll approve.
Flags: needinfo?(paolo.mozmail)
Looking at the list of extensions we consider executable, apart from "exe" I think they are uncommon enough that a double prompt might be acceptable. There are cases like "crt" where the message we show may be misleading, but it's probably something we can fix later if there is a need. Surely, the amount of prompting for something like a "com" file from an unknown host might get a bit ridiculous (need to save to disk, reminder by Safe Browsing, warning by the Firefox prompt, warning by the operating system), but again this is rare enough nowadays, and users who want to open the file will just enter "whatever" mode by the second prompt anyways. There's no need to work on adding this check to the Downloads Panel in a security bug. Even the "jar" case already requires deliberate interaction, and also to have Java installed in the first place. (Although the reason I think we may want the additional, often unnecessary prompt is indeed because there is at least one case where the OS prompt may not be shown.) So, just file a new bug and post a patch. You should also align the logic in the Downloads View in the Library to ignore "exe" while you're there.
Flags: needinfo?(paolo.mozmail)
@dveditz are you okay with me filing public bugs for fixing this? Updating the downloads panel to prompt more often doesn't seem like a security issue but with the webextension code using the same path we might not want to make that public. Likewise bug 1367529 doesn't seem like a big deal on its own but without prompting for .jar files it becomes an issue.
Flags: needinfo?(dveditz)
Sounds fine.
Flags: needinfo?(dveditz)
May I get an update on this bug, please?
This is fixed now. Bug 1369771 updated the prompting on Windows so we only skip prompting for .exe files so launching the .jar on Windows will now prompt. This was landed in Firefox 55. Bug 1369782 updated the downloads.open() code so that it must be called from a user interaction. This missed Firefox 55 since there were some issues with how we were handling user interactions in WebExtensions, it is included in Firefox 56.
Status: UNCONFIRMED → RESOLVED
Closed: 7 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla56
Group: toolkit-core-security → core-security-release
Alias: CVE-2017-7821
Whiteboard: [adv-main56+]
Flags: qe-verify-
Whiteboard: [adv-main56+] → [adv-main56+][post-critsmash-triage]
Flags: sec-bounty?
Depends on: 1369771, 1369782
Flags: sec-bounty? → sec-bounty+
Group: core-security-release
Product: Toolkit → WebExtensions
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: