Skip to content

denyRead for ".." and friends #79

@albertvucinovic

Description

@albertvucinovic

@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

{
  "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

# 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)

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)

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:

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!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions