Drew Haven a.k.a. Periodic

Running Untrusted Code

Last updated

What is untrusted code? It’s any code for which you cannot vouch for the entire chain of custody. Any code you don’t trust should be in a sandbox with as little privilege as possible.

This includes a lot of scripts that you might get from the internet. Some scripts are small enough to review yourself, but honestly, who wants to do that every time? There are tons of small scripts and utilities I might want to run that I don’t trust.

Another case is LLM output. Who knows what the LLM might output? They hallucinate and make many mistakes. No one wants to accidentally run rm -rf / or anything like it.

There’s also the case of supply chain attacks. We trust a lot of code that we download implicitly. A lot of code dependencies are downloaded and executed as part of programming. Sometimes these have malicious code slipped in.

However, you have to draw the line somewhere. For example, it’s hard to trust every package on your OS. If someone slipped malicious code into my window manager I would be pretty fucked.

Using Docker

My favorite trick for running untrusted code is to run it in a small one-time container.

Here’s an example for running a python script.

docker run --rm \
  -v ~/src/repo:/repo:ro \ # Mount this RO unless it needs to do something like NPM builds or VENV installs
  -v ~/data:/data:ro \ # Mount RO to prevent modification.
  --network none \ # No network
  --cap-drop ALL \ # Drop other capabilities
  --security-opt no-new-privileges \ # Make sure it gets no new ones
  python:3.12-slim python3 /repo/untrusted_script.py

Some additional optional arguments if you are concerned:

  --read-only \ # Make the container RO
  --tmpfs /tmp \ # Give it some dedicated scratch space
  --memory 512m \ # Limit memory
  --cpus 1 \ # Limit CPU
  --pids-limit 100 \ # Prevent fork bombing
  --user 1000:1000 # Run as a non-root user to further limit capabilities and prevent root access to whatever you do give it