Skip to content

[NemoClaw][All platforms] [PR#1121]Sandbox user can write and delete config files in sandbox-base image #1608

@zNeill

Description

@zNeill

Description

Description

PR: fix(sandbox): restrict /sandbox to read-only via Landlock

The sandbox-base Docker image (ghcr.io/nvidia/nemoclaw/sandbox-base:latest) does not enforce read-only permissions on /sandbox/.openclaw/openclaw.json and /sandbox/.openclaw/.config-hash for the sandbox user. The sandbox user can successfully write to and delete both config files, violating the intended security model.

According to the production Dockerfile on the security/read-only-sandbox-filesystem branch, these files should be:

  • Owned by root:root
  • Permission 444 (read-only for all)
  • Additionally protected by Landlock LSM at runtime

However, the current sandbox-base image does not apply these permission restrictions, meaning these hardening steps are either missing from the base image layer or have not been merged and published yet.

Environment

  • OS: Ubuntu (Linux 6.17.0-1008-nvidia, aarch64)
  • Node.js: v22.22.2
  • Docker: 29.1.3
  • NemoClaw: v0.1.0
  • Branch: security/read-only-sandbox-filesystem (commit 0d85225)
  • Image: ghcr.io/nvidia/nemoclaw/sandbox-base:latest (46581a73edba)

Steps to Reproduce

  1. Pull the current sandbox-base image:
    docker pull ghcr.io/nvidia/nemoclaw/sandbox-base:latest
  2. Run the SEC-3 validation command:
    docker run --rm --entrypoint "" ghcr.io/nvidia/nemoclaw/sandbox-base:latest gosu sandbox python3 -c "
    import os
    
    for path in ['/sandbox/.openclaw/openclaw.json', '/sandbox/.openclaw/.config-hash']:
        name = os.path.basename(path)
        for op, fn in [
            ('WRITE', lambda p=path: open(p, 'w').write('x')),
            ('DELETE', lambda p=path: os.unlink(p)),
            ('RENAME', lambda p=path: os.rename(p, p + '.bak'))
        ]:
            try:
                fn()
                print(f'{op}_{name}=SUCCEEDED')
            except (PermissionError, OSError):
                print(f'{op}_{name}=BLOCKED')
    "
  3. Observe output:
    WRITE_openclaw.json=SUCCEEDED
    DELETE_openclaw.json=SUCCEEDED
    RENAME_openclaw.json=BLOCKED
    WRITE_.config-hash=SUCCEEDED
    DELETE_.config-hash=SUCCEEDED
    RENAME_.config-hash=BLOCKED

Analysis

The production Dockerfile on the security/read-only-sandbox-filesystem branch contains the correct permission hardening:

chmod 444 /sandbox/.openclaw/openclaw.json
chown root:root /sandbox/.openclaw/openclaw.json
chmod 444 /sandbox/.openclaw/.config-hash
chown root:root /sandbox/.openclaw/.config-hash

These settings are not present in the published sandbox-base image. The fix requires either:

  1. Moving the permission hardening into the base image build (Dockerfile.base), or
  2. Rebuilding and republishing the image from the production Dockerfile that already includes these changes.

Expected Behavior

All 6 operations should be blocked:

WRITE_openclaw.json=BLOCKED
DELETE_openclaw.json=BLOCKED
RENAME_openclaw.json=BLOCKED
WRITE_.config-hash=BLOCKED
DELETE_.config-hash=BLOCKED
RENAME_.config-hash=BLOCKED

Actual Behavior

WRITE and DELETE succeed for both files. Only RENAME is blocked because the files were already deleted by the preceding DELETE operation.

Bug Details

Field Value
Priority Unprioritized
Action Dev - Open - To fix
Disposition Open issue
Module Machine Learning - NemoClaw
Keyword NemoClaw, NEMOCLAW_GH_SYNC_APPROVAL, NemoClaw-SWQA-RelBlckr-Recommended

[NVB# 6059424]

[NVB#6059424]

Metadata

Metadata

Assignees

Labels

DockerSupport for Docker containerizationNV QABugs found by the NVIDIA QA TeamPlatform: UbuntuSupport for Linux UbuntuUATIssues flagged for User Acceptance Testing.bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions