Skip to content

Fix #166: Quote sandbox names in shell commands#335

Closed
hkc5 wants to merge 3 commits intoNVIDIA:mainfrom
hkc5:fix-sandbox-name-quoting
Closed

Fix #166: Quote sandbox names in shell commands#335
hkc5 wants to merge 3 commits intoNVIDIA:mainfrom
hkc5:fix-sandbox-name-quoting

Conversation

@hkc5
Copy link
Copy Markdown

@hkc5 hkc5 commented Mar 18, 2026

Summary

  • Add shellEscape() helper function that wraps strings in single quotes and safely handles embedded single quotes (replacing the previous "${sandboxName}" double-quote interpolation)
  • Apply shellEscape() to all three shell commands that use sandboxName:
    • openshell sandbox delete
    • openshell sandbox create --name
    • openshell forward start

This is a re-submission of the quoting fix originally in PR #211, which was accidentally opened with main as both the head and base branch. Only the quoting/escaping changes are included here — the lowercase normalization changes are tracked separately in PR #212.

Test plan

  • Onboard with a normal sandbox name (e.g. my-assistant) — should work as before
  • Verify shellEscape() correctly handles names containing single quotes (e.g. it's) — should produce 'it'"'"'s'
  • Verify the three shell invocations (sandbox delete, sandbox create --name, forward start) all use the escaped name

Summary by CodeRabbit

  • Bug Fixes
    • Improved safety of sandbox commands so names with special or shell-sensitive characters no longer cause failures.
    • Increased reliability of sandbox lifecycle actions (create, delete, connect, port forwarding) without changing public interfaces or behavior.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 18, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 63035e49-4a65-445a-a015-aae9e21fa73b

📥 Commits

Reviewing files that changed from the base of the PR and between 09afb41 and 691ceb9.

📒 Files selected for processing (1)
  • bin/lib/onboard.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • bin/lib/onboard.js

📝 Walkthrough

Walkthrough

Multiple openshell CLI invocations in createSandbox() were changed to remove double-quoted interpolation of sandboxName and instead wrap the value with shellQuote(sandboxName) for all commands that passed the sandbox name.

Changes

Cohort / File(s) Summary
Shell quoting in CLI invocations
bin/lib/onboard.js
Replaced double-quoted ${sandboxName} usages with ${shellQuote(sandboxName)} in openshell sandbox get, openshell sandbox delete, --name ... for creation, openshell forward start --background 18789 ..., and openshell sandbox connect ... commands.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 I hop through scripts and tuck names tight,
Shell-quoted snug in the soft moonlight.
No stray spaces, no broken line,
A quiet sandbox, all safe and fine. 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% 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 PR title 'Fix #166: Quote sandbox names in shell commands' directly and clearly summarizes the main change—applying proper shell quoting to sandbox name arguments in CLI commands.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
⚔️ Resolve merge conflicts
  • Resolve merge conflict in branch fix-sandbox-name-quoting

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

Fixes NVIDIA#166

- Add shellEscape() function to properly escape sandbox names in shell
  commands by wrapping in single quotes and handling embedded single
  quotes correctly
- Apply shell escaping to all shell commands that use sandboxName:
  - openshell sandbox delete
  - openshell sandbox create --name
  - openshell forward start

This replaces the previous double-quoted interpolation ("${sandboxName}")
with shellEscape(), which is more robust and prevents shell injection when
sandbox names contain special characters.
@hkc5 hkc5 force-pushed the fix-sandbox-name-quoting branch from bf84ea6 to fd3b4a3 Compare March 20, 2026 08:45
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.

🧹 Nitpick comments (2)
bin/lib/onboard.js (2)

60-71: Duplicate shell-escaping helper exists.

A similar function shellQuote() already exists at lines 101-103 using the '\'' escape pattern. Both patterns are valid POSIX techniques, but having two functions for the same purpose violates DRY. Consider consolidating into a single helper.

♻️ Suggested consolidation

Either rename and reuse the existing shellQuote() for all shell-escaping needs, or replace it with this new shellEscape():

-function shellQuote(value) {
-  return `'${String(value).replace(/'/g, `'\\''`)}'`;
-}
+// Reuse shellEscape for all shell quoting needs
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@bin/lib/onboard.js` around lines 60 - 71, There are two duplicate helpers
(shellEscape and shellQuote); remove the duplication by consolidating to a
single helper and updating call sites: choose one name (prefer keep shellQuote
or rename shellEscape) and delete the other function, then replace all
references to the removed function with the retained function (ensure the
retained implementation uses a POSIX-safe pattern such as replacing ' with '\''
or equivalent used in shellQuote/shellEscape). Update any module exports or
imports in this file to reference only the chosen function (shellEscape or
shellQuote) so all usages call the single consolidated helper.

454-454: Shell escaping applied correctly to these call sites.

The use of shellEscape(sandboxName) at sandbox delete (line 454), create --name (line 473), and forward start (line 541) is consistent with the PR objectives.

However, other sandboxName usages in this file still use double-quoted interpolation without escaping:

  • Line 237: openshell sandbox get "${sandboxName}"
  • Line 523: openshell sandbox delete "${sandboxName}"
  • Line 816: openshell sandbox connect "${sandboxName}"

While the sandbox name validation at line 429 restricts input to [a-z0-9-] (making injection impossible), the inconsistent escaping pattern is a code smell. Consider applying shellEscape() uniformly for maintainability and defense-in-depth.

♻️ Apply shellEscape consistently
-    const exists = runCapture(`openshell sandbox get "${sandboxName}" 2>/dev/null`, { ignoreError: true });
+    const exists = runCapture(`openshell sandbox get ${shellEscape(sandboxName)} 2>/dev/null`, { ignoreError: true });
-    const delResult = run(`openshell sandbox delete "${sandboxName}" 2>/dev/null || true`, { ignoreError: true });
+    const delResult = run(`openshell sandbox delete ${shellEscape(sandboxName)} 2>/dev/null || true`, { ignoreError: true });
-    run(`cat <<'EOF_NEMOCLAW_SYNC' | openshell sandbox connect "${sandboxName}"
+    run(`cat <<'EOF_NEMOCLAW_SYNC' | openshell sandbox connect ${shellEscape(sandboxName)}

Also applies to: 473-473, 541-541

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

In `@bin/lib/onboard.js` at line 454, Replace the remaining double-quoted
interpolations of sandboxName with shellEscape(sandboxName) to make escaping
consistent and defense-in-depth; specifically update any calls that build shell
commands with sandboxName (e.g., run("openshell sandbox get
\"${sandboxName}\""), run("openshell sandbox delete \"${sandboxName}\""), and
run("openshell sandbox connect \"${sandboxName}\"")) to use
shellEscape(sandboxName) instead, keeping the same command text (openshell
sandbox get/delete/connect and the --name option) and reusing the existing
shellEscape helper and run function so all run(...) invocations embed the
escaped sandboxName variable.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@bin/lib/onboard.js`:
- Around line 60-71: There are two duplicate helpers (shellEscape and
shellQuote); remove the duplication by consolidating to a single helper and
updating call sites: choose one name (prefer keep shellQuote or rename
shellEscape) and delete the other function, then replace all references to the
removed function with the retained function (ensure the retained implementation
uses a POSIX-safe pattern such as replacing ' with '\'' or equivalent used in
shellQuote/shellEscape). Update any module exports or imports in this file to
reference only the chosen function (shellEscape or shellQuote) so all usages
call the single consolidated helper.
- Line 454: Replace the remaining double-quoted interpolations of sandboxName
with shellEscape(sandboxName) to make escaping consistent and defense-in-depth;
specifically update any calls that build shell commands with sandboxName (e.g.,
run("openshell sandbox get \"${sandboxName}\""), run("openshell sandbox delete
\"${sandboxName}\""), and run("openshell sandbox connect \"${sandboxName}\""))
to use shellEscape(sandboxName) instead, keeping the same command text
(openshell sandbox get/delete/connect and the --name option) and reusing the
existing shellEscape helper and run function so all run(...) invocations embed
the escaped sandboxName variable.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 9453f3e3-9d85-4b90-bccc-de3a8f1279b2

📥 Commits

Reviewing files that changed from the base of the PR and between bf84ea6 and fd3b4a3.

📒 Files selected for processing (1)
  • bin/lib/onboard.js

hkc5 added 2 commits March 21, 2026 09:22
Removes the newly added shellEscape() function which duplicated the
pre-existing shellQuote() helper. All call sites updated to use shellQuote().
@hkc5
Copy link
Copy Markdown
Author

hkc5 commented Mar 30, 2026

Closing to reduce noise. Will reopen if needed.

@hkc5 hkc5 closed this Mar 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

NemoClaw CLI Use this label to identify issues with the NemoClaw command-line interface (CLI).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants