10 KiB
Code Execution Security Guide
Overview
The execute_code tool runs bash scripts in isolated subprocesses using landrun (Landlock LSM). This document covers the security model, threat analysis, and configuration.
Security Architecture
Agent (Model)
↓ generates bash code
anvilmcp (validates)
↓ spawns subprocess
landrun (Landlock sandbox)
↓ restricts filesystem/network
bash subprocess
↓ executes code
↓ accesses 9P via socket
anvilsrv (9P server)
Isolation Mechanisms
1. Landlock LSM (Kernel-Enforced)
Landlock provides mandatory access control at the kernel level. Restrictions cannot be bypassed by the subprocess.
Filesystem restrictions:
- rwx:
~/.cache/anvillm/exec/<workspace>(workspace only) - ro:
/usr,/lib,/lib64,/bin,/etc/alternatives,/etc/ld.so.cache(system binaries) - rw:
$NAMESPACE(9P socket) - Everything else: denied
Network: Not explicitly restricted (relies on outer landrun if needed)
Nested sandboxes: Inner landrun can only add MORE restrictions, never relax them. Restrictions stack.
2. Workspace Isolation
Each execution gets a fresh temporary directory:
- Path:
~/.cache/anvillm/exec/anvilmcp-<random> - Permissions: 0700 (user-only)
- Lifecycle: Created before execution, deleted after
- Working directory: Set to workspace
Scripts can only write to their workspace. All other filesystem locations are read-only or denied.
3. Resource Limits
Timeout: 30 seconds default (configurable per call)
- Enforced via context.WithTimeout
- Subprocess killed on timeout
- Logged as security event
Output size: 10 MB maximum
- Enforced via limitedWriter
- Prevents memory exhaustion
- Returns error if exceeded
Concurrency: 3 simultaneous executions maximum
- Enforced via semaphore
- Prevents resource exhaustion
- Blocks until slot available
4. Code Validation
Dangerous patterns rejected before execution:
rm -rf /- Filesystem destruction:(){ :|:& };:- Fork bombmkfs- Filesystem formattingdd if=/dev/zero- Device writeschmod 777- Permission escalationcurl http/wget http- Network access> /dev/- Device writesexec(/eval(- Code injection
Validation is basic pattern matching. Not comprehensive - relies on sandbox for enforcement.
Threat Model
Threat 1: Malicious Code Injection
Scenario: Agent generates malicious bash code
Risk: LOW
Mitigations:
- Agent-generated code (not user input)
- Landlock restricts filesystem access
- Workspace isolation
- Code validation (basic)
- Timeout enforcement
Residual risk: Agent could generate code that consumes CPU within timeout, or writes garbage to workspace. Acceptable for trusted agents.
Threat 2: Sandbox Escape
Scenario: Subprocess breaks out of landrun restrictions
Risk: LOW
Mitigations:
- Landlock is kernel-enforced (not userspace)
- No known Landlock bypasses (as of kernel 5.13+)
- Nested sandboxes only add restrictions
- No setuid binaries in allowed paths
Residual risk: Kernel vulnerability in Landlock. Mitigated by keeping kernel updated.
Threat 3: Resource Exhaustion
Scenario: Code consumes excessive CPU, memory, or disk
Risk: MEDIUM
Mitigations:
- Timeout (30s default)
- Output size limit (10 MB)
- Concurrency limit (3 max)
- Workspace cleanup on completion
Residual risk: CPU exhaustion within timeout window. Could add ulimit for CPU/memory if needed.
Threat 4: Data Exfiltration
Scenario: Sensitive data leaked from subprocess
Risk: LOW (Improved from direct tools)
Mitigations:
- Data stays in subprocess (not in context)
- Only summary/results returned
- No network access (unless explicitly granted)
- 9P socket access controlled by outer sandbox
Residual risk: Data could be written to workspace, but workspace is deleted. Data could be sent via 9P to other agents - same risk as direct tools.
Threat 5: 9P Socket Access
Scenario: Subprocess abuses 9P access to read/write unauthorized data
Risk: MEDIUM (Same as direct tools)
Mitigations:
- 9P socket permissions (Unix socket, user-only)
- anvilsrv enforces access control
- Audit logging in anvilsrv
Residual risk: If subprocess has 9P access, it has same capabilities as direct tool calls. This is by design - code execution is meant to replace direct tools.
Threat 6: Path Traversal
Scenario: Agent reads tools outside mcptools directory
Risk: LOW
Mitigations:
- Filename validation (reject
..and/) - 9P path normalization
- Direct file read from known directory
Residual risk: None - path traversal blocked at multiple layers.
Security Benefits vs Direct Tools
Improved:
- Data isolation (subprocess)
- Privacy preservation (PII doesn't enter context)
- Explicit control over data flow
- Workspace isolation
Same:
- 9P socket access control
- Process isolation
- Agent trust model
Additional Considerations:
- Code validation required
- Sandbox configuration complexity
- Resource limit tuning
Conclusion: Code execution improves security posture compared to direct tool calls, with acceptable additional complexity.
Configuration
Adjusting Timeout
Default: 30 seconds
Increase for long-running operations:
execute_code with code: "..." timeout: 120
Decrease for quick operations:
execute_code with code: "..." timeout: 5
Adjusting Output Limit
Default: 10 MB
To change, edit cmd/anvilmcp/execute.go:
limitedWriter := &limitedWriter{w: &outputBuf, limit: 50 * 1024 * 1024} // 50 MB
Adjusting Concurrency
Default: 3 simultaneous executions
To change, edit cmd/anvilmcp/main.go:
executionSemaphore = make(chan struct{}, 10) // 10 concurrent
Adding Filesystem Paths
To grant access to additional paths, edit cmd/anvilmcp/execute.go:
cmd = exec.CommandContext(ctx, landrunPath,
"-rwx", workDir,
"-ro", "/usr",
"-ro", "/additional/path", // Add here
// ...
)
Warning: Only add paths that are safe for agent access. Avoid home directory, /etc, /var.
Disabling Network Access
Network is not explicitly restricted by default. To block:
- Use outer landrun with network restrictions
- Or add iptables rules for the user
- Or use network namespaces
Example outer landrun:
landrun -no-net -- anvilmcp
Monitoring
Execution Logs
Location: ~/.cache/anvillm/logs/anvilmcp-exec.log
Fields:
- Timestamp
- Code hash (SHA256)
- Language
- Duration
- Success/failure
- Output size
- Error message
Security Events
Location: ~/.cache/anvillm/logs/anvilmcp-security.log
Events:
- Validation failures (dangerous patterns)
- Timeouts
- Output size limit exceeded
- Sandbox errors
Monitoring Commands
Check recent executions:
tail -f ~/.cache/anvillm/logs/anvilmcp-exec.log
Check security events:
grep -i error ~/.cache/anvillm/logs/anvilmcp-security.log
Count executions by status:
jq -r '.Success' ~/.cache/anvillm/logs/anvilmcp-exec.log | sort | uniq -c
Incident Response
Suspicious Activity
If you observe suspicious code execution:
- Check security logs for validation failures
- Review agent context/prompts for anomalies
- Check workspace contents (if not yet deleted)
- Review 9P access logs in anvilsrv
Sandbox Escape Attempt
If you suspect sandbox escape:
- Kill all anvilmcp processes immediately
- Check kernel logs:
dmesg | grep landlock - Review Landlock version:
uname -r(need 5.13+) - Update kernel if outdated
- Report to security team
Resource Exhaustion
If system becomes unresponsive:
- Kill anvilmcp:
pkill -9 anvilmcp - Check running subprocesses:
ps aux | grep bash - Review execution logs for long-running operations
- Adjust timeout/concurrency limits
- Consider adding ulimit restrictions
Best Practices
For Agents
- Minimize code complexity: Simple scripts are easier to validate
- Use timeouts: Don't rely on default, specify appropriate timeout
- Handle errors: Check exit codes, parse stderr
- Limit output: Filter/aggregate in subprocess, return summaries
- Clean up: Don't leave large files in workspace (auto-deleted anyway)
For Operators
- Monitor logs: Regular review of execution and security logs
- Update kernel: Keep Landlock up-to-date
- Tune limits: Adjust timeout/concurrency based on workload
- Audit access: Review 9P access patterns
- Test sandbox: Periodically verify restrictions are enforced
For Developers
- Validate inputs: Don't trust agent-generated code blindly
- Fail closed: Reject on validation error, don't execute
- Log everything: Execution attempts, failures, security events
- Test escapes: Regularly test sandbox with malicious code
- Update patterns: Add new dangerous patterns as discovered
Testing Sandbox
Verify restrictions are enforced:
Test 1: Filesystem Write Outside Workspace
execute_code with code: "echo test > /tmp/escape.txt"
# Expected: Permission denied
Test 2: Read Sensitive Files
execute_code with code: "cat /etc/shadow"
# Expected: Permission denied
Test 3: Network Access
execute_code with code: "curl http://example.com"
# Expected: Command not found or network unreachable
Test 4: Fork Bomb
execute_code with code: ":(){ :|:& };:"
# Expected: Validation error (rejected before execution)
Test 5: Timeout
execute_code with code: "sleep 60" timeout: 5
# Expected: Timeout after 5 seconds
Test 6: Output Limit
execute_code with code: "dd if=/dev/zero bs=1M count=20"
# Expected: Output size limit exceeded
All tests should fail safely without compromising the system.
References
- Landlock documentation: https://docs.kernel.org/userspace-api/landlock.html
- landrun: https://github.com/zouuup/landrun
- Anthropic code execution pattern: https://www.anthropic.com/engineering/code-execution-with-mcp
- User guide: ./code-execution-user-guide.md
- Migration guide: ./code-execution-migration-guide.md