Skip to content

Commit 82a1141

Browse files
fix(scripts): enforce config integrity check in non-root mode (NVIDIA#1071)
* sec(scripts): enforce config integrity check in non-root mode In non-root mode, verify_config_integrity() failure was logged as a warning but execution continued, allowing a tampered openclaw.json to be loaded. The root path correctly treats this as fatal. Make the non-root path consistent: exit 1 on integrity failure so a modified config is never silently accepted regardless of the execution mode. Closes NVIDIA#1013 * test(scripts): add regression tests for non-root config integrity exit Verify that the non-root code path exits on verify_config_integrity failure and does not contain the old "proceeding anyway" fallback. Also verify both root and non-root paths call verify_config_integrity. Signed-off-by: latenighthackathon <latenighthackathon@users.noreply.github.com> --------- Signed-off-by: latenighthackathon <latenighthackathon@users.noreply.github.com> Co-authored-by: latenighthackathon <latenighthackathon@users.noreply.github.com> Co-authored-by: KJ <kejones@nvidia.com>
1 parent 6d06818 commit 82a1141

2 files changed

Lines changed: 22 additions & 1 deletion

File tree

‎scripts/nemoclaw-start.sh‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,8 @@ if [ "$(id -u)" -ne 0 ]; then
295295
echo "[gateway] Running as non-root (uid=$(id -u)) — privilege separation disabled"
296296
export HOME=/sandbox
297297
if ! verify_config_integrity; then
298-
echo "[SECURITY WARNING] Config integrity check failed — proceeding anyway (non-root mode)"
298+
echo "[SECURITY] Config integrity check failed — refusing to start (non-root mode)"
299+
exit 1
299300
fi
300301
write_auth_profile
301302

‎test/nemoclaw-start.test.js‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,24 @@ describe("nemoclaw-start non-root fallback", () => {
1515
expect(src).toMatch(/touch \/tmp\/gateway\.log/);
1616
expect(src).toMatch(/nohup "\$OPENCLAW" gateway run >\/tmp\/gateway\.log 2>&1 &/);
1717
});
18+
19+
it("exits on config integrity failure in non-root mode", () => {
20+
const src = fs.readFileSync(START_SCRIPT, "utf-8");
21+
22+
// Non-root block must call verify_config_integrity and exit 1 on failure
23+
expect(src).toMatch(
24+
/if ! verify_config_integrity; then\s+.*exit 1/s,
25+
);
26+
// Must not contain the old "proceeding anyway" fallback
27+
expect(src).not.toMatch(/proceeding anyway/i);
28+
});
29+
30+
it("calls verify_config_integrity in both root and non-root paths", () => {
31+
const src = fs.readFileSync(START_SCRIPT, "utf-8");
32+
33+
// The function must be called at least twice: once in the non-root
34+
// if-block and once in the root path below it.
35+
const calls = src.match(/verify_config_integrity/g) || [];
36+
expect(calls.length).toBeGreaterThanOrEqual(3); // definition + 2 call sites
37+
});
1838
});

0 commit comments

Comments
 (0)