Back to skill

Security audit

vidunderstand

Security checks for vulnerabilities and agentic risk

Overview

This video transcription skill has a coherent purpose, but it should be reviewed carefully because URL inputs can fetch arbitrary network resources and upload the result to remote cloud processing.

Install only if you are comfortable sending selected videos, video URLs, prompts, task IDs, and some filename metadata to the GuaiKei cloud service and its upload storage. Do not use it on confidential meetings, customer data, private intranet URLs, localhost URLs, cloud metadata URLs, or sensitive recordings unless you have verified the provider's data handling and can restrict network access.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/utils/validator.js:3
Finding
Unrestricted URL Fetching Enables SSRF and Internal Service Data Exfiltration<![CDATA[ ## Vulnerability Details **File Location**: `scripts/utils/validator.js:3-9`, `scripts/video2text/index.js:96-113`, and `scripts/utils/download.js:478-492` **Vulnerability Type**: Server-Side Request Forgery (SSRF) through unrestricted URL downloads and redirects **Risk Level**: High ### Vulnerable Code ```js // scripts/utils/validator.js:3-9 function isUrl(url) { try { const parsedUrl = new URL(url); return parsedUrl.protocol === "http:" || parsedUrl.protocol === "https:"; } catch (_) { return false; } } ``` ```js // scripts/video2text/index.js:96-113 if (validator.isUrl(file)) { const filepath = utils.downloadPath(); try { await fs.promises.mkdir(filepath, { recursive: true }); } catch (error) { utils.printError("临时下载目录创建失败: " + (error.message || String(error))); process.exit(1); } try { const downloadResult = await helper.download(file, filepath); let tempFilePath = downloadResult?.filePath || ""; if (tempFilePath === "") { utils.printError("下载失败: 未返回文件路径"); process.exit(1); } ``` ```js // scripts/utils/download.js:478-492 if (this.__isRequireRedirect(response)) { this.__redirectCount++; if (this.__redirectCount > this.__opts.maxRedirects) { const err = new Error("Too many redirects"); this.__setState(this.__states.FAILED); this.emit("error", err); return reject(err); } const redirectedURL = /^https?:\/\//.test(response.headers.location) ? response.headers.location : new URL(response.headers.location, this.url).href; this.__isRedirected = true; this.__initProtocol(redirectedURL); this.emit("redirected", redirectedURL, this.url); return this.__start(); } ``` ### Technical Analysis The URL validator verifies only whether the supplied URL uses HTTP or HTTPS. It does not reject destinations resolving to loopback, private, link-local, reserved, multicast, or cloud metadata address ranges. Examples of potentially reachable destinations inc ...[truncated 2048 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Resolve the destination hostname before making a request and reject all non-public IPv4 and IPv6 addresses. 2. Explicitly block loopback, private, link-local, multicast, reserved, carrier-grade NAT, and cloud metadata ranges. 3. Apply the same validation to every redirect before following it. 4. Limit redirects to the supported protocols and a small maximum count. 5. Defend against DNS rebinding by connecting only to an address that was resolved and approved during validation, while preserving correct TLS hostname verification. 6. Prefer an allowlist of supported public media domains if the Skill is intended for specific platforms. 7. Reject URLs containing unexpected credentials or ports. 8. Impose strict response-size, download-time, and media-type limits before writing or uploading content. 9. Validate that downloaded content is an expected media format before sending it to the remote service. 10. Add automated tests for direct and redirected access to IPv4, IPv6, loopback, private-network, and metadata endpoints. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/utils/upload.js:10
Finding
API-Controlled Upload Destination Is Not Restricted to Trusted Storage Hosts<![CDATA[ ## Vulnerability Details **File Location**: `scripts/video2text/index.js:140-146` and `scripts/utils/upload.js:10-37` **Vulnerability Type**: Unrestricted transmission of user files to an API-selected HTTPS host **Risk Level**: Medium ### Vulnerable Code ```js // scripts/video2text/index.js:140-146 const presignedUrl = await video.getPresignedUrl(tokenValue, file); if (!presignedUrl || !presignedUrl?.url || presignedUrl.url === "") { throw new Error("获取预签名URL失败,请反馈给开发者"); } utils.printInfo("上传文件到安全空间..."); await upload.uploadFileToOSS(file, presignedUrl.url, presignedUrl.headers); ``` ```js // scripts/utils/upload.js:10-37 async function uploadFileToOSS(filename, presignedUrl, headers) { const url = new URL(presignedUrl); if (url.protocol !== "https:") { throw new Error("上传URL必须是HTTPS协议"); } return new Promise((resolve, reject) => { const fileStats = fs.statSync(filename); const totalSize = fileStats.size; let uploadedSize = 0; let settled = false; const fileStream = fs.createReadStream(filename); // 复制预签名 headers,并补充 OSS PUT 必需字段 const uploadHeaders = Object.assign({}, headers); // 关键修复:明确 Content-Length,否则 Node 对流式 body 默认使用 chunked // Transfer-Encoding,阿里云 OSS 预签名 PUT 通常会拒绝而返回 400/403 uploadHeaders["Content-Length"] = String(totalSize); if (!uploadHeaders["Content-Type"]) { uploadHeaders["Content-Type"] = "application/octet-stream"; } const options = { host: url.hostname, path: url.pathname + url.search, method: "PUT", headers: uploadHeaders, }; ``` ### Technical Analysis The upload destination and headers are supplied by the response from `www.guaikei.com`. The client validates only that the URL uses HTTPS. It does not verify the hostname, port, expected object-storage provider, or header names. As a result, any HTTPS hostname selected by the API response is accepted as the recipient of the complete user-selected file. HTTPS protects tran ...[truncated 1553 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Maintain a strict allowlist of expected object-storage hostnames or hostname suffixes. 2. Verify hostname boundaries correctly; for example, allowing `.example.com` must not accept `example.com.attacker.test`. 3. Reject IP-literal destinations, unexpected ports, embedded credentials, non-HTTPS protocols, and malformed internationalized hostnames. 4. Validate the API response against a strict schema before initiating the upload. 5. Permit only the exact upload headers required by the storage provider; reject arbitrary API-supplied headers. 6. Document all API and object-storage domains that receive user data. 7. Consider cryptographically binding the upload destination to trusted service configuration rather than accepting an unrestricted host from a runtime response. 8. Add integration tests confirming that uploads to unapproved HTTPS hosts are rejected. 9. Provide clear user disclosure and consent regarding remote storage, retention, deletion, and processing. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
scripts/api/video.js:11
Finding
Full Local File Path Is Disclosed to the Remote API<![CDATA[ ## Vulnerability Details **File Location**: `scripts/api/video.js:11-29`, called from `scripts/video2text/index.js:140` **Vulnerability Type**: Unnecessary local environment metadata disclosure **Risk Level**: Low ### Vulnerable Code ```js // scripts/api/video.js:11-29 async function getPresignedUrl(token, filename) { if (!token || typeof token !== "string") { throw new Error("token 必须是非空字符串"); } if (!filename || typeof filename !== "string") { throw new Error("filename 必须是非空字符串"); } const data = { file: filename }; const response = await requestApi( "/api/video/presign", token, data, constants.CREATE_MAX_ATTEMPTS, "预上传", ); if (response.data) { return response.data; ``` ```js // scripts/video2text/index.js:140 const presignedUrl = await video.getPresignedUrl(tokenValue, file); ``` ### Technical Analysis For local input, the `filename` argument can be an absolute or relative path supplied by the user. The entire value is serialized into the API request as the `file` property. A presigned upload operation generally needs an object name, media name, or extension—not the complete local filesystem path. Full paths can reveal operating-system usernames, home-directory layouts, mount points, project names, customer identifiers, or internal directory structures. ### Attack Path 1. A user invokes the Skill with a path such as `/home/alice/clients/acme/private-meeting.mp4`. 2. The path passes local-file validation. 3. `getPresignedUrl()` places the complete path in `{ file: filename }`. 4. `postJson()` serializes the object and sends it to `www.guaikei.com`. 5. The remote service receives both the intended filename and unrelated local directory metadata. ### Impact Assessment The remote API obtains local environment metadata beyond what is required to process the selected file. The issue does not expose the contents of other files and does not grant filesystem access or code execution. The scope is ...[truncated 178 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Send only `path.basename(filename)` rather than the complete local path. 2. Prefer a randomly generated object identifier while retaining only a validated media extension. 3. Remove path separators, control characters, and unexpected Unicode characters from any filename transmitted remotely. 4. Avoid recording full local paths in remote logs, telemetry, errors, or analytics. 5. Document the minimum metadata sent to the service and verify that the API does not require local directory information. 6. Add a test asserting that API request bodies never contain parent-directory components or absolute paths. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (30)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The skill gates functionality behind a private token and embeds marketing/contact acquisition flow, which increases the chance users are pushed to disclose or provision credentials to an unvetted third party. In an agent setting, credential collection and vendor lock-in messaging are risky because they normalize secret handling without clear trust boundaries or independent verification.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The skill gates functionality behind a private token and embeds marketing/contact acquisition flow, which increases the chance users are pushed to disclose or provision credentials to an unvetted third party. In an agent setting, credential collection and vendor lock-in messaging are risky because they normalize secret handling without clear trust boundaries or independent verification.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The skill gates functionality behind a private token and embeds marketing/contact acquisition flow, which increases the chance users are pushed to disclose or provision credentials to an unvetted third party. In an agent setting, credential collection and vendor lock-in messaging are risky because they normalize secret handling without clear trust boundaries or independent verification.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The skill gates functionality behind a private token and embeds marketing/contact acquisition flow, which increases the chance users are pushed to disclose or provision credentials to an unvetted third party. In an agent setting, credential collection and vendor lock-in messaging are risky because they normalize secret handling without clear trust boundaries or independent verification.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The skill gates functionality behind a private token and embeds marketing/contact acquisition flow, which increases the chance users are pushed to disclose or provision credentials to an unvetted third party. In an agent setting, credential collection and vendor lock-in messaging are risky because they normalize secret handling without clear trust boundaries or independent verification.

Natural-Language Policy Violations

Medium
Confidence
86% confidence
Finding
The README presents all user-facing instructions, warnings, and examples exclusively in Chinese. Under the policy rule, forcing a specific language without user opt-in is a natural-language policy concern unless the skill clearly documents that it is intended only for a Chinese-speaking or region-specific audience.

Whitespace Padding

Medium
Category
Prompt Injection
Content
4. 同时传入文件路径与任务ID,优先执行 `--id`,忽略 `--file`
5. 无自定义 prompt 时,默认完整转录视频全部文字

| 用户自然语言指令                                         | 自动生成命令                                                                                                |
| -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| 视频提取 https://example.com/video.mp4 中的文字          | `node scripts/video2text/index.js --file "https://example.com/video.mp4"`                                   |
| 把本地 /path/to/your/video.mp4 改成小红书风格的文案      | `node scripts/video2text/index.js --file "/path/to/your/video.mp4" --prompt "改写成小红书风格的文案"`       |
Confidence
70% confidence
Finding
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Lp3

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding
Without declared permissions the skill's intent is opaque and cannot be validated.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill processes user-supplied videos through a third-party cloud service, but the user warning about upload, remote processing, and data exposure is not made sufficiently prominent at the point of use. This is dangerous because users may provide sensitive internal recordings or confidential URLs without informed consent, leading to privacy, compliance, or contractual breaches.

Vague Triggers

Medium
Confidence
93% confidence
Finding
This package.json is a manifest file, so vague-trigger checks apply. The description and keyword list span many generic intents such as content creation, meeting minutes, course breakdown, interview整理, and short-video operations, but provide no explicit trigger phrases, scope boundaries, or negative examples, which could cause overly broad matching or unintended invocation.

Natural-Language Policy Violations

Medium
Confidence
78% confidence
Finding
The natural-language description is entirely in Chinese and explicitly promises outputs such as Chinese copywriting styles for platforms like 抖音 and 小红书, plus Chinese-English translation, but does not mention any option for language or locale selection. This can conflict with a language/locale policy requiring user choice unless the locale restriction is clearly documented and justified.

Natural-Language Policy Violations

Medium
Confidence
88% confidence
Finding
This JavaScript file uses Chinese-only natural-language strings in docstrings, operation labels, and thrown error messages, with no indication that the skill is region-specific or that users can choose another language. The policy requires flagging language or locale constraints when they are imposed without opt-in or justification.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
This JavaScript file contains natural-language comments and runtime log/error strings exclusively in Chinese, which imposes a specific language on users and operators. Under the policy, locale/language constraints should either be optional, user-selectable, or clearly justified as region-specific.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The stop flow deletes the target file when removeOnStop is enabled, and the error-handling path can remove files when removeOnFail is enabled, yet there is no user-facing disclosure that stopping or failed downloads may delete local files. This is a destructive file operation covered by SQP-2 for code files when no confirmation, print/log, comment, or documented warning is present.

Missing User Warnings

Medium
Confidence
87% confidence
Finding
This code performs network requests to arbitrary URLs and writes the received content to disk, but the file contains no confirmation prompt and no user-facing print/log statement disclosing that data will be fetched and saved locally. For a code file, SQP-2 applies when safety-relevant operations such as network access and file writes have no visible disclosure in the code itself.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
This JavaScript file contains natural-language comments and runtime status/error messages only in Chinese, such as the doc comment at L25 and multiple user-facing logs from L41-L78. Because the skill does not offer a language selection or document that it is intentionally limited to a Chinese-speaking context, it risks violating language/locale policy requirements.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
This file returns user-facing error text in Chinese, which imposes a specific language on users. The stated policy prohibits forcing a language or locale without user opt-in unless the constraint is clearly documented and justified, and no such opt-in or justification appears in this file.

Natural-Language Policy Violations

Medium
Confidence
98% confidence
Finding
The authentication failure message is presented only in Chinese and includes remediation guidance in that language. This is a natural-language policy issue because users are not given a language choice, and the file does not indicate that the skill is explicitly limited to a Chinese-speaking or region-specific audience.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
The file emits all user-facing warnings and status messages in Chinese, including error, info, and success output. Because this is a general utility module and no opt-in, fallback language, or documented region-specific constraint is present, it creates a language/locale policy issue for users who may not understand the messages.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
The banner text is hard-coded in Chinese, which imposes a specific language on users. Under the policy, language constraints should either be optional for the user or clearly documented as a justified locale-specific limitation.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
The manifest description forces a specific language/locale for core skill metadata, which can violate language-choice policy when no user opt-in or alternative is offered. This is especially relevant because the description defines triggering behavior and user-facing scope.

Natural-Language Policy Violations

Medium
Confidence
88% confidence
Finding
The user-facing SKILL.md content is written wholly in Chinese and directs usage in that language without any opt-in or alternative locale path. Under the policy, forcing a specific language without user choice is a natural-language policy concern.

Whitespace Padding

Medium
Category
Prompt Injection
Content
## 7. 🗣️ 自然语言 → 命令(照这张表转)

| 用户说的话                                           | 就执行这条命令                                                                                              |
| ---------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| 提取 https://example.com/video.mp4 里的文字          | `node scripts/video2text/index.js --file "https://example.com/video.mp4"`                                   |
| 总结这个视频的核心观点 https://example.com/video.mp4 | `node scripts/video2text/index.js --file "https://example.com/video.mp4" --prompt "总结这个视频的核心观点"` |
Confidence
70% confidence
Finding
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Whitespace Padding

Medium
Category
Prompt Injection
Content
## 7. 🗣️ 自然语言 → 命令(照这张表转)

| 用户说的话                                           | 就执行这条命令                                                                                              |
| ---------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| 提取 https://example.com/video.mp4 里的文字          | `node scripts/video2text/index.js --file "https://example.com/video.mp4"`                                   |
| 总结这个视频的核心观点 https://example.com/video.mp4 | `node scripts/video2text/index.js --file "https://example.com/video.mp4" --prompt "总结这个视频的核心观点"` |
Confidence
70% confidence
Finding
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Natural-Language Policy Violations

Low
Confidence
81% confidence
Finding
The manifest description and the entire skill guidance are presented in Chinese, and output examples assume Chinese-language prompting and Chinese platform-specific rewrites. While the skill later mentions language adaptation, the top-level description does not explicitly offer a language choice or state that users may interact in another language.

Static analysis

No suspicious patterns detected.