anthropics / anthropics/sandbox-runtime
denyRead for ".." and friends
- Dominant language
- TypeScript
- Stars
- 5.2k
- Forks
- 439
- Avg merge
- 2d 9m
- Merged PRs (30d)
- 13
Description
# @anthropic-ai/sandbox-runtime (srt) - Relative Path Issue Analysis
## Problem Summary
The `@anthropic-ai/sandbox-runtime` (srt) does not properly support relative paths like `..` and `../..` in `denyRead` configurations. When such paths are specified, the sandbox **changes the current working directory to the user's home directory** instead of maintaining the expected directory.
## Root Cause
When `denyRead: ["..", "../..", ...]` is configured:
1. **Relative paths are normalized to absolute paths** – The `normalizePathForSandbox()` function converts `..` to the absolute parent directory (e.g., `/tmp` when in `/tmp/srt_test2`)
2. **`denyRead` mounts tmpfs over denied paths** – On Linux, when a path is in `denyRead`, the sandbox mounts a `tmpfs` filesystem over that directory (or `/dev/null` over files) to hide its contents
3. **Mounting tmpfs over parent directories breaks path resolution** – When `/tmp` is covered by tmpfs, the path `/tmp/srt_test2` no longer resolves correctly. The kernel's current directory reference becomes invalid
4. **The sandbox falls back to `$HOME`** – Instead of handling this gracefully, the sandbox/shell changes the working directory to your home directory, causing `pwd` and file operations to behave unexpectedly
## Evidence
### Test Configuration
```json
{
"filesystem": {
"denyRead": [".."],
"allowWrite": ["."],
"denyWrite": []
},
"network": {
"allowedDomains": [],
"deniedDomains": []
}
}
```
### Results
- **`pwd`** returns `/home/username` instead of `/tmp/srt_test2`
- **`ls -la`** shows home directory contents, not the expected directory
- **Files in the original directory become inaccessible**
- **Both relative (`..`) and absolute (`/tmp`) paths** exhibit the same behavior
### Test Commands
```bash
# With denyRead: [".."]
$ srt --settings config.json "pwd"
/home/username
$ srt --settings config.json "ls -la"
# Shows home directory contents
# Without denyRead
$ srt --settings config2.json "pwd"
/tmp/srt_test2
```
## Underlying Code Issues
### 1. Path Normalization (`sandbox-utils.js`)
```javascript
function normalizePathForSandbox(pathPattern) {
const cwd = process.cwd();
// ...
else if (pathPattern.startsWith('./') || pathPattern.startsWith('../')) {
// Convert relative to absolute based on current working directory
normalizedPath = path.resolve(cwd, pathPattern);
}
// ...
}
```
Relative paths are converted to absolute paths based on `process.cwd()` at sandbox initialization time.
### 2. Linux bwrap Implementation (`linux-sandbox-utils.js`)
```javascript
async function generateFilesystemArgs(readConfig, writeConfig, ...) {
// ...
const readDenyPaths = [...(readConfig?.denyOnly || [])];
for (const pathPattern of readDenyPaths) {
const normalizedPath = normalizePathForSandbox(pathPattern);
if (!fs.existsSync(normalizedPath)) {
// ...
continue;
}
const readDenyStat = fs.statSync(normalizedPath);
if (readDenyStat.isDirectory()) {
args.push('--tmpfs', normalizedPath); // Mounts tmpfs over denied directory
} else {
args.push('--ro-bind', '/dev/null', normalizedPath);
}
}
return args;
}
```
This overlays tmpfs on denied directories, making subdirectories inaccessible.
### 3. Missing `--chdir` in bwrap Arguments
The sandbox doesn't explicitly preserve the working directory with bwrap's `--chdir` option, allowing it to change when path resolution fails.
## Related Issues
This is part of a broader pattern of filesystem path handling problems in srt:
- **GitHub Issue #72**: "allowWrite patterns don't work for nested directories on macOS (git clone fails)" – similar path resolution issues
- **Glob patterns on Linux**: The implementation filters out glob patterns on Linux, limiting expressiveness
- **Symlink handling**: The normalization resolves symlinks, which can cause unexpected behavior
## Workarounds
1. **Use absolute paths** instead of relative paths in configurations
2. **Avoid `denyRead` on parent directories** of your working directory
3. **Set explicit `allowWrite` paths** that don't conflict with `denyRead` rules
4. **Consider the working directory** when designing sandbox policies
## Security Implications
While the sandbox still provides security isolation (denied paths remain inaccessible), the unexpected change in working directory can:
- Cause confusion and misconfiguration
- Potentially lead to unintended file access if scripts rely on relative paths
- Break tools that depend on the current working directory
## Conclusion
The `@anthropic-ai/sandbox-runtime` doesn't properly support relative paths like `..` and `../..` because its security model (mounting tmpfs over denied directories) conflicts with maintaining a valid current working directory. When parent directories are denied read access, path resolution fails and the sandbox falls back to the user's home directory rather than preserving or gracefully handling the invalid working directory state.
This appears to be a design limitation rather than a simple bug, requiring architectural changes to properly support relative path restrictions while maintaining working directory integrity.
---
**Investigation Date**: 2025-01-27
**srt Version**: 0.0.19
**Test Platform**: Linux
Description written by an llm, but the issue is real!
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.