Skip to content

fix(security): enforce secure permissions on openclaw.json during migration#187

Merged
drobison00 merged 1 commit intoNVIDIA:mainfrom
dumko2001:fix/h17-openclaw-json-perms
Mar 23, 2026
Merged

fix(security): enforce secure permissions on openclaw.json during migration#187
drobison00 merged 1 commit intoNVIDIA:mainfrom
dumko2001:fix/h17-openclaw-json-perms

Conversation

@dumko2001
Copy link
Copy Markdown
Contributor

@dumko2001 dumko2001 commented Mar 17, 2026

Rationale

openclaw.json contains sensitive session and routing data that should never be world-readable.

Changes

Added chmodSync(0o600) to all migration-state file write/copy operations.

Verification Results

  • Automated Tests: Passed all 52 core tests via npm test.
  • Manual Audit: Verified 600 mode on host-side config after migration.
  • Security Review: Verified no sensitive data leaks and correct permission enforcement.

Summary by CodeRabbit

  • Bug Fixes
    • Enhanced file permission handling for configuration files during migration and restoration processes to ensure proper access control and security.

@wscurran wscurran added security Something isn't secure priority: high Important issue that should be resolved in the next release labels Mar 19, 2026
@cv
Copy link
Copy Markdown
Contributor

cv commented Mar 21, 2026

Hey @dumko2001, enforcing secure permissions on openclaw.json during migration is important — good catch. The repo has been moving fast though. A rebase onto main would let us review this properly.

@dumko2001 dumko2001 force-pushed the fix/h17-openclaw-json-perms branch from 9f9dc6d to cdd2a17 Compare March 21, 2026 21:27
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 21, 2026

📝 Walkthrough

Walkthrough

The changes add file permission restrictions (0o600) to openclaw.json configuration files in three scenarios: sandbox preparation, snapshot bundle creation, and external config restoration. This restricts read and write access to the file owner only.

Changes

Cohort / File(s) Summary
File Permission Restrictions
nemoclaw/src/commands/migration-state.ts
Added chmodSync calls to apply 0o600 permissions to openclaw.json files in three locations: during sandbox state preparation, snapshot bundle creation with external config, and external config restoration.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Poem

🐰 Three locks now guard our config files tight,
Each openclaw.json secured day and night,
With 0o600 permissions set just right,
Only the owner can read by candlelight! 🔐

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: enforcing secure file permissions (0o600) on openclaw.json files during migration operations.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@dumko2001
Copy link
Copy Markdown
Contributor Author

@cv this pr was autoclosed because of the 10 pr limit so can u check if you need to reopen it. #189

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
nemoclaw/src/commands/migration-state.ts (1)

681-690: ⚠️ Potential issue | 🟡 Minor

Apply explicit permission enforcement to internal config during restore.

When hasExternalConfig is false, the internal openclaw.json inside stateDir is restored via copyDirectory() at line 682 without explicit permission enforcement. For consistency with external config handling (which receives chmodSync(0o600) at line 688), the internal config should also be explicitly chmod'd to 0o600 if it exists in the restored state.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@nemoclaw/src/commands/migration-state.ts` around lines 681 - 690, The restore
path uses copyDirectory(snapshotStateDir, manifest.stateDir) to restore internal
config when manifest.hasExternalConfig is false, but it doesn't explicitly set
secure permissions; after the directory copy, check for the internal config file
at path.join(manifest.stateDir, "config", "openclaw.json") and, if it exists,
call chmodSync(..., 0o600) (mirroring the external config branch that uses
copyFileSync and chmodSync) and log the restoration (use logger.info) so
internal config permissions are enforced consistently; update the code near the
copyDirectory call and reuse manifest.stateDir, hasExternalConfig,
copyDirectory, chmodSync, and logger identifiers to locate where to add this.
🧹 Nitpick comments (1)
nemoclaw/src/commands/migration-state.ts (1)

563-565: Consider using atomic permission setting to eliminate race window.

The current sequence (write then chmod) leaves a brief window where the file exists with default permissions. For sensitive files, you can pass the mode option directly to writeFileSync to set permissions atomically on file creation:

✨ Suggested improvement for atomic permission setting
   const configPath = path.join(preparedStateDir, "openclaw.json");
-  writeFileSync(configPath, JSON.stringify(config, null, 2));
-  chmodSync(configPath, 0o600);
+  writeFileSync(configPath, JSON.stringify(config, null, 2), { mode: 0o600 });

Note: Keep chmodSync as a fallback if the file might already exist (though in this case, the directory is freshly created via rmSync + mkdirSync).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@nemoclaw/src/commands/migration-state.ts` around lines 563 - 565, The current
sequence writes the config file then calls chmodSync, leaving a small race
window; update the write to pass the mode option (e.g.,
writeFileSync(configPath, JSON.stringify(config, null, 2), { mode: 0o600 })) so
the file is created with correct permissions atomically, and keep the existing
chmodSync(configPath, 0o600) as a fallback in case the file already existed;
apply this change around the code that constructs configPath using
preparedStateDir and uses writeFileSync/chmodSync.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@nemoclaw/src/commands/migration-state.ts`:
- Around line 681-690: The restore path uses copyDirectory(snapshotStateDir,
manifest.stateDir) to restore internal config when manifest.hasExternalConfig is
false, but it doesn't explicitly set secure permissions; after the directory
copy, check for the internal config file at path.join(manifest.stateDir,
"config", "openclaw.json") and, if it exists, call chmodSync(..., 0o600)
(mirroring the external config branch that uses copyFileSync and chmodSync) and
log the restoration (use logger.info) so internal config permissions are
enforced consistently; update the code near the copyDirectory call and reuse
manifest.stateDir, hasExternalConfig, copyDirectory, chmodSync, and logger
identifiers to locate where to add this.

---

Nitpick comments:
In `@nemoclaw/src/commands/migration-state.ts`:
- Around line 563-565: The current sequence writes the config file then calls
chmodSync, leaving a small race window; update the write to pass the mode option
(e.g., writeFileSync(configPath, JSON.stringify(config, null, 2), { mode: 0o600
})) so the file is created with correct permissions atomically, and keep the
existing chmodSync(configPath, 0o600) as a fallback in case the file already
existed; apply this change around the code that constructs configPath using
preparedStateDir and uses writeFileSync/chmodSync.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 42e45e9d-ab02-42b4-9574-0da423d804c4

📥 Commits

Reviewing files that changed from the base of the PR and between 255e606 and cdd2a17.

📒 Files selected for processing (1)
  • nemoclaw/src/commands/migration-state.ts

@wscurran wscurran requested a review from drobison00 March 23, 2026 16:40
Copy link
Copy Markdown

@drobison00 drobison00 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good, targeted updates.

@drobison00 drobison00 merged commit 0fcb7e4 into NVIDIA:main Mar 23, 2026
5 of 6 checks passed
Ryuketsukami pushed a commit to Ryuketsukami/NemoClaw that referenced this pull request Mar 24, 2026
alexcode-cc pushed a commit to alexcode-cc/NemoClaw that referenced this pull request Mar 24, 2026
HagegeR pushed a commit to HagegeR/NemoClaw that referenced this pull request Mar 24, 2026
jessesanford pushed a commit to jessesanford/NemoClaw that referenced this pull request Mar 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

priority: high Important issue that should be resolved in the next release security Something isn't secure

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants