fix(sandbox): quote cp() paths to prevent shell injection (Tolmo ee4c9b53)#185
Conversation
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
🔀 Interaction FlowsequenceDiagram
participant Caller as Caller (User Code)
participant FS as SandboxFileSystem.cp()
participant Shlex as shlex.quote()
participant Proc as Sandbox /process Endpoint
participant Shell as sh -c (in sandbox)
Caller->>FS: cp(source, destination)
Note over FS: source/destination may contain<br/>shell metacharacters (;, |, $(), etc.)
FS->>Shlex: quote(source)
Shlex-->>FS: escaped source
FS->>Shlex: quote(destination)
Shlex-->>FS: escaped destination
FS->>FS: Build command:<br/>f"cp -r {quoted_src} {quoted_dst}"
FS->>Proc: process.create(cmd)
Proc->>Shell: sh -c "cp -r 'safe_src' 'safe_dst'"
Note over Shell: Metacharacters treated as<br/>literal path characters ✓
SummaryThis PR fixes a shell injection vulnerability in Fix: Both the async ( Testing: New parametrized tests verify that injection payloads (command separators, substitution, spaces) are properly neutralized in both sync and async paths. Note Posted by PR Sequence Diagram · Tag @mendral-app with feedback. |
|
📋 Created Linear issue ENG-3839 — status: In Progress
Auto-created because no Linear reference was found in the PR title, description, or branch name. Note Posted by Linear Issue Enforcer · Tag @mendral-app with feedback. |
…ession The session preview token was attached both as the X-Blaxel-Preview-Token header and a redundant bl_preview_token entry in SandboxConfiguration.params. The header alone authenticates this programmatic client, so the query-param copy only risks leaking a ~24h full-sandbox-control credential into access logs, Referer headers, and browser history. Remove it from from_session() in both the async and sync variants and add regression tests asserting from_session() produces no credential-bearing params. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
|
Bugbot is not enabled for this team, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
Automated-feedback review & impact summaryTriage of all bot feedback/checks — no open actionable finding:
The 2 failing CI checks are unrelated to this PR (diff-isolation evidence):
Neither failing test (nor any code it imports) is touched by this PR, so their outcome here is identical to Impact: behavior-preserving for all legitimate paths; closes root-level shell injection in the sandbox; pure client-side SDK change (no server deploy/migration). Residual/follow-up (separate work, not this PR): the endpoint still runs via No low-risk valid bug was surfaced, so no code changes were made in response to bot feedback. |
…thub.com:beamlit/sdk-python into cdrappier/devin/fix-sandbox-cp-shell-injection
… extra args This commit cleans up the integration tests by removing the tests for creating sandboxes with nvme and iptables extra arguments, as well as the combined test for both. The remaining test focuses on creating a sandbox without extra arguments, ensuring a more streamlined test suite.
🧪 Testing GuideWhat this PR addressesThis PR fixes two security issues in the Blaxel sandbox SDK:
Additionally, two nvme-related integration tests were removed from Steps to reproduce the original issueShell injection (cp):
Token leakage (from_session):
What to verify (expected behavior)Shell injection fix:
Token leakage fix:
General:
Note Posted by PR Testing Guide · Tag @mendral-app with feedback. |
There was a problem hiding this comment.
LGTM
All changes are correct and well-motivated. The preview token removal is a straightforward security hardening — SandboxConfiguration defaults params to {} when None is passed, so existing behavior is preserved. The shlex.quote() fix remains sound. No new issues introduced.
Tag @mendral-app with feedback or questions. View session
Fixes ENG-3839
Summary
SandboxFileSystem.cp()built a shell command by interpolating caller-suppliedsource/destinationstraight into an f-string, which the sandbox/processendpoint runs viash -c. Any shell metacharacter in a path (;,|,&&,$(), backticks, spaces) was therefore interpreted by the shell and executed inside the sandbox (as root). Fixes Tolmo finding ee4c9b53 (MEDIUM).Fix: quote both paths with
shlex.quote()so the shell treats them as single literal arguments. Behavior is preserved — the copy still runs inside the sandbox viash -c; only the injection is closed.Applied identically to both variants:
src/blaxel/core/sandbox/default/filesystem.py(asynccp())src/blaxel/core/sandbox/sync/filesystem.py(synccp())Tests
Added parametrized regression tests in
tests/core/test_sandbox_filesystem.pycovering both variants. Each feeds injection payloads (; touch /tmp/pwned,$(), backticks,&&,|, spaces) assourceanddestination, mocks the process manager, and asserts the payload appears only inside a single-quoted literal — i.e. the injected command never lands as bare shell syntax. 13 passed.Notes / follow-ups (not in this PR)
/filesystem/copysandbox endpoint (source/dest as separate JSON fields) or an argv/array execution mode on/process, both of which require server-side work inblaxel-ai/sandbox.blaxel-ai/sdk-typescript) very likely carries the samecp -r ${source} ${destination}pattern and should get an equivalent fix.Link to Devin session: https://app.devin.ai/sessions/14470e1d481f453091e027719aa92d9c
Requested by: @drappier-charles
Note
PR now includes three logical changes: (1)
shlex.quote()fix for shell injection incp()(previously reviewed), (2) removal ofbl_preview_tokenfrom query params infrom_session()to avoid leaking the credential in URLs, with regression tests, and (3) cleanup of redundant integration tests for nvme/iptables extra args.Written by Mendral for commit 291d9cc.