Safeguard
Security Guides•

How do you run an untrusted script in a throwaway container?

Use no network, a read only root, dropped capabilities, resource limits and a non root user. A flag by flag checklist, plus what a container still cannot stop.

Safeguard Security Team
4 min read

Run it with no network, a read only filesystem, a small writable scratch area, all capabilities dropped, no new privileges, a non root user, and limits on memory, CPU and process count. Remove the container afterward. This lowers risk for casual checks, but a container still shares the host kernel.

The command

docker run --rm \
  --network none \
  --read-only \
  --tmpfs /tmp:rw,noexec,nosuid,size=64m \
  --cap-drop ALL \
  --security-opt no-new-privileges \
  --user 65534:65534 \
  --pids-limit 100 \
  --memory 256m \
  --cpus 1 \
  -v "$PWD/script:/work:ro" \
  python:3 python /work/check.py

The image name and script are placeholders. Pin the image by digest in real use, and scan it first.

What each flag does

FlagEffect, per Docker's documentation
rmRemoves the container and its anonymous volumes when it exits
network noneOnly a loopback device exists inside, so no outside connections
read-onlyMounts the root filesystem read only, so writes go only to listed volumes
tmpfs with noexec and nosuidA memory backed scratch directory that cannot run programs or setuid binaries
cap-drop ALLRemoves the capabilities Docker grants by default
no-new-privilegesStops processes gaining privilege, so su and sudo stop working
userRuns as the named user and group IDs, not root
pids-limitCaps the number of processes
memory and cpusCap memory and CPU through the container's cgroup
ro suffix on the mountStops the container modifying your script folder

Docker notes the minimum memory limit is 6 megabytes, and that a CPU value of 1.5 on a two CPU host guarantees at most one and a half CPUs.

Why no network matters most

The most common harm from a hostile script is sending your data out or fetching a second stage. Docker's none network driver gives the container only a loopback interface. If the script needs a package download, do that in a separate, reviewed build step and copy the result in.

What this setup cannot do

A container is a process on your host kernel. Docker's security page lists the kernel's own security among the areas to review, and gVisor's documentation says a workload using kernel security primitives is still one system call away from the host kernel. Seccomp, capabilities and namespaces shrink that exposure. They do not remove it.

For code that is plainly hostile, use an application kernel or a virtual machine. See which sandbox fits which code.

Also remember what you did not isolate: the image itself. An image with vulnerable packages or unknown provenance is a risk before your script even runs, so scan it.

Try it yourself

Click through it at your own pace, or open it full screen.

Run through the scan and look at how findings are grouped by layer and package, which is what you want to see before you run an unfamiliar image.

Quick check

Is a read only root filesystem enough on its own?

No. It blocks writes to the image, but the process can still use the network, memory and CPU unless you limit them.

Why drop all capabilities if I run as a non root user?

Defense in depth. A non root user already holds fewer privileges, and dropping capabilities removes what remains if the process finds a way to raise its privilege.

Safeguard scans images and dependencies, with a free scan at gold.safeguard.sh/scan.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.