Back to skill

Security audit

Business Opportunity Screenshot

Security checks for vulnerabilities and agentic risk

Overview

This skill appears intended to make a business-opportunity report and screenshot, but its script can run unintended system commands and write files outside intended folders when given crafted inputs.

Review before installing. Only run this in a restricted workspace with trusted arguments, and avoid using a browser profile containing sensitive sessions. The script should be fixed to use argument-array process execution, validate slugs and filenames, escape HTML output, close the Chromium process, and update or pin dependencies from an approved registry.

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 (5)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/screenshot.js:41
Finding

OS Command Injection Through the User-Controlled Search Query

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/screenshot.js:68
Finding

OS Command Injection Through ClawHub-Provided Skill Slugs

Content
View full analysis
l.includes('- ')); const skills = []; for (const line of lines) { const match = line.match(/-\s+(\S+)\s+(.+)/); if (match) { skills.push({ slug: match[1], name: match[2] }); } } console.log(`[INFO] Found ${skills.length} skills from API`); return skills.slice(0, 15); } function inspectSkill(slug) { try { const result = exec(`clawhub inspect ${slug}`); ``` ### Technical Analysis Skill slugs parsed from the output of `clawhub search` are treated as trusted even though they originate outside the application. The parser accepts any contiguous non-whitespace value as a slug: ```javascript (\S+) ``` This permits shell metacharacters to be included in the parsed value. The slug is later interpolated into a shell command and executed through the same `execSync` wrapper used by the search operation. This is a second-order injection issue: the dangerous value is first received and stored as parsed search data, then reaches a shell execution sink during the inspection phase. Exploitation requires control over or compromise of the ClawHub command output, a spoofed local `clawhub` executable, or another mechanism that can alter the returned search text. ### Attack Path 1. An attacker causes `clawhub search` to return a crafted result line containing a slug with shell syntax. 2. The regular expression accepts the crafted non-whitespace value as `match[1]`. 3. The value is stored as `s.slug`. 4. The main processing loop passes the value to `inspectSkill`. 5. `inspectSkill` builds `clawhub inspect ${slug}`. 6. `execSync` executes the string through a shell. 7. The injected command runs with the privileges of the Skill process. ### Impact Assessment If the external search response or local ClawHub tool is attac ...[truncated 429 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/screenshot.js:306
Finding

Arbitrary File Placement Through Output Name Path Traversal

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/screenshot.js:131
Finding

HTML and Script Injection in the Generated Report

Content
View full analysis
⚠️ 数据来源:预设列表(API 限流)' : ''; const html = ` ${outputName} ``` External Skill fields are also interpolated directly: ```javascript ${skills.slice(0,3).map(s => `
${s.slug} @${s.owner}

${s.summary}

📅 更新: ${s.updated} 📦 版本: ${s.version}
`).join('')} ``` The generated content is written as HTML: ```javascript const htmlPath = path.join(WORKSPACE, `${outputName}.html`); fs.writeFileSync(htmlPath, html, 'utf8'); ``` It is subsequently opened in Chromium: ```javascript await startBrowser(`file://${htmlPath}`); ``` ### Technical Analysis The code places `outputName` and multiple externally sourced ClawHub fields directly into HTML markup without context-sensitive escaping. Values containing HTML tags or event-handler attributes can therefore alter the generated document. A payload capable of introducing executable markup may run when Chromium opens the local report. The vulnerable fields include at least: - `outputName` - `s.slug` - `s.owner` - `s.summary` - `s.updated` - `s.version` The same rendering pattern is repeated for each report category. Because the report is loaded automatically in a browser, exploitation does not require the user to open ...[truncated 1229 chars]
Remediation
View remediation
', '>') .replaceAll('"', '"') .replaceAll("'", '''); } ``` Apply it to every untrusted field: ```javascript ${escapeHtml(s.slug)} @${escapeHtml(s.owner)}

${escapeHtml(s.summary)}

``` Additional controls should include: 1. Prefer a DOM builder that assigns untrusted values through `textContent`. 2. Disable JavaScript on the Puppeteer page if report scripting is unnecessary. 3. Add a restrictive Content Security Policy that disallows inline scripts and unnecessary network destinations. 4. Validate and limit the length of every external metadata field. 5. Avoid loading the report in a persistent browser profile containing authenticated sessions or sensitive state. 6. Add tests covering tags, quotes, event handlers, and encoded markup in every rendered field. ]]>

T08 · Insecure Dependencies

Note
Location
package-lock.json:16
Finding

Dependency Lockfile Uses a Non-Default Package Registry Mirror

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (11)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 69)May include surrounding context.

md
node scripts/screenshot.js

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 72)May include surrounding context.

md
node scripts/screenshot.js

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 75)May include surrounding context.

md
node scripts/screenshot.js

Known Vulnerable Dependency: basic-ftp==5.2.0 — 4 advisory(ies): GHSA-6v7q-wjvx-w8wg (basic-ftp: Incomplete CRLF Injection Protection Allows Arbitrary FTP Command Exe); CVE-2026-39983 (basic-ftp has FTP Command Injection via CRLF); CVE-2026-41324 (basic-ftp vulnerable to denial of service via unbounded memory consumption in Cl) +1 more

High
Category
Supply Chain
Confidence
97% confidence
Finding

The lockfile pins basic-ftp to 5.2.0, which is flagged with multiple advisories including FTP command injection and denial-of-service issues. Although this package is only a transitive dependency here (via get-uri/pac-proxy-agent/proxy-agent in the Puppeteer stack), keeping a known vulnerable version in the dependency tree creates risk if any code path allows attacker-influenced FTP/PAC URI handling.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: extract-zip==2.0.1 — 2 advisory(ies): CVE-2026-19693 (extract-zip allows arbitrary file writes through symlink archive entries); CVE-2026-56876 (extract-zip unvalidated symlink path traversal)

High
Category
Supply Chain
Confidence
98% confidence
Finding

extract-zip 2.0.1 is present as a transitive dependency and has advisories for arbitrary file write and symlink path traversal during archive extraction. In this dependency graph it is brought in by @puppeteer/browsers, so if the skill ever downloads and extracts browser archives or other attacker-influenced ZIP content, exploitation could lead to writes outside the intended directory.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: ip-address==10.1.0 — 2 advisory(ies): CVE-2026-69192 (ip-address: Address4 decodes leading-zero octets as decimal while resolvers deco); CVE-2026-42338 (ip-address has XSS in Address6 HTML-emitting methods)

High
Category
Supply Chain
Confidence
89% confidence
Finding

ip-address 10.1.0 is a known vulnerable transitive dependency through socks/socks-proxy-agent/proxy-agent. The listed issues require specific use of IP parsing or HTML-emitting methods; in this lockfile-only context there is no evidence the vulnerable functionality is actually exercised, but the dependency is still genuinely vulnerable and could become reachable if proxy parsing or related output handling is used.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: ws==8.19.0 — 2 advisory(ies): CVE-2026-45736 (ws: Uninitialized memory disclosure); CVE-2026-48779 (ws: Memory exhaustion DoS from tiny fragments and data chunks)

High
Category
Supply Chain
Confidence
96% confidence
Finding

ws 8.19.0 is included by puppeteer-core and is flagged for memory disclosure and memory exhaustion denial-of-service vulnerabilities. Because Puppeteer communicates with browser/debugging endpoints over WebSocket, a vulnerable ws version can matter if the skill connects to untrusted or attacker-controlled endpoints, making the issue more relevant than a dormant utility dependency.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The HTML output explicitly sets lang="zh-CN" and the visible UI text throughout the report is in Chinese, which forces a specific language/locale. There is no opt-in, fallback, or documented region-specific justification in the file, so this matches the language/locale policy concern.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
94% confidence
Finding

The dependency is version-ranged with a caret (^24.39.1), so installs may resolve to newer minor/patch releases over time rather than a single audited artifact. This creates a software supply chain risk: a compromised or breaking upstream release could be pulled in automatically, reducing build reproducibility and potentially introducing vulnerable code into the skill.

Content

Scanner excerpt · package.json (reported line 14)May include surrounding context.

json
"license": "ISC",
  "type": "commonjs",
  "dependencies": {
    "puppeteer-core": "^24.39.1"
  }
}

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

The script creates a new HTML file under the workspace via fs.writeFileSync, which is a file-write operation covered by the warning rule for code files. Although there is an informational log after the write, there is no prior disclosure, confirmation, or inline documentation warning that the script will create artifacts in the user's workspace.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The code creates the output directory and writes a screenshot image to disk, which affects user files and storage. The later success log confirms the action after it occurs, but the file lacks any explicit warning or descriptive comment near entrypoint behavior that screenshots and directories will be created.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/screenshot.js:41