Closed Bug 1273265 (CVE-2017-7765) Opened 9 years ago Closed 8 years ago

Firefox Mark of the Web bypass (MSVR 1533)

Categories

(Firefox :: File Handling, defect)

Unspecified
Windows 10
defect
Not set
normal

Tracking

()

RESOLVED FIXED
Firefox 55
Tracking Status
firefox52 --- wontfix
firefox-esr52 54+ fixed
firefox53 --- wontfix
firefox54 --- fixed
firefox55 --- fixed

People

(Reporter: MSVulnReport, Assigned: Paolo, NeedInfo)

References

Details

(Keywords: sec-moderate, Whiteboard: [post-critsmash-triage][adv-main54+][adv-esr52.2+])

Attachments

(3 files)

Attached file 85231FFExploit.htm —
User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Safari/537.36 Edge/13.10586 Steps to reproduce: Dan from Microsoft Vulnerability Research (MSVR) here. We’ve found a way to bypass Mark of the Web in FireFox. I have a repro available at the following URL: http://payloadhoster.cloudapp.net/85231FFExploit.htm (the same file is attached, but would need to be hosted somewhere along with a file to download in order to repro the issue) To reproduce the issue: 1. On a Windows 10 machine with Office installed, browse to the page in Firefox 2. Click the link 3. Select either to save the file locally, or open in PowerPoint This vulnerability appears to be caused by links with a “download” attribute that causes the filename to be longer than what’s allowed in Windows. It’s likely that the cause here is trying to call one Windows API or another with a string that’s too long. Thank you for reviewing this report and we'll pass on any questions from the engineering team to the finder promptly. We look forward to hearing your team's analysis. For our prompt attention, please email msvr@microsoft.com and reference MSVR 1533 in the title. Actual results: mark of the web is not applied in either case Expected results: mark of the web is applied and the file is open in protected view
OS: Unspecified → Windows 10
Group: firefox-core-security → core-security
Component: Untriaged → File Handling
Product: Firefox → Core
This is a DOM related issue. Can you take a look at this?
Flags: needinfo?(amarchesini)
Keywords: sec-moderate
jimm might have an idea of an appropriate owner as well.
Group: core-security → core-security-release
Flags: needinfo?(jmathies)
AIUI this is because of: https://dxr.mozilla.org/mozilla-central/source/toolkit/components/jsdownloads/src/DownloadIntegration.jsm#632 which is going to have the file name suggested by the download attribute. Now... we could change the filename to not be so long, but AIUI the filename needs to match that of the file we're saving, otherwise it still won't be marked as "from the web". I don't know where we modify the actual filename - presumably, we need to ensure that we save the file somewhere where it doesn't actually get the super-long filename, and we have 'space' left at the end to tag on the ":Zone.Identifier" stuff. Paolo originally wrote this code (bug 909022), and generally knows our download code, so I think it'd be best if he took this.
Flags: needinfo?(paolo.mozmail)
This used to be in the download manager c++ code, but I guess we ported it over js. Not really my area anymore.
Flags: needinfo?(jmathies)
(In reply to :Gijs Kruitbosch from comment #3) > Now... we could change the filename to not be so long, but AIUI the filename > needs to match that of the file we're saving, otherwise it still won't be > marked as "from the web". I don't know where we modify the actual filename - > presumably, we need to ensure that we save the file somewhere where it > doesn't actually get the super-long filename, and we have 'space' left at > the end to tag on the ":Zone.Identifier" stuff. We rely indirectly on the nsIFile.createUnique function to shorten the path at the time it is chosen, it can be tricky to make room for the ":Zone.Identifier" part there: https://dxr.mozilla.org/mozilla-central/source/toolkit/mozapps/downloads/DownloadPaths.jsm#55 We could try prepending "\\?\" during our "OS.File" call in Downloads.jsm to increase the 260 characters limit for that particular operation, I'm not sure if that works with the Alternate Data Stream syntax though. We may have to be careful about features we lose like the automatic conversion of forward slash to backslash.
Flags: needinfo?(paolo.mozmail)
I experimented with the prefix on my Windows 7 system on an NTFS partition: let streamPath = "\\\\.\\" + aDownload.target.path + ":Zone.Identifier"; This still result in Windows error 3 (The system cannot find the path specified), presumably returned when CreateFileW is called by OS.File. I also tried this without the ADS syntax, just in case: let streamPath = "\\\\.\\" + aDownload.target.path + "_Zone.Identifier"; And the result is the same. So, apparently the prefix that according to the documentation should increase the limit accepted by the API to 32767 characters doesn't work here. What are the correct Windows API calls to apply an ADS to a file with a long name using the Windows API?
Flags: needinfo?(MSVulnReport)
(And both calls above work correctly with shorter names).
Wondering why nsIFile doesn't use MAX_PATH to check what is allowed and what is not on Windows.
(In reply to Andrea Marchesini (:baku) from comment #8) > Wondering why nsIFile doesn't use MAX_PATH to check what is allowed and what > is not on Windows. CreateUnique makes an assumption that 255 excluding the NUL terminator works for all platforms: https://dxr.mozilla.org/mozilla-central/source/xpcom/io/nsLocalFileCommon.cpp#53 For the rest, we don't have to check for MAX_PATH explicitly because the OS will raise an error for us if needed. The issue we have only arises when we append the ADS syntax to the file name.
Flags: needinfo?(amarchesini)
(In reply to :Paolo Amadini from comment #9) > (In reply to Andrea Marchesini (:baku) from comment #8) > > Wondering why nsIFile doesn't use MAX_PATH to check what is allowed and what > > is not on Windows. > > CreateUnique makes an assumption that 255 excluding the NUL terminator works > for all platforms: > > https://dxr.mozilla.org/mozilla-central/source/xpcom/io/nsLocalFileCommon. > cpp#53 > > For the rest, we don't have to check for MAX_PATH explicitly because the OS > will raise an error for us if needed. The issue we have only arises when we > append the ADS syntax to the file name. Is anything going to be terribly upset if we just #ifdef XP_WIN that limit to whatever MAX_PATH is on Windows minus the length of the ADS syntax ? Or is that a dumb idea for other reasons? :-)
(In reply to :Gijs Kruitbosch from comment #10) > Is anything going to be terribly upset if we just #ifdef XP_WIN that limit > to whatever MAX_PATH is on Windows minus the length of the ADS syntax ? It's kind of linked to the specific ADS name we are using, ":Zone.Identifier", so not terribly great but it's a quick and dirty solution that could work as I think it's the only ADS we'll ever use (hehe, I mean, the only ADS we're currently using). We may introduce regressions as we may prevent downloads to be saved at all in deeply nested folders where it would be otherwise legitimate to have a short file name, but it may be a cost we need to pay if the Windows API doesn't give us a better solution anyways...
Group: core-security-release → firefox-core-security
Product: Core → Firefox
Version: unspecified → Trunk
FYI: if this issue is fixed and an acknowledgement given, credit should go to: Jonathan Birch and Microsoft Vulnerability Research
Has there been any updates on this bug?
(In reply to MSVulnReport from comment #13) > Has there been any updates on this bug? Thanks for asking, I have a technical question for you from comment 6. We might be dealing with a limitation of the Windows API or NTFS with regard to file name length in the presence of an ADS. It's possible this is something that should be fixed on the Microsoft side, even though we might have a workaround. I experimented with the prefix on my Windows 7 system on an NTFS partition: let streamPath = "\\\\.\\" + aDownload.target.path + ":Zone.Identifier"; This still result in Windows error 3 (The system cannot find the path specified), presumably returned when CreateFileW is called by OS.File. I also tried this without the ADS syntax, just in case: let streamPath = "\\\\.\\" + aDownload.target.path + "_Zone.Identifier"; And the result is the same. So, apparently the prefix that according to the documentation should increase the limit accepted by the API to 32767 characters doesn't work here. What are the correct Windows API calls to apply an ADS to a file with a long name using the Windows API?
This needs to be backported to ESR as this has a larger effect on enterprise customers. This decision is from conversation with Microsoft, Google, and partners.
(In reply to Raymond Forbes[:rforbes] from comment #15) > This needs to be backported to ESR as this has a larger effect on enterprise > customers. This decision is from conversation with Microsoft, Google, and > partners. It would be nice if Microsoft, Google, and partners took a look at the questions I raised in this bug. The bug or limitation might be in the Windows API and affect other products as well.
@paolo we had a meeting with the microsoft team yesterday at Blue Hat. The engineer who would be working on this is planning on making a bugzilla account and responding very soon.
(In reply to :Paolo Amadini from comment #16) > > It would be nice if Microsoft, Google, and partners took a look at the > questions I raised in this bug. In fact, I added a Microsoft representative from our meeting to this bug yesterday. He'll be working with the developers on their end to get questions answered.
That's great, thanks for the update!
Status: UNCONFIRMED → NEW
Ever confirmed: true
This is Jonathan Birch, with Microsoft Office Security. I'm meeting with the relevant API owners tomorrow, but in response to this: > I experimented with the prefix on my Windows 7 system on an NTFS partition: > > let streamPath = "\\\\.\\" + aDownload.target.path + ":Zone.Identifier"; > > This still result in Windows error 3 (The system cannot find the path > specified), presumably returned when CreateFileW is called by OS.File. I > also tried this without the ADS syntax, just in case: > > let streamPath = "\\\\.\\" + aDownload.target.path + "_Zone.Identifier"; > > And the result is the same. So, apparently the prefix that according to the > documentation should increase the limit accepted by the API to 32767 > characters doesn't work here. They've gotten back to me to say that the syntax you're looking for might be \\?\ rather than \\.\ Also, I'm not currently receiving email sent to me through Bugzilla, due to issues with S/MIME on my end. I'm not sure if that matters, but I'm working on getting is solved.
(In reply to Jonathan Birch from comment #20) > This is Jonathan Birch, with Microsoft Office Security. I'm meeting with the > relevant API owners tomorrow, but in response to this: > They've gotten back to me to say that the syntax you're looking for might be > \\?\ rather than \\.\ Ah, sorry! So, just prepending \\?\ works fine and it fixes the bug when saving to a local file system. If I understand correctly, however, it won't give the correct result for UNC paths, and won't normalize slashes into backslashes. So here is a new question for the API owners: do I really have to pass the path to the undocumented RtlDosPathNameToNtPathName_U function to work around the MAX_PATH limit and still preprocess the path, as described in the following blog post I just found? https://googleprojectzero.blogspot.it/2016/02/the-definitive-guide-on-win32-to-nt.html If the conversion rules are very simple we might just reimplement them in JavaScript without the complications of accessing an ntdll export. Note that we want to keep compatibility back to Windows 7 at least. > Also, I'm not currently receiving email sent to me through Bugzilla, due to > issues with S/MIME on my end. I'm not sure if that matters, but I'm working > on getting is solved. I'll also notify you of this message directly.
Flags: needinfo?(MSVulnReport) → needinfo?(jobirch)
> Ah, sorry! So, just prepending \\?\ works fine and it fixes the bug when > saving to a local file system. If I understand correctly, however, it won't > give the correct result for UNC paths, and won't normalize slashes into > backslashes. > > So here is a new question for the API owners: do I really have to pass the > path to the undocumented RtlDosPathNameToNtPathName_U function to work > around the MAX_PATH limit and still preprocess the path, as described in the > following blog post I just found? > > https://googleprojectzero.blogspot.it/2016/02/the-definitive-guide-on-win32- > to-nt.html > > If the conversion rules are very simple we might just reimplement them in > JavaScript without the complications of accessing an ntdll export. > > Note that we want to keep compatibility back to Windows 7 at least. Based on discussion with API owners: You can get the canonicalized path name by prepending \\?\ and then calling GetFullPathName on the full string. There should be no need to call RtlDosPathNameToNtPathName_U. The resulting path should be passable to any Win32 API for saving files and not subject to MAX_PATH limits. This will probably end up giving the user a file they can't open due to its filename being too long. Filename segments are still limited to 255 characters, so you'll still need to truncate in some way. My impression is that you have some other solution to that issue already. Is that enough information to help you solve this issue?
(In reply to Jonathan Birch from comment #22) > Based on discussion with API owners: You can get the canonicalized path name > by prepending \\?\ and then calling GetFullPathName on the full string. > There should be no need to call RtlDosPathNameToNtPathName_U. The resulting > path should be passable to any Win32 API for saving files and not subject to > MAX_PATH limits. That works for converting slashes to backslashes, but still doesn't support UNC paths out of the box. Considering that we are operating under some well known restrictions, and we don't need to provide generic access to paths whose length is beyond MAX_PATH, I've special cased the UNC "DOS" paths and I believe that it works sufficiently well in combination with GetFullPathName for the problem we're trying to solve here. The only issue would be if GetFullPathName misses other normalizations that RtlDosPathNameToNtPathName_U does, beyond handling UNC paths, resulting in an attempt to access a file with a different name in the presence of some special characters, but this is for the API owners to tell. Note that we filter allowed file names, and we've already accessed the file before. > This will probably end up giving the user a file they can't open due to its > filename being too long. > > Filename segments are still limited to 255 characters, so you'll still need > to truncate in some way. My impression is that you have some other solution > to that issue already. We already operate withing the MAX_PATH limitations for all other operations, and I've tested the file can still be opened and its properties inspected from Windows Explorer after the ADS is added. > Is that enough information to help you solve this issue? I'll post a patch with an implementation that solves the bug for the test case, when saving to local paths or UNC paths. I may need more information on the normalization question above, and the patch can be a good starting point if the API owners want to take a look.
Attached patch The patch — — Splinter Review
Gijs, you may also want to take a look in the meantime.
Attachment #8810055 - Flags: feedback?(gijskruitbosch+bugs)
Comment on attachment 8810055 [details] [diff] [review] The patch Review of attachment 8810055 [details] [diff] [review]: ----------------------------------------------------------------- I think Jim would be a better reviewer/feedback-giver here. :-)
Attachment #8810055 - Flags: feedback?(gijskruitbosch+bugs) → feedback?(jmathies)
Comment on attachment 8810055 [details] [diff] [review] The patch Review of attachment 8810055 [details] [diff] [review]: ----------------------------------------------------------------- ::: toolkit/components/osfile/modules/osfile_win_front.jsm @@ +353,5 @@ > + if (options.winAllowLengthBeyondMaxPathWithCaveats) { > + // Use the \\?\ syntax to allow lengths beyond MAX_PATH. This limited > + // implementation only supports a DOS local path or UNC path as input. > + let isUNC = path.length >= 2 && (path[0] == "\\" || path[0] == "/") && > + (path[1] == "\\" || path[1] == "/"); Why do we check for forward slashes here, afaict this isn't allowed for unc paths.
Attachment #8810055 - Flags: feedback?(jmathies) → feedback+
(In reply to Jim Mathies [:jimm] from comment #26) > Why do we check for forward slashes here, afaict this isn't allowed for unc > paths. Most Windows APIs actually accept forward slashes and convert them to backslashes automatically, so we need to check for forward slashes as well. Given that this path prefix is set by the Firefox preferences UI, though, it is unlikely that the full path checked here would have forward slashes, unless about:config has been edited directly by an advanced user. I think we're now only waiting for Jonathan Birch to relay the patch and comment 23 to the Windows API owners to tell if this fix is good enough or it may introduce known regressions on shorter paths.
Flags: needinfo?(jobirch)
Flags: needinfo?(jobirch)
For the record, that might happen after the holidays, as I just got an out of office automated reply.
I have a thread in progress regarding the question in Comment 23. I'll relay the patch as well. I'll post back here as soon as I have an answer.
Sorry for the delay in getting this patch reviewed. There were a few complications on our end. I've had people knowledgeable about path canonicalization examine the source for this patch, and they say it looks correct. I have not been able to perform any practical testing of the patch itself, as it's not clear that I can actually build Firefox from source. Is that enough for you to move forward with checking in this fix? You still have the original repro to check your fix against for practical testing.
Flags: needinfo?(jobirch)
Comment on attachment 8810055 [details] [diff] [review] The patch (In reply to Jonathan Birch from comment #30) > I've had people knowledgeable about path canonicalization examine the source > for this patch, and they say it looks correct. Thanks, this is definitely helpful! I'm asking Jim for the final review.
Attachment #8810055 - Flags: review?(jmathies)
Patch looks good, can we put a test together for this?
Flags: needinfo?(paolo.mozmail)
It will be a while before I can find the time to put together a test case, as I'm traveling right now. It's definitely possible to have one, it would just rely on the same new API when reading the Alternate Data Stream. Any test case would need to be verified in automation, but only after we've landed the patch properly in all branches. I'm not quite sure about the landing process for security patches. Gijs, what happens after the patch gets a final review?
Flags: needinfo?(paolo.mozmail) → needinfo?(gijskruitbosch+bugs)
(In reply to :Paolo Amadini from comment #33) > It will be a while before I can find the time to put together a test case, > as I'm traveling right now. It's definitely possible to have one, it would > just rely on the same new API when reading the Alternate Data Stream. > > Any test case would need to be verified in automation, but only after we've > landed the patch properly in all branches. I'm not quite sure about the > landing process for security patches. Gijs, what happens after the patch > gets a final review? This bug is rated sec-moderate, so as far as I understand https://wiki.mozilla.org/Security/Bug_Approval_Process you should be able to land the patch without explicit sec-approval once it has review. You'll probably want to ask for approval for branch patches for 53 and 54, and possibly 52-esr. The wikipage suggests NOT landing tests until after we ship the fix. That said, I would strongly encourage you to write the test ASAP, and run it against beta locally (not on try) after you create a branch patch, to ensure we actually fix the issue and successfully test for it in automation, even if we then don't land it until afterwards. Does that answer your question?
Flags: needinfo?(gijskruitbosch+bugs) → needinfo?(paolo.mozmail)
Attachment #8810055 - Flags: review?(jmathies) → review+
Attached patch The test — — Splinter Review
Assignee: nobody → paolo.mozmail
Status: NEW → ASSIGNED
Attachment #8854382 - Flags: review?(jmathies)
I ran the test locally on Nightly for now, not on a Beta build yet. The affected OS.File code has not been touched very much recently, and I expect the patch to apply cleanly to all branches. It looks like we might be able to land the patch in the next two days, for Beta 10: https://calendar.google.com/calendar/embed?src=bW96aWxsYS5jb21fZGJxODRhbnI5aTh0Y25taGFiYXRzdHY1Y29AZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ
Flags: needinfo?(paolo.mozmail)
Comment on attachment 8810055 [details] [diff] [review] The patch This bug is sec-moderate because it cannot be used alone to run arbitrary code on the user's computer, but it removes the security warning that the Windows operating system shows before running executables downloaded from the Internet. While sec-approval is not needed, I'm requesting it so I can get help with the landing process. I'll be around in the next few days, but note that the sheriffs may also be able to land the patch without assistance if needed. [Security approval request comment] How easily could an exploit be constructed based on the patch? - Easily. Do comments in the patch, the check-in comment, or tests included in the patch paint a bulls-eye on the security problem? - People familiar with the Windows file system can very easily understand the issue being fixed. Which older supported branches are affected by this flaw? - All branches Do you have backports for the affected branches? If not, how different, hard to create, and risky will they be? - The patch should apply easily to all branches How likely is this patch to cause regressions; how much testing does it need? - There is a very slim chance of regressions with file names with special characters, but this is mitigated by the fact that the code has been reviewed by Microsoft experts.
Attachment #8810055 - Flags: sec-approval?
Comment on attachment 8810055 [details] [diff] [review] The patch Approval Request Comment [Feature/Bug causing the regression]: Downloads [User impact if declined]: For downloaded executables with long file names, the Windows security warning is not shown. [Is this code covered by automated tests?]: Yes [Has the fix been verified in Nightly?]: No [Needs manual test from QE? If yes, steps to reproduce]: See the attached exploit [List of other uplifts needed for the feature/fix]: None [Is the change risky?]: Low risk [Why is the change risky/not risky?]: Manual and automated tests have been executed locally. There is a very slim chance of regressions with file names with special characters, but this is mitigated by the fact that the code has been reviewed by Microsoft experts. [String changes made/needed]: None
Attachment #8810055 - Flags: approval-mozilla-esr52?
Attachment #8810055 - Flags: approval-mozilla-beta?
Attachment #8810055 - Flags: approval-mozilla-aurora?
This is a sec-moderate. Sec-moderate bugs do not need to have sec-approval+ to land on trunk. https://wiki.mozilla.org/Security/Bug_Approval_Process
Attachment #8810055 - Flags: sec-approval?
Comment on attachment 8854382 [details] [diff] [review] The test Review of attachment 8854382 [details] [diff] [review]: ----------------------------------------------------------------- Thanks!
Attachment #8854382 - Flags: review?(jmathies) → review+
(In reply to :Paolo Amadini from comment #37) > While sec-approval is not needed, I'm requesting it so I can get help with > the landing process. Hey Al, do I just go ahead and land the patch on trunk myself now? Do I include a commit message and a description?
Flags: needinfo?(abillings)
Well, it is still a security bug so I would be careful what the commit message and description say. As to whether you land or not, you can land or ask sheriffs to land. Yes, it can land though.
Flags: needinfo?(abillings)
If we can we get Beta approval and land later today, can this land this for Beta 10?
Flags: needinfo?(lhenry)
Yes, that's fine, if you can land on m-c first and tests pass. We will go to build Thursday morning, and I'll be checking for uplift requests over the day today.
Flags: needinfo?(lhenry)
This could still land for beta 10, I just don't want to mark it approved till it lands and sticks on trunk - I will have another look in the morning, and may end up going to build later in the day Thursday anyway.
Flags: needinfo?(paolo.mozmail)
Flags: needinfo?(lhenry)
Wes, can you make sure we land this on trunk, so I can approve it for aurora/beta? Thanks!
Flags: needinfo?(lhenry) → needinfo?(wkocher)
Status: ASSIGNED → RESOLVED
Closed: 8 years ago
Flags: needinfo?(wkocher)
Resolution: --- → FIXED
Target Milestone: --- → Firefox 55
So... has this landed on any branches yet?
Flags: needinfo?(lhenry)
(In reply to :Paolo Amadini from comment #49) > So... has this landed on any branches yet? It has not. When it has been, the affected flags for those branches will be set to fixed. It is still waiting for branch approvals.
Group: firefox-core-security → core-security-release
Comment on attachment 8810055 [details] [diff] [review] The patch Let's uplift to aurora, but this has missed beta 10 and so I'd like to let the fix ride with 54.
Flags: needinfo?(lhenry)
Attachment #8810055 - Flags: approval-mozilla-beta?
Attachment #8810055 - Flags: approval-mozilla-beta-
Attachment #8810055 - Flags: approval-mozilla-aurora?
Attachment #8810055 - Flags: approval-mozilla-aurora+
wontfix for 53 based on comment 51. will keep on the list for 52.2esr.
Comment on attachment 8810055 [details] [diff] [review] The patch The patch is low risk, has been in 54 for almost a month, ESR52.2+
Attachment #8810055 - Flags: approval-mozilla-esr52? → approval-mozilla-esr52+
Just to confirm something, will there be a CVE for this? If so, I would like to be credited.
(In reply to Jonathan Birch from comment #56) > Just to confirm something, will there be a CVE for this? If so, I would like > to be credited. --> Al?
Flags: needinfo?(abillings)
A CVE will be assigned before our release. We don't put the names of people on CVE so CVE assignment is immaterial for credit. This will be mentioned as fixed in the advisory for the appropriate release. The advisory will list the reporter credit as "Jonathan Birch and Microsoft Vulnerability Research" within it.
Flags: needinfo?(abillings)
Hello, would you be able to confirm this issue as fixed on your end?
Flags: needinfo?(MSVulnReport)
Whiteboard: [post-critsmash-triage]
Whiteboard: [post-critsmash-triage] → [post-critsmash-triage][adv-main54+][adv-esr52.2+]
Alias: CVE-2017-7765
Group: core-security-release
Pushed by paolo.mozmail@amadzone.org: https://hg.mozilla.org/integration/mozilla-inbound/rev/673af834eacb Test writing zone information for files with long names. r=jimm
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: