Containerised Browsing with Docker

This year’s Pwn2Own contest saw the majority of the main stream browsers being compromised once again, highlighting that we still have some way to go for a secure browsing experience.

It is generally accepted that one of the most effective ways to improve the security of how we browse is using compartmentalisation. In short, this concept involves isolating various software components in to segregated compartments so that if one compartment is compromised, it limits the exposure of the breach. One project that has led the way in the space is Qubes OS and is highly recommended for those looking to take compartmentalisation seriously. Those not quite ready to take the step of moving to Qubes or equivalent, or without the supported hardware, may want to dip their toe in the water by using containers with Docker. We’re not proclaiming that browsing in a container makes you immune to attack, @mj0011sec showed us at Pwn2Own that this concept can still be compromised with his full virtual machine escape from Edge, but it certainly adds an additional layer of defence.

This post describes some of the steps that you can use to setup a browser in Docker on OS X, as well as releases our simple proof of concept app (DockerProxy) that provides a more seamless integration in to the OS.

Using GUI applications in Docker fundamentally relies on some way passing the display from the container to the host OS. The standard ways of achieving this are sharing the X11 socket, using X11 Forwarding or using VNC. There’s several tutorials online documenting how to do this, including these by Fabio Rehm and Jessie Frazelle. This blog post will document how to setup a browser based in Docker on OS X and how to integrate it in to the OS using DockerProxy.

Firstly, there’s a number of software packages that are required, namely XQuartz to provide an X11 session, socat for forwarding the X11 socket and Docker. To install Docker you can use Docker For Mac, or Docker from homebrew, however whichever you choose, you should use the VirtualBox driver.

To install these pre-requisites and setup a base docker machine, use the following:

[code=”bash”]brew install socat
brew install Caskroom/cask/xquartz
brew install docker
brew install docker-machine
docker-machine create –driver=virtualbox default
docker-machine start[/code]
Once XQuartz is installed, open a terminal window using xterm. In the newly displayed xterm window, you should use socat to forward TCP port 6000 to the correct display socket, similar to the following:

[code=”bash”]socat TCP-LISTEN:6000,reuseaddr,fork,bind=,range= UNIX-CLIENT:\”$DISPLAY\”[/code]

In order to use DockerProxy, we require a Docker image containing a browser. You may build your own hardened image or use one of the many pre-built images created by the Docker community.

For the purposes of this PoC, we’ll use the Chrome image created by Jessie Frazelle although any of the freely available images should work. Download the image using docker pull:

[code=”bash”]docker pull jess/chrome[/code]

Next, download and build DockerProxy as per the github instructions.

Once DockerProxy is compiled, copy it to the Applications folder and open it. DockerProxy must be configured as the default browser so it can intercept URL requests, it does this by making itself the default handler for the HTTP and HTTPS URL schemes; select the “Make Default Browser” button.

At this point, DockerProxy is ready to use and any URLs that are opened in OS X will load the app, allowing the user to open in the Docker container or in the default browser. A short video demonstrating this behaviour is shown below:

The concept doesn’t end there, it can easily be extended to other handlers such as opening documents or images inside a container.

This blog post was written by @domchell.

written by

MDSec Research

Ready to engage
with MDSec?

Copyright 2021 MDSec