Closed Bug 1487355 Opened 6 years ago Closed 5 years ago

Use of WM_CopyData might be a sandbox bypass

Categories

(Toolkit :: Startup and Profile System, enhancement)

enhancement
Not set
normal

Tracking

()

RESOLVED INVALID

People

(Reporter: pauljt, Assigned: pauljt)

References

Details

(Keywords: sec-audit)

Attachments

(1 file)

Attached file send-WM_CopyData.ps1
There is some code in nsNativeAppSupportWin.cpp[1] which uses WM_CopyData to send command line arguments between processes. I got lost trying to trace exactly what we do with said arguments but i think it ends up in nsRemoteService[2] and getting executed. 

I don't know what permissions are needed to send this message, but I'm concerned that a compromised child process able to get a handle to the parent window could send this message to bypass the sandbox. 

That said, I'd tried putting some print statements in, and I counldnt hit this code in brief testing, and attempts to manually send a message to a firefox process to trigger this were not successful.  (see attached attempted PoC) 

This code is _old_ (15 years) so it might be that it isnt used any more. Or maybe Im just missing something.

I did have a look in the sandbox, and we seem to explicitly allow WM_CopyData [3] (Again not sure if im reading that correctly though.)

Filing this bug to investigate a bit further and rule this safe or not. 


[1]https://searchfox.org/mozilla-central/source/toolkit/xre/nsNativeAppSupportWin.cpp#540

[2] https://searchfox.org/mozilla-central/source/toolkit/components/remote/nsRemoteService.cpp#155

[3] https://searchfox.org/mozilla-central/source/ipc/glue/WindowsMessageLoop.cpp#354
Group: core-security → toolkit-core-security
Paul, what was the conclusion on this? That it wasn't reachable from content, but we wanted to put together a test to verify?
Flags: needinfo?(ptheriault)
I'm not sure we got a conclusion -  there are two parts that I think I need to investigate :
  - I'm not sure if sending wm_copydata messages is possible from a content process to parent process AND  
  - even if you can I'm not sure that the parent will actually catch and process the message under normal conditions

The attached script was my work in progress to try to verify this via testing but I wasn't able to induce the expected logging in the parent, so I probably need to take another approach.
Assignee: nobody → ptheriault
Keywords: sec-audit
Flags: needinfo?(ptheriault)
Group: toolkit-core-security → firefox-core-security

Oh yay, we removed support for DDE in 513742, so problem solved (if there was one).

Status: NEW → RESOLVED
Closed: 5 years ago
Depends on: 513742
Resolution: --- → FIXED
Group: firefox-core-security → core-security-release

(In reply to Paul Theriault [:pauljt] (needinfo pls) from comment #3)

Oh yay, we removed support for DDE in 513742, so problem solved (if there was one).

We removed DDE support but we still use WM_CopyData to send command lines between Firefox processes. Does this need to be reopened?

Flags: needinfo?(ptheriault)

Ah ok, yeh we should at least consider it. Leaving needinfo for me to add this to upcoming IPC audit.

Status: RESOLVED → REOPENED
Resolution: FIXED → ---

And to be clear this code is still very much in use. It is used when launching a second instance of Firefox with the same profile. Instead of actually opening a new instance we send the command line arguments to the existing process so anything outside Firefox can execute any of the registered command line handlers.

(In reply to Dave Townsend [:mossop] (he/him) from comment #6)

And to be clear this code is still very much in use. It is used when launching a second instance of Firefox with the same profile. Instead of actually opening a new instance we send the command line arguments to the existing process so anything outside Firefox can execute any of the registered command line handlers.

Do you know what the actual flow is here? This is the main (parent) process of Firefox that is receiving the message, right? This bug is less about other processes sending a malicious message (since if there is a malicious process on your system, you are already hosed), but more the concern that a compromised Firefox Web Content process could send one of these commands to the parent process, and some how escalate privileges out of the Firefox sandbox that way. Knowing what I do about our command line parameters, if the sandbox does NOT prevent the content process from sending a WM_copydata message that the parent process will act on, then I think we have a problem. At a minimum the content process could cause a different profile to be loaded, and I am aware of other weaknesses in command line parsing that probably lead to privilege escalation.

So there are two things here:

  • does the content process sent this message as part of normal operations
  • and if NOT, then are we actually preventing the content process from sending this message

If the content process DOES send this message as part of normal operations then we have a different problem and we need to audit/rethink the security of our command line options.

Flags: needinfo?(ptheriault)

(re-adding needinfo so i remember to dig into this further. I've managed to write some test code to send this from a separate process to parent process, but now I need to try to simulate the compromised child process somehow)

Flags: needinfo?(ptheriault)

(In reply to Paul Theriault [:pauljt] (needinfo pls) from comment #7)

Do you know what the actual flow is here? This is the main (parent) process of Firefox that is receiving the message, right?

Yes, normally this is a message sent from a main process Firefox to another main process Firefox. But we do no validation that that is where the message came from and it looks like there isn't any way to validate the source of this message. We would have to switch to a different technique if we needed to be able to do that.

This bug is less about other processes sending a malicious message (since if there is a malicious process on your system, you are already hosed), but more the concern that a compromised Firefox Web Content process could send one of these commands to the parent process, and some how escalate privileges out of the Firefox sandbox that way. Knowing what I do about our command line parameters, if the sandbox does NOT prevent the content process from sending a WM_copydata message that the parent process will act on, then I think we have a problem.

At a minimum the content process could cause a different profile to be loaded.

This isn't the case. Not all of our command line arguments can be passed in this way.

I am aware of other weaknesses in command line parsing that probably lead to privilege escalation.

Indeed, we're in the middle of fixing one right now!

So there are two things here:

  • does the content process sent this message as part of normal operations

No.

  • and if NOT, then are we actually preventing the content process from sending this message

That would be a question for sandbox folks I guess. A process needs to find the HWND for the message window of a main process (This isn't freely available in the content process, you would have to call windows APIs to find it) and be able to call SendMessage with the right format of data.

(In reply to Dave Townsend [:mossop] (he/him) from comment #9)

(In reply to Paul Theriault [:pauljt] (needinfo pls) from comment #7)
...

  • and if NOT, then are we actually preventing the content process from sending this message

That would be a question for sandbox folks I guess. A process needs to find the HWND for the message window of a main process (This isn't freely available in the content process, you would have to call windows APIs to find it) and be able to call SendMessage with the right format of data.

This should be prevented by the fact that the content processes are in a different Desktop, because you can't send any windows messages between Desktops.
I think that being low integrity would probably block this as well, but we should test that to see if we have this extra protection if, for some reason, the creation of the separate Desktop fails. If you drop the content process to level 1 (security.sandbox.content.level) and restart this will drop the integrity level, but give few other protections.
User Interface Privilege Isolation should prevent this message, the documentation says it does allow certain "read" type messages, but it seems that definitely shouldn't cover WM_COPYDATA.
The easiest way to test might just be to add an IPC message that sends the HWND from the parent for the child to use.
I would suspect that the content process should also be blocked from even finding the HWND from higher integrity process, but I'm not totally sure.

Tom, I'm closing this as invalid since the post's above appear confident that abuse is unlikely. Need-info just as an FYI in case you actually want to do the testing as described in the previous comment.

Status: REOPENED → RESOLVED
Closed: 5 years ago5 years ago
Flags: needinfo?(ptheriault) → needinfo?(tom)
Resolution: --- → INVALID
Group: core-security-release
Flags: needinfo?(tom)
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: