Back to skill

Security audit

occ

Security checks for vulnerabilities and agentic risk

Overview

This skill mostly does what it says, but it silently runs npm install with unpinned dependencies during normal use, which is too much hidden authority for a controller tool.

Review this skill before installing. Its OpenCode session control behavior is coherent, but it should not silently install npm packages during normal use. Prefer a version that removes automatic npm install, removes unused axios or pins dependencies with a lockfile, and documents setup, local server startup, and data sent to OpenCode sessions.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T08 · Insecure Dependencies

Warning
Location
scripts/bin/opencode-server.js:13
Finding
Undisclosed Runtime Installation of Unpinned npm Dependencies<![CDATA[ ## Vulnerability Details **File Location**: `scripts/bin/opencode-server.js:13-37`; `scripts/package.json:16-18` **Vulnerability Type**: Automatic installation of unpinned third-party dependencies **Risk Level**: Medium ### Vulnerable Code `scripts/bin/opencode-server.js:13-37`: ```js async function checkAndInstallDependencies() { const scriptDir = path.join(__dirname, '..'); const packageJsonPath = path.join(scriptDir, 'package.json'); const nodeModulesPath = path.join(scriptDir, 'node_modules'); if (!fs.existsSync(packageJsonPath)) { console.error('Error: package.json not found in', scriptDir); process.exit(1); } if (!fs.existsSync(nodeModulesPath)) { console.log('📦 Dependencies not found. Installing...'); await installDependencies(scriptDir); console.log('✅ Dependencies installed successfully.'); } } function installDependencies(scriptDir) { return new Promise((resolve, reject) => { const npmInstall = exec('npm install', { cwd: scriptDir }); npmInstall.stdout.on('data', (data) => { process.stdout.write(data); }); npmInstall.stderr.on('data', (data) => { process.stderr.write(data); }); ``` `scripts/package.json:16-18`: ```json "dependencies": { "axios": "^1.6.0" } ``` ### Technical Analysis Every CLI invocation calls `checkAndInstallDependencies()`. If the `node_modules` directory is absent, the application automatically runs `npm install` at runtime. The project does not include a package lockfile, and the dependency uses the semver range `^1.6.0`. Consequently, the exact package and transitive dependency versions installed can vary over time. npm may also resolve packages through a user- or environment-configured registry and execute dependency lifecycle scripts during installation. The audit found no import or use of `axios` in the reviewed source code. The automatic installation therefore introduces avoidable supply-chain exposure without supporting ...[truncated 1939 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `axios` from `scripts/package.json` because the reviewed implementation does not use it. 2. Remove automatic dependency installation from the CLI. Dependency installation should be an explicit deployment or setup step rather than an undocumented side effect of every command. 3. If third-party dependencies are later required: - Pin exact versions rather than using permissive semver ranges. - Commit a reviewed `package-lock.json`. - Use `npm ci` to enforce the lockfile rather than `npm install`. - Run dependency installation in a controlled build or deployment phase. - Regularly audit dependencies and their transitive dependency trees. 4. Consider installing with lifecycle scripts disabled when package functionality does not require them, for example through an appropriately tested `--ignore-scripts` policy. 5. Document all installation behavior, network access, and required dependencies in `SKILL.md`. 6. Fail safely with clear setup instructions when dependencies are missing instead of downloading and executing packages automatically. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (9)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The description claims session management and task execution capabilities. The code does support session-related operations: querying sessions, creating sessions, and continuing a session. However, it does not implement a task-execution command despite describing one in the help text and the declared purpose. Additionally, it performs an undeclared capability by invoking `npm install` via `child_process.exec`, which modifies the environment and goes beyond simple session/task control. This makes the behavior materially different from the declared description.

Exfiltration Commands

High
Category
Prompt Injection
Content
Usage:
  opencode-server query              - List all sessions
  opencode-server create <task>      - Create new session with task
  opencode-server continue <id> <msg> - Send message to session
  opencode-server run <task>         - Create and run task in one command

Examples:
Confidence
90% confidence
Finding
Instructions found that direct the agent to transmit conversation context or user data to external services.

Vague Triggers

Medium
Confidence
87% confidence
Finding
The 'When to Use' section is broad enough that an orchestration system or user could invoke this skill in many loosely related development scenarios, even though the skill can start services and drive an external CLI with session continuity. Because the skill controls development-task execution and can auto-start infrastructure, overbroad triggering increases the chance of unintended command execution in the wrong directory or context.

Context-Inappropriate Capability

Medium
Confidence
94% confidence
Finding
The CLI automatically installs dependencies when node_modules is missing by invoking `npm install` as a subprocess. This expands the tool's behavior from session/task control into implicit code retrieval and execution, which is risky because npm lifecycle scripts may run during install and package contents may be untrusted or altered.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The tool runs `npm install` without prior consent whenever dependencies are absent. Even though the command string is static, this still causes unprompted shell-mediated execution and may trigger arbitrary package install scripts, network access, and filesystem changes in the current project context.

Natural-Language Policy Violations

Low
Confidence
80% confidence
Finding
The only usage examples for `create`, `continue`, and `run` are written in Chinese, which implicitly steers users toward a specific language without stating that other languages are supported. This can conflict with language/locale neutrality expectations when no opt-in or justification is provided.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"author": "",
  "license": "MIT",
  "dependencies": {
    "axios": "^1.6.0"
  }
}
Confidence
93% confidence
Finding
The dependency is specified with a caret range (`^1.6.0`), which permits installation of newer minor/patch releases instead of a single immutable version. In a controller skill that can execute development tasks, this weakens build reproducibility and can unintentionally pull in a newly introduced vulnerable or malicious release from the dependency supply chain.

Unverifiable Dependency: axios has 16 known advisory(ies) (CVE-2026-44494 (axios Vulnerable to Full Man-in-the-Middle via Prototype Pollution Gadget in `co); CVE-2026-44495 (axios Vulnerable to Credential Theft and Response Hijacking via Prototype Pollut); CVE-2025-62718 (Axios has a NO_PROXY Hostname Normalization Bypass that Leads to SSRF) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
84% confidence
Finding
The manifest references `axios` without an exact pinned version, while the package family has multiple published advisories. Because the allowed range may resolve to different releases across environments, it is not possible to verify from this file alone whether the installed version is safe; in a tool that controls OpenCode and executes development tasks, a vulnerable HTTP client could increase exposure to SSRF, proxy bypass, credential leakage, or response-manipulation issues depending on how it is used elsewhere.

Missing User Warnings

Low
Confidence
89% confidence
Finding
This utility performs network requests and may send request bodies over HTTP, which falls under operations that transmit user or system data. The file contains no confirmation prompt, logging, comment, or docstring disclosing that behavior to the user or caller.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/bin/opencode-server.js:31

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/src/utils/server.js:46