👾
We've been using hyphens before they were cool and abused by AIs. Don't let our hyphens trick you, there are still human fingers behind our content.

Yes, another container-related article. To be honest, I wouldn’t be that interested if people —myself included— did things right. But we feel we’re not quite there yet, particularly because every time I teach people about isolation, I leave feeling I have learned new ways to weaponize the concept.

If this is the first article you read about this subject, we’ve discussed devcontainers in the past and the consequences of not isolating your setup sufficiently.

Where do you run your code? - an intro to devcontainers
An introduction to devcontainers. One way to isolate your environment is one step closer to being more secure than before.
Where do you run your code? part II - devcontainer security
Achieving isolation can be a complicated issue. Learn about how you can improve your environment security with this post.

Containerization ≠ Security

So, you say you started using devcontainers, but how effectively do you use them? How often do you run third-party dev/containers? And how often do you check them for potential security issues or misconfigurations?

Unfortunately for you, my dear wanderer, using any type of technology for isolation does not necessarily translate to you being safe —at least not by default. If you don't believe me, maybe I should remind you of Iran's isolated air-gapped nuclear falicity that was hacked through an infected usb device from outside.

Like everything, they are tools, and if you don’t know what you are doing or how to use them properly, it just adds complexity to your setup and a degree of unnecessary strangeness to it—providing a false sense of security.

“I can’t think of anything more nasty than a bathroom Cheeto lock” - Reddit

ByBit’s hack

The top #1 example I use today is ByBit’s historical hack of 1.5 billion dollars by the Lazarus Group. You might wonder, how is this hack connected to containerization? Well, let’s say it provided a key role in it.

In this specific case, forensic analysis revealed a chilling detail: the developer's machine was compromised by a Docker container running in privileged mode, with the dangerous 'privileged' flag concealed, likely craftily, within a configuration file. Nothing seems off. But now, the attacker has access. – DFNs

Inside the docker container, there was a Python application.

This Python application also included a Dockerized version of the application that could be run inside a privileged container. Unknown to the developer, this seemingly benign application enabled DPRK operators to exploit a remote code execution (RCE) vulnerability in the PyYAML library, providing code execution capabilities and subsequently control over the host system – Elastic

So the TL;DR would be something like: a combination of a container being too permissive, along with the exploitation of a vulnerability implanted within a Python application. Of course, it did not end there, but that’s out of the scope of this blog post.

Such a privilege

When you use containers technology enough, you’ll realize that the possibilities to weaponize, misconfigure, misuse or backdoor them are quite a lot.

In the case of devcontainers it is also super relevant what do you use to start them up. IDEs such as VSCode do some amazing things for you to facilitate your development experience, but not without introducing some risks and losing isolation. I have a pending article specifically about it. If there’s enough interest, let us know in the comments, and I might find the motivation to write it out.

Of course, everything becomes much easier for an attacker once you’ve run the container with privileges. Running a container with the --privileged flag enables all OS capabilities, provides access to all devices if it were the host, AppArmor/SELinux seccomp gets disabled, and Kernel interfaces are fully writable, meaning that you can load kernel modules, mess with cgroups, change networking stack, and much more.

Almost like not using a container at all.

Let’s say that every time you run --privileged , you move from being in a steel prison room to a traditional Japanese, almost-transparent, rice paper-thin wall (Shoji) tea house —without the tea, of course. Escaping from that last one seems easier, huh?

Cats beign cats - @davidcoverdale

Rootless containers

If we were to follow a more ‘security chaos engineering’ approach, and not negate human nature –that which is to commit mistakes–,then the best way to avoid privilege escalations is by not giving the possibility for it to happen at all.

One of the ways that I know how to do that is by creating rootless containers, although I do not use them regularly. I might write a separate article to describe this if needed. But the gist of it is that instead of having services like docker run locally as root (UID=0) mapping inside the container UID to 0 as well, you will configure your environment to run docker with a non-privileged user instead (e.g.UID=1000), which, as a consequence, will map the container’s UID 0 to the hosts’ UID 1000 .

So, worst-case scenario, when you run flags such as --privileged or --devices They will just provide the container with the capabilities that the user has on the host.

Making isolation more accessible

Something I have found 'the hard way' while recommending devcontainers, though obvious for some, is that not everybody wants to dedicate the time to learn how to configure them properly, or research enough to come up with their own setup. So approaches like SolarSpace based on our devcontainers and facilitating them to be run with a few clicks (which btw has been updated and now lets you choose from a few) are necessary.

Thinking on how to improve the experience of our devcontainer, and users having different needs, I started to vibecode a web interface that will allow anyone to create their own based on a customized experience. With a few clicks you could set up a Gitpod or GitHub Codespace. When I showed this to tnch, he really liked it, but was surprised to see a web UI of something he had assumed I’d just code straight first as a CLI (since I’m more familiar with TUIs than anything).

I immediately agreed with him and ditched the web UI completely, and started to draft how I would imagine it. Fortunately for me, we currently have a local intern (hi dantesito) for just a few months —our first one!— and this idea really piqued his interest.

devcontainer-wizard pre-release

You can find the repository for this tool here @theredguild/devcontainer-wizard. Either way, I’m going to show you briefly how it currently works.

If you want to use our latest version, you can just run pnpm dev inside the cloned repository or if you want to install it, we have just published the package under @theredguild/devcontainer-wizard. and devcontainer-wizard in case someone tries to 'squat' that name.

Running pnpm install -g devcontainer-wizard or any of your favorite installation methods for npm packages would do.

Needless to say, this is a pre-release version, so we expect feedback on any encountered bugs, or that you submit a setup of your own to be featured there as well!

As you can see in the video, it walks you through the setup, from where you choose to create a highly tailored configuration or select from the pre-defined templates we have available at @theredguild/devcontainer.

You can also run it headless to create, or start with the prebuilt ones, which you can query by typing prebuilt -L/--list.

> devcontainer-wizard prebuilt --list
minimal               Use Hardhat and Foundry doing zero config.
auditor               Audit smart contracts.
isolated              Run untrusted code.
airgapped             Air-gapped environment.
eth-security-toolbox  Auditor environment with Trail of Bits selected tools
legacy                The Red Guild's original devcontainer.
paranoid              Maximum security isolation, read-only OS and air-gapped environments.

We have also included our previous devcontainers and the eth-security-toolbox container by Trail of Bits, in which we added their own VSCode extensions to provide full synergy ;).

At the end, you will see something like this along with the information you chose through the process:

◆ Generation Summary:
   Project: test
   Location: /tmp/.devcontainer/test
   Languages: solidity
   Frameworks: hardhat
   Security Tools: semgrep
   Testing Tools: None
   VS Code Extensions: 8 extensions
  Building devcontainer to finish setup...
      [2025-09-04T18:26:16.959Z] #9 sha256:230f1af031f1d1670f2595ac2f22083a52b97a1b...
    [2025-09-04T18:26:17.958Z] #9 sha256:230f1af031f1d1670f2595ac2f22083a52b97a1b...
    [2025-09-04T18:26:18.459Z] #9 sha256:230f1af031f1d1670f2595ac2f22083a52b97a1b...
    [2025-09-04T18:26:18.587Z] #9 extracting sha256:230f1af031f1d1670f2595ac2f220...

Right after it finishes, it will prompt you to pick if you want to open it under a terminal, or open it through an IDE like VSCode or Cursor.

And that's it! We hope you enjoy it, and let this be the beginning of something bigger, closer to improving everyone's security and accessibility.