Back to skill

Security audit

videotocaption

Security checks for vulnerabilities and agentic risk

Overview

This video transcription skill mostly does what it says, but its URL handling and cloud upload path are too broad and under-disclosed for automatic trust.

Review before installing. Use it only for videos you are comfortable sending to the GuaiKei service and its storage provider. Do not give it confidential recordings or internal/private URLs unless that transfer is approved, and prefer local files or known public video links from a constrained network environment.

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
scripts/utils/validator.js:3
Finding
Unrestricted URL Download Enables Server-Side Request Forgery and External Data Exfiltration<![CDATA[ ## Vulnerability Details **File Location**: `scripts/utils/validator.js:3-6`, `scripts/video2text/index.js:97-106`, `scripts/video2text/index.js:140-149`, `scripts/utils/download.js:317-331`, `scripts/utils/upload.js:10-12`, `scripts/utils/upload.js:35-39` **Vulnerability Type**: Unrestricted URL fetching, redirect-based SSRF, and external upload of fetched content **Risk Level**: High ### Vulnerable Code ```js // scripts/utils/validator.js:3-6 function isUrl(url) { try { const parsedUrl = new URL(url); return parsedUrl.protocol === "http:" || parsedUrl.protocol === "https:"; } catch (_) { return false; } } ``` ```js // scripts/video2text/index.js:97-106 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); ``` ```js // scripts/video2text/index.js:140-149 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); utils.printInfo("文件上传到安全空间成功,获取视频分析任务ID"); ``` ```js // scripts/utils/download.js:317-331 const req = this.__protocol.request(options, (response) => { if (this.__isRequireRedirect(response)) { redirectCount++; if (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, url).href; this.emit("redirected", redirectedUR ...[truncated 3199 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Permit only explicitly supported public video providers or direct-media hosts where operationally possible. 2. Resolve hostnames before connecting and reject all non-public IPv4 and IPv6 ranges, including: - Loopback addresses. - RFC1918 private addresses. - Link-local addresses. - Unique-local IPv6 addresses. - Multicast, unspecified, reserved, and documentation ranges. - Cloud metadata endpoints. 3. Repeat destination validation after every redirect. Do not trust only the original URL. 4. Protect against DNS rebinding by connecting to a previously validated resolved address while preserving the expected TLS hostname. 5. Restrict destination ports to an approved set, normally 80 and 443. 6. Enforce a strict maximum redirect count. 7. Require an approved video MIME type and validate file signatures before upload. 8. Enforce maximum response and file sizes while streaming; abort the request immediately when limits are exceeded. 9. Apply a total download deadline in addition to socket inactivity timeouts. 10. Do not upload a fetched resource until all source, size, and media validation has completed successfully. 11. Consider running the downloader in a network sandbox that cannot reach loopback, private networks, metadata services, or internal infrastructure. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
scripts/api/video.js:19
Finding
Full Local Filesystem Path Is Disclosed to the External API<![CDATA[ ## Vulnerability Details **File Location**: `scripts/api/video.js:19-27` **Vulnerability Type**: Unnecessary disclosure of local filesystem metadata **Risk Level**: Low ### Vulnerable Code ```js const data = { file: filename }; const response = await requestApi( "/api/video/presign", token, data, constants.CREATE_MAX_ATTEMPTS, "预上传", ); ``` ### Technical Analysis The `filename` argument is the complete path supplied to `getPresignedUrl()`. For local files, this can include the user's home directory, account name, organization, project names, client identifiers, and internal directory structure. The full path is serialized into the request body and sent to `www.guaikei.com` when obtaining upload authorization. A complete local path is not necessary to create an object-storage upload URL; a basename, generated object identifier, extension, or validated MIME type should be sufficient. ### Attack Path 1. A user processes a sensitive local path, such as `/home/alice/clients/acme-merger/interview.mp4`. 2. The command passes the complete path to `video.getPresignedUrl()`. 3. `getPresignedUrl()` creates the payload `{ file: filename }`. 4. The request layer serializes and sends that payload to the external API. 5. The service receives local workstation metadata unrelated to the video content itself. ### Impact Assessment The issue does not provide filesystem access and does not expose the file contents beyond the separately intended video upload. It can, however, disclose sensitive environmental metadata, including: - Local usernames and home-directory structure. - Organization, customer, or project names. - Confidential case, campaign, or engagement identifiers embedded in directories. - Operating-system and deployment layout details. This information may assist profiling, social engineering, or follow-on attacks and violates data-minimization principles. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace the full path with `path.basename(filename)` before constructing the API payload. 2. Prefer a cryptographically random object name rather than preserving the original filename. 3. If file-type information is required, send only a separately validated extension or MIME type. 4. Remove directory components and control characters from any filename transmitted remotely. 5. Document all metadata sent to the external service and apply strict data-minimization rules. 6. Add an automated test confirming that request bodies never contain absolute paths, home-directory names, or parent-directory components. ]]>
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 (29)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The skill advertises video transcription, but its documented behavior includes generic remote downloading over HTTP/HTTPS, local file writes, metadata probing, and retry controls. Those capabilities materially expand risk: attacker-supplied URLs could trigger SSRF-like access, download unexpected content, or persist untrusted data locally, especially since the manifest frames public links broadly rather than tightly constraining allowed domains.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The skill advertises video transcription, but its documented behavior includes generic remote downloading over HTTP/HTTPS, local file writes, metadata probing, and retry controls. Those capabilities materially expand risk: attacker-supplied URLs could trigger SSRF-like access, download unexpected content, or persist untrusted data locally, especially since the manifest frames public links broadly rather than tightly constraining allowed domains.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The skill advertises video transcription, but its documented behavior includes generic remote downloading over HTTP/HTTPS, local file writes, metadata probing, and retry controls. Those capabilities materially expand risk: attacker-supplied URLs could trigger SSRF-like access, download unexpected content, or persist untrusted data locally, especially since the manifest frames public links broadly rather than tightly constraining allowed domains.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The usage section actively instructs users to submit local video files or public video URLs to a third-party cloud processing service, but it does not present a clear, proximate warning that the content leaves the user's environment and is transmitted to an external provider. Although the README later makes privacy assurances, those are marketing claims rather than an informed-consent warning at the point of use, so users may upload sensitive recordings, meetings, interviews, or internal media without understanding the disclosure risk.

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
91% confidence
Finding
The skill requests access to an environment secret (`GUAIKEI_API_TOKEN`) but does not declare an explicit tool scope or permissions boundary. In agent environments, missing scope declarations can cause over-broad execution rights and make secret handling less auditable, increasing the chance of unintended secret exposure or misuse.

Natural-Language Policy Violations

Medium
Confidence
84% confidence
Finding
The manifest description states output types such as meeting notes, copywriting, and translation entirely in Chinese terms and does not indicate user language choice. This creates a locale-policy issue because the skill appears oriented to Chinese output by default rather than explicitly offering language selection up front.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill processes user-supplied videos and links via a remote service, but the warning about remote upload is not presented prominently up front. This creates a privacy and informed-consent risk: users may provide sensitive local files or URLs without realizing the content will be transmitted off-host to a third party.

Intent-Code Divergence

Medium
Confidence
85% confidence
Finding
The documentation states that error messages should be neutral and should not include marketing copy, contact information, or website links. However, nearby documentation and later sections repeatedly embed the vendor website and WeChat contact in operational guidance, which contradicts the stated intent of keeping failure handling free of promotional material.

Vague Triggers

Medium
Confidence
88% confidence
Finding
The manifest description advertises many loosely bounded use cases such as transcription, summarization, rewriting, translation, and content generation across multiple platforms without clearly defining when the skill should or should not be invoked. In agentic environments, broad trigger language increases the chance of over-invocation, unintended handling of sensitive user content, or routing tasks to this skill outside its safe operational scope.

Natural-Language Policy Violations

Medium
Confidence
87% confidence
Finding
This JavaScript file contains natural-language strings exclusively in Chinese across docstrings, operation labels, and error messages. Under the policy rules, forcing a specific language without user opt-in or a clearly documented regional constraint is a language/locale policy violation.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
The file's comments, error messages, and generated help text are all hard-coded in Chinese, including thrown errors and CLI help output. This creates a language/locale policy concern because the skill enforces a specific language for user-facing interactions without any opt-in, fallback, or documented region-specific justification.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
This module performs HTTP/HTTPS requests and writes downloaded content to disk, including deleting partial files on stop or failure, but the file contains no confirmation prompt and no user-facing disclosure such as a print/log statement or explanatory docstring about these safety-relevant actions. Because the operations affect local files and transmit data over the network, the absence of any in-file warning meets the code-file criteria for missing user disclosure.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
The code emits a fixed Chinese-language error string in a user-facing exception message. This imposes a specific language/locale choice without offering the user any language selection or documented justification, which matches the natural-language locale policy violation criteria.

Natural-Language Policy Violations

Medium
Confidence
98% confidence
Finding
This error message is presented only in Chinese and includes support instructions, making it clearly user-facing natural language. Because the skill does not offer language opt-in or document a justified region-specific restriction here, it violates the language/locale policy guidance.

Natural-Language Policy Violations

Medium
Confidence
89% confidence
Finding
Across these lines, thrown errors for input validation, parsing, timeout, and retry exhaustion are hard-coded in Chinese. These are user-visible natural-language strings and collectively force a locale without opt-in or documented justification, which falls under the policy violation category.

Natural-Language Policy Violations

Medium
Confidence
98% confidence
Finding
The file emits all user-facing warning and status text exclusively in Chinese, including the critical message that the skill is paused and instructions for remediation. This creates a language/locale policy concern because the skill does not appear to offer any language selection or opt-in for non-Chinese output.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The skill processes local videos and public URLs through an external cloud service, but the description does not clearly warn users that their content and possibly fetched URLs will be uploaded off-host. For a media-transcription skill, this omission is significant because users may submit confidential recordings, meetings, interviews, or internal training videos without informed consent.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The trust section states the skill only communicates with guaikei.com, but the skill also accepts arbitrary public video URLs and documents downloading remote media before upload. That mismatch hides the real network exposure surface from users and reviewers, which matters because processing untrusted external URLs can trigger unexpected outbound requests and data transfer to third parties.

Intent-Code Divergence

Medium
Confidence
94% confidence
Finding
The skill promises uploaded video is destroyed and not stored, but other sections describe task ID reuse for up to 24 hours and temporary local file retention. These contradictory retention claims can cause users to share sensitive media under false assumptions about deletion and persistence.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The documentation claims errors will be neutral and free of marketing/contact information, yet nearby sections instruct users to obtain tokens via the vendor website or WeChat and include direct business contact details. This inconsistency can mislead users and downstream agents about what may be emitted during failure handling, increasing the risk of social-engineering style prompts or policy bypass through trusted error channels.

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.

Intent-Code Divergence

Low
Confidence
98% confidence
Finding
Section 10 says the skill's declared name is `video2text-ai`, presented as a compliance claim. The actual frontmatter name at the top of the file is `videotocaption`, so the documentation actively misstates the implemented manifest identity.

Natural-Language Policy Violations

Low
Confidence
76% confidence
Finding
The natural-language metadata is overwhelmingly Chinese-specific, including the main description and most keywords, but there is no indication that users can choose another language or that the locale restriction is intentional and documented. This may violate language/locale policy when a skill implicitly forces one language without opt-in.

Static analysis

No suspicious patterns detected.