Back to skill

Security audit

Novita Sandbox

Security checks for vulnerabilities and agentic risk

Overview

This remote sandbox skill is coherent for isolated browsing and code execution, but needs Review because it can upload arbitrary local files to Novita and overwrite local files from sandbox output without enforced path limits or confirmation.

Review this before installing if you will use it around private workspaces or credentials. Use a dedicated environment, pin the Novita SDK to a reviewed version, give it only the Novita API key it needs, avoid uploading secrets or broad workspace files, download only into a disposable staging directory, and kill sandboxes when finished to clear preserved state and stop billing.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/sandbox.py:132
Finding
Unrestricted Local File Upload and Overwrite Crosses the Sandbox Security Boundary<![CDATA[ ## Vulnerability Details **File Location**: `scripts/sandbox.py:132-155` **Vulnerability Type**: Unrestricted local file access and third-party data transfer **Risk Level**: High ### Vulnerable Code ```python def cmd_upload(args): sbx = connect(args.sandbox_id) try: with open(args.local_path, "rb") as f: sbx.files.write(args.sandbox_path, f) json_out({"status": "ok", "from": args.local_path, "to": args.sandbox_path}) except FileNotFoundError: json_err(f"Local file not found: {args.local_path}") except Exception as e: json_err(f"Upload failed: {e}", sandbox_id=args.sandbox_id) def cmd_download(args): sbx = connect(args.sandbox_id) try: content = sbx.files.read(args.sandbox_path) if content is None: json_err(f"File not found in sandbox: {args.sandbox_path}", sandbox_id=args.sandbox_id) if isinstance(content, bytes): with open(args.local_path, "wb") as f: f.write(content) else: with open(args.local_path, "w") as f: f.write(content) json_out({"status": "ok", "from": args.sandbox_path, "to": args.local_path}) except Exception as e: json_err(f"Download failed: {e}", sandbox_id=args.sandbox_id) ``` The relevant documentation also exposes these operations in `SKILL.md:155-163`, while `SKILL.md:302` only provides a non-enforced instruction not to upload sensitive files. ### Technical Analysis The `upload` operation accepts an arbitrary local path and transmits the selected file to a Novita cloud sandbox. It does not enforce a workspace root, reject symbolic links, screen sensitive locations, impose a size limit, or require confirmation before crossing the local-to-cloud trust boundary. The `download` operation similarly accepts an arbitrary local destination and opens it using `wb` or `w`. These modes overwrite existing files without confirmation. There is no canonica ...[truncated 2497 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Require an explicitly configured local workspace root and reject all paths outside it. 2. Resolve paths with `Path.resolve()` and verify that the canonical path remains beneath the approved root. 3. Reject symbolic links and revalidate opened files to mitigate symlink and time-of-check/time-of-use attacks. 4. Deny known sensitive file classes and directories, including SSH keys, cloud credentials, environment files, browser profiles, keychains, and Agent configuration. 5. Require explicit user confirmation before uploading any local file to a third-party service. 6. Apply file-size and file-type limits before upload. 7. For downloads, refuse to overwrite existing files by default. Use exclusive creation and require a separate `--overwrite` option with confirmation. 8. Write downloads to a controlled staging directory and use atomic replacement only after validation. 9. Clearly disclose the remote destination, selected local path, file size, and overwrite behavior before transfer. 10. Enforce these restrictions in code rather than relying solely on Skill instructions. ]]>

T08 · Insecure Dependencies

Warning
Location
scripts/requirements.txt:1
Finding
Novita SDK Dependency Is Not Reproducibly Pinned<![CDATA[ ## Vulnerability Details **File Location**: `scripts/requirements.txt:1` **Vulnerability Type**: Unbounded third-party dependency version **Risk Level**: Medium ### Vulnerable Code ```text novita-sandbox>=1.0.5 ``` The same installation constraint is presented in `SKILL.md:39-45`: ```bash pip3 install "novita-sandbox>=1.0.5" # Or: pip3 install -r skills/novita-sandbox/scripts/requirements.txt ``` ### Technical Analysis The requirement specifies only a minimum version. It therefore permits installation of any future `novita-sandbox` release satisfying `>=1.0.5`. This contradicts the documentation's statement that the SDK version is “tested and pinned.” No lockfile, upper version bound, or cryptographic package hashes are provided. Consequently, installation is not reproducible and the reviewed source does not uniquely identify the code that will execute during package installation or at runtime. This dependency is security-sensitive because it receives the Novita API key and implements sandbox creation, network communication, command execution, and file transfer. A compromised, malicious, or unexpectedly incompatible future release could alter those operations or access information available to the local Python process. ### Attack Path 1. A future or compromised package release is published under the `novita-sandbox` package name. 2. The release version satisfies the broad `>=1.0.5` constraint. 3. A user follows the documented installation command without a previously constrained environment or trusted lockfile. 4. The package manager selects and installs the newer release. 5. Package installation hooks, imported module code, or runtime SDK behavior executes with the privileges of the installing or invoking user. 6. Malicious or compromised code could access the API key, manipulate transferred files, redirect network operations, or execute other actions allowed to the Python process. This finding does not establish that the current package i ...[truncated 683 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin the dependency to an exact reviewed version, for example: ```text novita-sandbox==1.0.5 ``` 2. Generate and publish cryptographic hashes for all distributions and install with `pip --require-hashes`. 3. Maintain a reviewed lockfile that includes transitive dependencies. 4. Update dependencies through a controlled process involving changelog review, source or artifact verification, and security testing. 5. Prefer isolated virtual environments and avoid privileged or system-wide package installation. 6. Correct the documentation so that its claim of a pinned version matches the actual dependency constraint. 7. Consider constraining the package index to an approved source and using dependency scanning or provenance verification where available. ]]>
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (10)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill claims it is not for reading or writing local user files, yet it documents upload and download operations that necessarily read from and write to local paths. That mismatch can mislead users or higher-level agents into trusting the skill in contexts where local workspace isolation matters, creating a path for unintended exfiltration of local files to the remote sandbox or untrusted artifacts being written back locally.

Ae1

High
Category
analysis-evasion
Content
**Important:** This skill requires `novita-sandbox>=1.0.5`. Do NOT modify `scripts/sandbox.py` — the SDK version is tested and pinned.
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

External Script Fetching

High
Category
Supply Chain
Content
```bash
python3 skills/novita-sandbox/scripts/sandbox.py create --template browser-chromium --timeout 120
python3 skills/novita-sandbox/scripts/sandbox.py exec <sandbox_id> \
  "curl -sL https://example.com" --timeout 30
```

### JS-rendered pages (puppeteer)
Confidence
90% confidence
Finding
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The skill exposes direct host filesystem access via `open(args.local_path, ...)` in both upload and download operations, despite the manifest explicitly stating it is not for reading or writing local user files. In an agent setting, this creates a path for a remote-execution-focused tool to exfiltrate local files into the sandbox or overwrite arbitrary local files from sandbox-controlled content, breaking the intended trust boundary.

Context-Inappropriate Capability

High
Confidence
95% confidence
Finding
For a skill whose stated purpose is remote sandbox execution and browsing, host filesystem access is unnecessary and materially expands the attack surface. If an agent can be induced to use `upload` or `download`, untrusted sandbox workloads can indirectly read from or write to the local machine, enabling data theft or local file tampering.

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill invokes capabilities that interact with environment variables and local file operations, but it declares no explicit tool scope or permissions boundary. In a security-sensitive skill that handles untrusted code and browsing, missing scope declarations increase the chance that an agent can overreach into local resources or expose secrets because the enforcement contract is unclear.

Intent-Code Divergence

Medium
Confidence
89% confidence
Finding
The code creates sandboxes with `secure=False` and `allow_internet_access=True` while presenting the tool as a secure sandbox for untrusted code and browser activity. This mismatch can cause operators or higher-level agents to assume stronger isolation than is actually configured, increasing the likelihood of risky use of the environment and broader data exposure over the network.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The `download` command writes sandbox-provided content directly to an arbitrary host path without any confirmation, path restriction, or warning. In this context, the sandbox may contain untrusted code output, so writing it onto the host can overwrite files, plant malicious scripts, or place attacker-controlled content in sensitive locations.

Missing User Warnings

Medium
Confidence
85% confidence
Finding
The kill command performs an irreversible destructive action by destroying a sandbox, but the implementation provides no confirmation prompt or warning at execution time. The CLI help says 'Destroy a sandbox,' but there is no stronger user disclosure in code for this destructive operation.

Unpinned Dependencies

Low
Category
Supply Chain
Content
novita-sandbox>=1.0.5
Confidence
95% confidence
Finding
The dependency is specified with a lower-bound range (>=1.0.5) instead of an exact version, so future installs may pull in different releases than were originally reviewed or tested. In a security-sensitive sandbox skill, this increases supply-chain and reproducibility risk because a later compromised, vulnerable, or behavior-changing package version could be installed automatically.

Static analysis

No suspicious patterns detected.