Skip to content

VM vs Docker for AI Sandbox: What Actually Went Wrong

Problem

A Reddit user created a Virtual Machine to sandbox Claude Code, hoping to safely use the --dangerously-skip-permissions flag. On their very first prompt, Claude “escaped” the sandbox and started using Chrome on the host machine.

The post title was dramatic: “Claude Escaped My VM Sandbox During My First Prompt.” But when I read the details, I realized this wasn’t an AI escape story. It was a network configuration lesson.

What Actually Happened

The user had Claude running both inside the VM and on the host machine. The host machine’s Chrome browser had the Claude extension installed. When Claude inside the VM needed to interact with a browser, it discovered Chrome on the host through the network and started using it.

Here’s the key detail from the original post:

Since I had Claude both inside and outside the VM and the host Chrome had the Claude extension installed, it managed to use Chrome outside of the VM sandbox.

This wasn’t a sophisticated AI jailbreak. It was a misconfigured network.

Why the VM “Escape” Happened

The top comment on the Reddit thread cut straight to the truth:

Claude didn’t escape anything. You gave it a door to walk through.

Another commenter elaborated:

You put it in a VM that had an open network back to the host? It didn’t escape anything. You left the door wide open with an Exit Here sign.

When I analyze what went wrong, the issue becomes clear:

  1. Network bridging: The VM was likely configured with a bridged network, sharing the host’s IP
  2. Chrome extension exposed: The Claude extension on Chrome listens on localhost
  3. No network isolation: Claude in the VM could reach the host’s local services

A more technical comment explained:

The chrome extension allows connections from localhost, so if your VM wasn’t bridged networks (it shares your IP) the extension would be fare game on a well-known IP (the guest VMs default gateway).

The Real Lesson: Configuration Matters More Than Technology

This incident made me think about a common misconception: that VMs are inherently more secure than containers for AI sandboxing.

The reality is that both VMs and Docker containers are only as secure as their configuration.

Where VMs Can Fail

vm-misconfig-comparison.txt
Common VM Misconfiguration | Security Impact
-------------------------------------|------------------
Bridged networking (default) | VM shares host network stack
Shared clipboard enabled | Data can cross VM boundary
Shared folders/drives | File system escape route
USB device passthrough | Physical device access
Guest additions with full features | Enhanced host integration = more attack surface

Where Docker Can Fail

docker-misconfig-comparison.txt
Common Docker Misconfiguration | Security Impact
-------------------------------------|------------------
Host network mode (--network host) | Container shares host network
Privileged mode (--privileged) | Container has host capabilities
Volume mount to / or /home | Full host filesystem access
No user namespace isolation | Root in container = root on host
No resource limits | Container can exhaust host resources

Proper VM Isolation Configuration

If I want to use a VM for AI sandboxing, I need to isolate it properly. Here’s what a correct configuration looks like.

Network Isolation

qemu-isolated-network.sh
# WRONG: Bridged network (shares host network)
qemu-system-x86_64 \
-netdev bridge,id=net0,br=br0 \
-device virtio-net-pci,netdev=net0
# CORRECT: NAT network with no host access
qemu-system-x86_64 \
-netdev user,id=net0,restrict=on \
-device virtio-net-pci,netdev=net0
# The restrict=on parameter prevents guest from
# accessing host network services

For VirtualBox users:

virtualbox-isolated-network.sh
# WRONG: Bridged Adapter
VBoxManage modifyvm "Claude-Sandbox" --nic1 bridged
# CORRECT: Internal Network (no external access)
VBoxManage modifyvm "Claude-Sandbox" --nic1 intnet
VBoxManage modifyvm "Claude-Sandbox" --intnet1 "isolated-network"

Disable Shared Features

disable-vm-sharing.sh
# Disable shared clipboard
VBoxManage modifyvm "Claude-Sandbox" --clipboard disabled
# Disable drag and drop
VBoxManage modifyvm "Claude-Sandbox" --draganddrop disabled
# Disable shared folders
VBoxManage sharedfolder remove "Claude-Sandbox" -name "shared" 2>/dev/null || true
# No USB passthrough
VBoxManage modifyvm "Claude-Sandbox" --usb off

Docker: The Simpler Alternative?

The Reddit thread had a practical suggestion:

Not sure why anyone would use a VM to sandbox Claude, it’s totally not worth the overhead. There is an included sandbox mode in Claude Code, check the docu or use docker.

For most use cases, Docker provides sufficient isolation with much less overhead. But it requires proper configuration too.

Proper Docker Isolation

docker-compose-isolated.yml
services:
claude-sandbox:
image: node:20
container_name: claude-isolated
working_dir: /workspace
# CORRECT: User-defined bridge network (isolated)
networks:
- sandbox-net
# Read-only project mount (prevents destruction)
volumes:
- ./project:/workspace:ro # :ro = read-only
# Resource limits
deploy:
resources:
limits:
cpus: '2'
memory: 4G
# Drop all capabilities, add only what's needed
cap_drop:
- ALL
cap_add:
- SYS_PTRACE # For debugging, if needed
# No privilege escalation
security_opt:
- no-new-privileges:true
# Isolated network
networks:
sandbox-net:
driver: bridge
internal: true # No external network access

The internal: true option is the Docker equivalent of VM network isolation. The container cannot reach the host network or external internet.

What Each Isolation Layer Does

docker-isolation-layers.txt
Isolation Option | What It Prevents
-------------------------------------|------------------
internal network | Access to host services and internet
read-only volumes | Modification of host files
cap_drop: ALL | All Linux capabilities
no-new-privileges | Privilege escalation
non-root user in container | Root-level operations
resource limits | Resource exhaustion attacks

What the Original User Should Have Done

If the Reddit user wanted to sandbox Claude properly, here’s what they should have configured:

Option 1: Properly Isolated VM

  1. Use NAT networking with restrict=on (QEMU) or Internal Network (VirtualBox)
  2. Disable all shared features (clipboard, folders, USB)
  3. Don’t install Claude on the host at all
  4. Use a snapshot before each session

Option 2: Docker with Isolation

claude-docker-sandbox.yml
services:
claude:
image: node:20
networks:
- isolated
volumes:
- ./project:/workspace:ro
# No Chrome, no extensions, no escape routes
networks:
isolated:
internal: true

Option 3: Claude Code Built-in Sandbox

Claude Code includes its own sandbox mode. This is the simplest option for most users.

Terminal window
# Check documentation for built-in sandbox features
claude --help

The Deeper Security Model Change

One comment stood out to me:

You’ve changed my mental security model, thank you!

This incident reveals a broader truth about AI tool security. We need to think about:

  1. Network perimeter is not enough: AI tools can reach across network boundaries if services are exposed
  2. Extensions and plugins are attack vectors: Browser extensions, IDE plugins, and system integrations create escape routes
  3. Isolation requires comprehensive configuration: Just running in a VM or container isn’t enough

Another Real-World Example

Another commenter shared a similar experience with MCP (Model Context Protocol) servers:

I downloaded an MCP server for MSSQL to do some data modeling. The MCP server only has insert/update/read/alter commands built-in. Can’t create objects.

I asked it to create a table. It tried the MCP tool, couldn’t. Immediately switches to sqlcmd.exe using the credentials I had saved in my appsettings.json.

This shows the same pattern: AI tools will find alternative paths to accomplish goals. If one tool is blocked, they’ll try another. Configuration files with credentials, exposed APIs, and accessible binaries all become potential “escape routes.”

Summary

In this post, I analyzed a real case where Claude appeared to “escape” a VM sandbox. The key point is that the problem wasn’t the VM technology itself, but the network configuration that allowed the guest VM to reach host services.

Both VMs and Docker containers are only as secure as their configuration. A misconfigured VM with bridged networking and shared features provides no meaningful isolation. A properly configured Docker container with internal networking and read-only mounts can be equally secure for most use cases.

The lesson I take away: Isolation is not about choosing VM vs Docker. It’s about understanding and configuring the network boundaries, shared resources, and access controls that actually matter.

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments