Back to skill

Security audit

妙言小智(PicTech.cc)-跨境电商图片翻译

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its image-translation purpose, but it needs review because it encourages unsafe API-key sharing and fetches arbitrary URLs without enough safeguards.

Install only if you are comfortable sending selected images to PicTech/stableai.com.cn and using a plugin-configured VK key. Do not paste API keys into chat. Avoid processing untrusted image URLs until the skill adds URL allowlisting, private-network blocking, redirect validation, image/type checks, and download size limits.

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

T09 · Insecure Skill Coding Practices

Error
Location
utils.js:12
Finding

Unrestricted Remote URL Fetching Enables Server-Side Request Forgery

Content
View full analysis
{ const tempPath = path.join(os.tmpdir(), `trans_${crypto.randomBytes(4).toString('hex')}`); const res = await axios({ url, method: 'GET', responseType: 'arraybuffer', timeout: 30000 }); const buffer = Buffer.from(res.data); await fsPromises.writeFile(tempPath, buffer); let name = 'web_image.png'; try { name = path.basename(new URL(url).pathname) || name; } catch (e) { } return { buffer, tempPath, name }; } ``` The translation service's result URL is also fetched without validation: ```js const imageRes = await axios.get(resultUrl, { responseType: 'arraybuffer' }); await fsPromises.writeFile(localSavePath, Buffer.from(imageRes.data)); ``` ### Technical Analysis The skill treats every string beginning with `http://` or `https://` as a valid remote image. It does not resolve and inspect the destination address or reject loopback, private, link-local, reserved, multicast, or cloud metadata addresses. Axios follows redirects by default. Consequently, validating only the initial URL scheme would not be sufficient: an initially public endpoint could redirect the request to an internal address. The same issue affects `resultUrl`, which is obtained from the external translation API and then fetched by the local Agent process without checking its scheme, hostname, resolved address, or redirect chain. The request is made with the network privileges and reachability of the process running the skill. For user-supplied input URLs, downloaded response bytes are subsequently hashed and uploa ...[truncated 1997 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
utils.js:12
Finding

Unbounded Remote Response Buffering Allows Memory and Disk Exhaustion

Content
View full analysis
{ const tempPath = path.join(os.tmpdir(), `trans_${crypto.randomBytes(4).toString('hex')}`); const res = await axios({ url, method: 'GET', responseType: 'arraybuffer', timeout: 30000 }); const buffer = Buffer.from(res.data); await fsPromises.writeFile(tempPath, buffer); let name = 'web_image.png'; try { name = path.basename(new URL(url).pathname) || name; } catch (e) { } return { buffer, tempPath, name }; } ``` The 15 MB limit is enforced only for local files: ```js const stats = await fsPromises.stat(task.path); if (stats.size > MAX_SIZE) { throw new Error('文件超过 15MB 限制'); } buffer = await fsPromises.readFile(task.path); ``` Translation result responses are also completely buffered without a size limit or timeout: ```js const imageRes = await axios.get(resultUrl, { responseType: 'arraybuffer' }); await fsPromises.writeFile(localSavePath, Buffer.from(imageRes.data)); ``` ### Technical Analysis The application declares a 15 MB input limit, but that limit applies only when `task.type` is `file`. Remote input URLs bypass the local `stat()` check. Axios receives the entire response as an `arraybuffer`, after which another `Buffer` object is constructed and the data is written to a temporary file. No `maxContentLength`, `maxBodyLength`, streaming byte counter, or trusted `Content-Length` check is configured. The code also does not verify the response MIME type or image file signature before buffering, saving, hashing, and uploading it. The result download has the same issue and does not specify a request timeout. Therefore, either a user-controlled input server or a malicious or compromised result hos ...[truncated 1596 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (18)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- 如果用户没有指定保存目录,让 `index.js` 使用默认结果目录。

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- 如果用户没有指定保存目录,让 `index.js` 使用默认结果目录。

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- 如果用户没有指定保存目录,让 `index.js` 使用默认结果目录。

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

README 全文及交互示例均默认要求用户以中文进行理解和操作,且参数说明中 sourceLanguage 也将输入语言选项限制为少数固定语言,没有说明是否支持用户按偏好选择技能交互语言。若组织要求不得在未获用户选择时强制特定语言/locale,这种默认单一语言说明可能构成自然语言策略问题。

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The documentation promotes persistent memorization of the VK/API key after a single chat entry, normalizing insecure secret submission and long-term storage without clarifying protections. In an agent skill context, persistent secret retention increases the chance of leakage through logs, local plaintext files, backups, prompt memory, or unintended reuse across sessions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The README explicitly instructs users to paste an API/VK secret directly into the assistant conversation, but does not warn that chat channels may be logged, retained, or exposed to other tools and operators. This creates a real secret-handling risk because credentials entered into conversational context can be captured in transcripts, telemetry, prompt history, or downstream integrations.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

This example directly tells the user to paste a secret VK key into the conversation for the assistant to use. That is dangerous because conversational channels are often observable and retained, and the skill context specifically encourages operational use, making accidental credential disclosure likely during normal onboarding.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The agent-facing instructions say that if the key is missing, the assistant should prompt the user to enter it. This operationalizes insecure secret collection through chat, which is especially risky in agent platforms where prompts, responses, and tool context may be persisted or exposed to other components.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
82% confidence
Finding

This markdown file contains user-facing natural-language instructions exclusively in Chinese, and the operational defaults are hard-coded as source language Chinese and target language English. Because the skill does not state that it is region-specific or provide an opt-in language choice for how the skill itself communicates, it may violate language/locale policy requirements.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

User-facing status and error messages in this file are consistently hard-coded in Chinese, with no indication that the user can choose another language. Under the policy, forcing a specific language without user opt-in is a natural-language policy concern unless the locale constraint is explicitly documented and justified.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The code uploads full image contents to a third-party API endpoint (stableai.com.cn) for processing, but this file contains no user-facing disclosure, consent gate, or data-handling warning before transfer. Because images may contain sensitive commercial, personal, or embedded metadata, silent exfiltration to an external service creates a real privacy and compliance risk, especially in automation contexts where users may assume processing is local.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This manifest presents the skill description, configuration title/description, and parameter labels/placeholders entirely in Chinese, with no indication that users can opt into another language. That creates a natural-language policy concern because the skill effectively requires a specific language for understanding and configuration.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The function fetches data from a remote URL and writes the response to a temporary file, which are safety-relevant operations under the code-file warning criteria. There is no confirmation prompt, logging/print statement, or explanatory comment/docstring in this file to disclose that network access and file creation will occur.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
92% confidence
Finding

The dependency is specified with a caret range, which allows newer minor/patch releases to be installed over time. This weakens build reproducibility and can introduce vulnerable or malicious upstream changes through the supply chain without any code change in the skill itself.

Content

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

json
"version": "1.0.0",
  "main": "index.js",
  "dependencies": {
    "@seald-io/nedb": "^4.1.2",
    "axios": "^1.15.2",
    "form-data": "^4.0.5"
  }

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

Axios is declared with a caret version range, so future installs may resolve to different releases than originally tested. Because axios is a network-facing HTTP client and has multiple known advisories in nearby versions, leaving it unpinned increases the chance of silently pulling in an affected or otherwise risky release.

Content

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

json
"main": "index.js",
  "dependencies": {
    "@seald-io/nedb": "^4.1.2",
    "axios": "^1.15.2",
    "form-data": "^4.0.5"
  }
}

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
86% confidence
Finding

The manifest does not pin axios to an exact version, so it is not possible to verify whether the installed package is one of the advisory-affected releases. In this skill context, axios is likely central to external API communication for image translation workflows, which makes any SSRF, MITM, request-smuggling, or prototype-pollution-related client weakness more meaningful than a dormant library issue.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
94% confidence
Finding

Using a caret range for form-data permits non-deterministic dependency resolution across environments and over time. For a library that constructs multipart requests, this can expose the skill to newly introduced bugs or known issues in transitive supply-chain updates.

Content

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

json
"dependencies": {
    "@seald-io/nedb": "^4.1.2",
    "axios": "^1.15.2",
    "form-data": "^4.0.5"
  }
}

Unverifiable Dependency: form-data has 2 known advisory(ies) (CVE-2025-7783 (form-data uses unsafe random function in form-data for choosing boundary); CVE-2026-12143 (form-data: CRLF injection in form-data via unescaped multipart field names and f)), 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

Because form-data is not pinned, the package version actually installed cannot be verified against the cited advisories. In a skill that likely uploads images and metadata to remote services, weaknesses such as unsafe boundary generation or CRLF injection in multipart construction could affect request integrity, though the practical impact depends on how user-controlled field names are handled elsewhere in the code.

Content

No source excerpt is available for this finding.