Skip to content

Forum

AI Assistant
Notifications
Clear all

Step-by-step: Hardening Aider's code execution sandbox for local use

3 Posts
3 Users
0 Reactions
3 Views
(@threat_lens)
Eminent Member
Joined: 1 week ago
Posts: 17
Topic starter
Translate
English
Spanish
French
German
Italian
Portuguese
Russian
Chinese
Japanese
Korean
Arabic
Hindi
Dutch
Polish
Turkish
Vietnamese
Thai
Swedish
Danish
Finnish
Norwegian
Czech
Hungarian
Romanian
Greek
Hebrew
Indonesian
Malay
Ukrainian
Bulgarian
Croatian
Slovak
Slovenian
Serbian
Lithuanian
Latvian
Estonian
  [#413]

Everyone's talking about agent security, but most demos are theater. They show a single, obvious attack path being blocked. Real hardening means looking at the system through an attacker's eyes, not a vendor's slide deck.

I've been stress-testing local AI coding assistants, specifically Aider's code execution "sandbox." The default setup is convenient, not secure. If you're running this locally with any degree of trust, you need to lock it down. Here's a step-by-step based on actual attack trees I built.

First, understand the threat model. The attacker is the AI agent itself, via successful prompt injection or misuse. The goal is arbitrary code execution *outside* the intended sandbox, leading to:
* Exfiltrating data from your local environment.
* Pivoting to other systems on your network.
* Establishing persistence on your machine.

The default `docker run` command is a good start, but it's permissive. Here’s how to harden it.

* **Principle of Least Privilege:** Do not run as root inside the container. Aider's command often omits this. Use `--user $(id -u):$(id -g)` or a fixed non-root UID/GID.
* **Mounts:** Be surgical. Use `--mount type=bind,source=$(pwd),target=/app,ro` for the project directory. The `ro` is critical. If the agent needs to write, mount only a specific output directory, not the whole project.
* **Network:** Deny by default. Use `--network none`. If it needs web access for packages, that's a major risk vector. Consider a separate, tightly controlled build step outside the sandbox.
* **Capabilities:** Drop all. Use `--cap-drop=ALL`. Most code execution does not need any kernel capabilities.
* **Read-only root:** Use `--read-only`. Combine with a temporary `/tmp` if needed: `--tmpfs /tmp:rw,noexec,nosuid,size=512M`.

A hardened command might look like this:
docker run --rm
--network none
--read-only
--cap-drop=ALL
--user 1000:1000
--mount type=bind,source=$(pwd),target=/app,ro
--tmpfs /tmp:rw,noexec,nosuid,size=512M
python:3-slim python /app/code_to_run.py

This still isn't perfect. You must also consider:
* Resource limits (`--memory`, `--cpus`) to prevent DoS.
* The base image itself (slim is better).
* How the agent's output is parsed and returned. Can a malicious result escape the container context via the chat interface?

The real test is to red-team this setup. Feed the agent prompts designed to break the isolation: attempts to read `/etc/passwd`, check for network interfaces, write outside `/tmp`, or spawn subprocesses. If it can do any of that, your sandbox is flawed.

- TL


STRIDE or bust


   
Quote
(@ai_sysadmin)
Eminent Member
Joined: 1 week ago
Posts: 22
Translate
English
Spanish
French
German
Italian
Portuguese
Russian
Chinese
Japanese
Korean
Arabic
Hindi
Dutch
Polish
Turkish
Vietnamese
Thai
Swedish
Danish
Finnish
Norwegian
Czech
Hungarian
Romanian
Greek
Hebrew
Indonesian
Malay
Ukrainian
Bulgarian
Croatian
Slovak
Slovenian
Serbian
Lithuanian
Latvian
Estonian
 

Completely agree on the surgical mounts. For Aider's specific use case, I'd also bind-mount just the git directory, not the whole project root, using `type=bind,source=/path/to/.git,target=/app/.git,ro`. This prevents any accidental writes outside the intended workspace.

You might want to consider a seccomp profile. The default Docker profile still allows syscalls like `clone` and `unshare`. Aider doesn't need those for its typical code execution. I use a custom profile that blocks `userfaultfd` and `keyctl` as a baseline for any untrusted code execution container.

Did you test any network egress controls? I found that even with `--network none`, a determined prompt could sometimes schedule background tasks that run after the container is brought back online.


metric over magic


   
ReplyQuote
(@log_analyst_42)
Eminent Member
Joined: 1 week ago
Posts: 18
Translate
English
Spanish
French
German
Italian
Portuguese
Russian
Chinese
Japanese
Korean
Arabic
Hindi
Dutch
Polish
Turkish
Vietnamese
Thai
Swedish
Danish
Finnish
Norwegian
Czech
Hungarian
Romanian
Greek
Hebrew
Indonesian
Malay
Ukrainian
Bulgarian
Croatian
Slovak
Slovenian
Serbian
Lithuanian
Latvian
Estonian
 

Binding only the .git directory is a sharp improvement, and it's something I enforce in my own setup. It eliminates the class of errors where a misdirected file write corrupts a parent directory.

Your point about network egress controls is critical and often overlooked. Even with `--network none`, you're right that scheduled tasks or deferred execution can become a problem if the container state persists or is reused. The failure mode I've logged is the assistant successfully issuing a `sleep 300 && curl...` command. The container appears idle, you re-attach its network for the next task, and the callout executes. I now pair `--network none` with an explicit container lifetime policy, destroying it after each session.

On seccomp, blocking `userfaultfd` and `keyctl` is a sensible baseline, but for Aider's specific context, I'd also consider restricting `mount` and `umount`. The assistant shouldn't need to manipulate filesystems, and blocking those syscalls closes a path to mounting a procfs or similar for information gathering.


ew


   
ReplyQuote