fix: replace predictable temp filenames with mkdtempSync#1105
fix: replace predictable temp filenames with mkdtempSync#1105BenediktSchackenberg wants to merge 3 commits intoNVIDIA:mainfrom
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughReplaced predictable temp filenames with a secure helper that creates an mkdtemp-scoped temp dir and returns a unique temp file path. Updated probe/model download helpers and sandbox sync writer to use the helper and to clean up only the mkdtemp-created parent directory. Removed caller-controlled tmpDir from sandbox writer. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Pull request overview
This PR addresses a local symlink/TOCTOU risk caused by predictable temporary filenames in onboarding probe/model-fetch helpers by switching to fs.mkdtempSync()-backed temp paths.
Changes:
- Added a
secureTempFile(prefix, ext)helper to generate temp file paths inside mkdtemp-created directories. - Replaced 6 predictable
/tmp/...Date.now()+Math.random()temp filename constructions withsecureTempFile(...). - Updated the sandbox sync script test to assert the new mkdtemp-based path shape and to clean up the created temp directory.
Reviewed changes
Copilot reviewed 1 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
bin/lib/onboard.js |
Introduces secureTempFile and migrates probe/model-fetch/sync-script temp paths away from predictable names. |
test/onboard.test.js |
Adjusts the sandbox sync temp-file test for mkdtemp-based paths and cleans up the temp directory. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@bin/lib/onboard.js`:
- Around line 539-543: The temp directories created by secureTempFile() are
never removed; modify writeSandboxConfigSyncFile (and all places that delete the
returned temp file) to remove the temp file's parent directory instead of only
unlinking the file. Specifically: when cleaning up values returned by
secureTempFile() (e.g., the path produced by writeSandboxConfigSyncFile and
other secureTempFile callers), compute the parent directory
(path.dirname(returnedPath)) and remove that directory (recursively/forcibly)
rather than just fs.unlink/fs.unlinkSync on the file; update all cleanup sites
that currently unlink the file to remove the parent dir to avoid leaving empty
temp dirs.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: ed611c39-c8ec-4bbc-a2aa-ea9a3e893649
📒 Files selected for processing (2)
bin/lib/onboard.jstest/onboard.test.js
|
✨ Thanks for submitting this PR with a detailed summary, it addresses a security bug with predictable temp filenames and proposes a fix to improve the security of NemoClaw, which could prevent potential vulnerabilities. |
Six functions in onboard.js created temporary files using Date.now() and Math.random().toString(36), both of which are predictable. A local attacker could win a race to pre-create a symlink at the predicted path in /tmp, redirecting curl output (API responses, model data) or injecting a malicious script via writeSandboxConfigSyncFile. Replace all six call sites with a secureTempFile() helper that uses fs.mkdtempSync() — the same approach already used securely at lines 1781 and 2710. Each temp file now lives inside its own directory with an OS-level cryptographically random suffix. The remaining Date.now() usage in patchStagedDockerfile is a build identifier written into the Dockerfile, not a temp filename — left as-is. Fixes: NVIDIA#1093
4884e10 to
9b7898d
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@test/onboard.test.js`:
- Line 442: The cleanup call unconditionally calls
fs.rmSync(path.dirname(scriptFile), { recursive: true, force: true }) which can
delete the system temp root if writeSandboxConfigSyncFile regresses; before
calling fs.rmSync, add a strict guard that ensures the target dir is a
subdirectory of os.tmpdir() (e.g., compute tempRoot = os.tmpdir(), targetDir =
path.resolve(path.dirname(scriptFile)), then verify targetDir !== tempRoot and
path.relative(tempRoot, targetDir) does not start with '..' and does start with
the path.sep or a non-empty relative path) and only then perform fs.rmSync;
reference path.dirname(scriptFile), writeSandboxConfigSyncFile, fs.rmSync and
os.tmpdir() when locating the code to change.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: dc7963be-a3e1-484e-81dc-0ee47bbe65a4
📒 Files selected for processing (2)
bin/lib/onboard.jstest/onboard.test.js
🚧 Files skipped from review as they are similar to previous changes (1)
- bin/lib/onboard.js
Add cleanupTempDir() helper that verifies the parent directory was actually created by secureTempFile() (checks prefix match and is not os.tmpdir() itself) before calling fs.rmSync recursive. This prevents a regression in secureTempFile from accidentally wiping the system temp root. Addresses CodeRabbit review on test and production cleanup sites.
Summary
Six functions in
bin/lib/onboard.jscreate temporary files usingDate.now()andMath.random().toString(36), both of which are predictable. A local attacker can win a TOCTOU race to pre-create a symlink at the predicted path in/tmp, enabling:writeSandboxConfigSyncFile, inject a malicious script that gets piped intoopenshell sandbox connectChanges
bin/lib/onboard.js:secureTempFile(prefix, ext)helper that usesfs.mkdtempSync()(OS-levelmkdtempsyscall with cryptographically random suffix)probeOpenAiLikeEndpoint(line ~667)probeAnthropicEndpoint(line ~711)fetchNvidiaEndpointModels(line ~857)fetchOpenAiLikeModels(line ~911)fetchAnthropicModels(line ~947)writeSandboxConfigSyncFile(line ~527)test/onboard.test.js:Why this approach
The file already uses
fs.mkdtempSync()securely in two other places (lines 1781 and 2710), making this fix consistent with existing code patterns rather than introducing new dependencies.The remaining
Date.now()usage inpatchStagedDockerfileis a build identifier written into the Dockerfile, not a temp filename — left unchanged.Fixes #1093
Summary by CodeRabbit
Refactor
Tests