Back to skill

Security audit

Url Images To Pdf

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its stated URL-to-PDF purpose, but a crafted URL could make its script run unintended shell commands on the user's machine.

Review before installing. Only run it on trusted URLs, preferably in a low-privilege or sandboxed environment, because malicious URL text could execute commands through the current curl invocation. The script should be changed to avoid shell interpolation, validate http/https URLs, and use argument-safe process APIs or native Node HTTP fetching before normal use.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Error
Location
extract.js:36
Finding
Arbitrary Command Execution Through URL Shell Injection## Vulnerability Details **File Location**: `extract.js`, lines 36-54 **Vulnerability Type**: OS command injection **Risk Level**: High ### Vulnerable Code ```js async function main() { const url = process.argv[2]; const outputName = process.argv[3] || 'output'; if (!url) { console.log('用法: node extract.js <URL> [输出文件名]'); process.exit(1); } console.log(`正在提取: ${url}`); // 创建临时目录 if (!fs.existsSync(TEMP_DIR)) { fs.mkdirSync(TEMP_DIR, { recursive: true }); } // 获取网页内容 console.log('正在获取网页内容...'); const html = execSync(`curl -sL -A "Mozilla/5.0" "${url}"`, { encoding: 'utf8' }); ``` ### Technical Analysis The URL is read directly from the command-line arguments and interpolated into a command string passed to `execSync`. By default, `execSync` executes the string through a system shell. Wrapping the URL in double quotes does not make the command safe. POSIX-compatible shells still process command substitutions such as `$(command)` and backtick expressions inside double-quoted strings. Consequently, an attacker-controlled URL can cause arbitrary local commands to execute. No URL validation, shell metacharacter rejection, or argument-safe process invocation separates the untrusted input from the shell command. ### Attack Path 1. An attacker supplies or persuades an operator or Agent to process a crafted URL containing shell command substitution. 2. For example, the script could be invoked with a URL argument containing: ```text https://example.com/$(touch /tmp/skill-command-executed) ``` 3. The value is inserted into the `curl` command string. 4. `execSync` launches a shell to interpret that string. 5. The shell evaluates `$(touch /tmp/skill-command-executed)` before invoking `curl`. 6. The injected command executes with the privileges and environment of the user running the Skill. ...[truncated 744 chars]
Remediation
## Remediation Suggestions Eliminate shell interpretation entirely. Prefer Node.js HTTP APIs already imported by the script, or invoke `curl` with an argument array through `execFileSync` or `spawn`. ```js const { execFileSync } = require('child_process'); let parsedUrl; try { parsedUrl = new URL(url); } catch { throw new Error('Invalid URL'); } if (!['http:', 'https:'].includes(parsedUrl.protocol)) { throw new Error('Only HTTP and HTTPS URLs are allowed'); } const html = execFileSync( 'curl', ['-sL', '-A', 'Mozilla/5.0', parsedUrl.href], { encoding: 'utf8', timeout: 30000, maxBuffer: 10 * 1024 * 1024 } ); ``` Using an argument-array API ensures the URL is passed as one literal process argument rather than interpreted as shell syntax. Do not attempt to solve the issue solely by adding quotation marks or manually escaping a small set of metacharacters. Additional hardening should include: - Restricting destination hosts if this Skill is intended only for specific image providers. - Permitting only `http:` and `https:` schemes. - Applying request timeouts and response-size limits. - Rejecting embedded credentials and malformed URLs. - Running the Skill as an unprivileged account with access only to necessary files. - Adding regression tests using URLs containing `$()`, backticks, semicolons, quotes, and newline characters.
Vulnerability Patterns
  • 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
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (6)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
The documentation claims the skill preserves original order and generally extracts images from a URL, while the analyzed behavior reportedly sorts files before PDF generation and is tailored to specific image host patterns. This mismatch is security-relevant because users and agents may trust inaccurate documentation, causing unintended data processing, incorrect output assumptions, or execution in contexts where the behavior is not actually understood.

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill invokes shell commands (`node .../extract.js`) but does not declare any `permissions` or `allowed-tools` scope. In an agent environment, missing tool scoping weakens containment and makes it easier for a skill to run with broader-than-expected execution privileges, especially since it also fetches remote content and writes files.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The skill documentation does not clearly warn that execution downloads remote webpage content and writes a PDF to disk. In an agentic setting, omission of these side effects can lead to unreviewed network access, storage of potentially sensitive or copyrighted content, and unexpected local file creation.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
This file contains natural-language usage instructions and status output exclusively in Chinese, which effectively forces a locale/language choice on all users. The policy for this audit flags language or locale constraints when they are imposed without offering the user a choice or documenting a justified regional scope.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The manifest description promises '保持原文顺序,不排序' and the file header describes URL image extraction to PDF, implying preservation of source order. However, the code comments and behavior at these lines perform an explicit sort of the downloaded filenames before adding them to the PDF, which contradicts that stated intent.

Natural-Language Policy Violations

Low
Confidence
93% confidence
Finding
The natural-language content in the description and instructions is exclusively Chinese, which can impose a language constraint on users without opt-in. The file does not indicate that the skill is intentionally region-specific or provide an alternative language option.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
extract.js:59