Back to skill

Security audit

guaikei-video-to-text

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its video-to-text purpose, but its URL handling can fetch and upload arbitrary reachable web resources without strong limits, so it needs review before installation.

Install only if you are comfortable sending selected videos, prompts, and a GUAIKEI_API_TOKEN-backed request to an external service. Avoid using untrusted URLs or running this on machines with access to internal network services until the skill restricts private-address URLs, validates redirects, enforces download size/time limits, and clearly discloses upload destinations.

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 Fetching Enables Server-Side Request Forgery and Data Exfiltration<![CDATA[ ## Vulnerability Details **File Locations**: - `scripts/utils/validator.js:3-8` - `scripts/video2text/index.js:96-118` - `scripts/video2text/index.js:140-154` - `scripts/utils/download.js:478-493` - `scripts/utils/download.js:909-926` **Vulnerability Type**: Server-Side Request Forgery (SSRF) with subsequent response upload **Risk Level**: High ### Vulnerable Code ```js // scripts/utils/validator.js:3-8 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-118 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/video2text/index.js:140-154 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"); if (presignedUrl.url.indexOf("?") === -1) { throw new Error("预签名URL格式错误,请反馈给开发者"); } const url = presignedUrl.url.substring(0, presignedUrl.url.indexOf("?")); const task = await video.getVideoId(tokenValue, url); ``` ```js // scripts/utils/download.js:478-493 if (this.__isRequireRedirect(response)) { this.__redirectCount++; if (this.__redirectCount > this.__opts.maxRedirects) { const err = new Error("Too many redirects"); this.__setState(this.__states.F ...[truncated 3637 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Resolve each destination hostname before making a request and reject every resolved address in prohibited IPv4 and IPv6 ranges, including: - Loopback - Private-use - Link-local - Multicast - Unspecified addresses - Reserved and documentation ranges - Known cloud metadata addresses 2. Apply the same validation to every redirect destination. Do not rely solely on validating the initial URL. 3. Prevent DNS rebinding by connecting only to an IP address that was resolved and validated by the application while retaining the original hostname for TLS Server Name Indication and certificate verification. 4. Where operationally possible, use an allowlist of approved public video hosts rather than accepting arbitrary HTTP endpoints. 5. Consider requiring HTTPS for remote media. If HTTP must remain supported, explicitly document and constrain its use. 6. Reject URLs containing embedded credentials unless this capability is explicitly required. 7. Disable redirects by default or limit them to a small number and require each redirect to retain an approved public destination. 8. Separate downloading from uploading and verify that the result is an expected media type before sending it to an external service. 9. Add tests covering direct and redirected requests to loopback, private IPv4, IPv4-mapped IPv6, link-local, metadata, and DNS-rebinding destinations. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/utils/download.js:31
Finding
Unbounded Remote Downloads Permit Disk, Bandwidth, and Execution-Time Exhaustion<![CDATA[ ## Vulnerability Details **File Locations**: - `scripts/utils/download.js:31-49` - `scripts/utils/download.js:464-474` - `scripts/utils/download.js:525-548` - `scripts/utils/helper.js:25-35` **Vulnerability Type**: Uncontrolled resource consumption through unbounded downloads **Risk Level**: Medium ### Vulnerable Code ```js // scripts/utils/download.js:31-49 this.__defaultOpts = { body: null, retry: false, method: "GET", headers: {}, fileName: "", timeout: -1, metadata: null, override: false, forceResume: false, removeOnStop: true, removeOnFail: true, maxRedirects: 10, progressThrottle: 1000, httpRequestOptions: {}, httpsRequestOptions: {}, resumeOnIncomplete: true, resumeIfFileExists: false, resumeOnIncompleteMaxRetry: 5, }; ``` ```js // scripts/utils/download.js:464-474 return this.__protocol.request(this.__reqOptions, (response) => { this.__response = response; if (!this.__isResumed) { this.__total = parseInt(response.headers["content-length"]) || null; this.__resetStats(); } if (this.__isResumed && response.statusCode === 200) { this.__isResumed = false; this.__total = parseInt(response.headers["content-length"]) || null; ``` ```js // scripts/utils/download.js:525-548 if (!this.__isResumed) { const _fileName = this.__getFileNameFromHeaders(response.headers); this.__filePath = this.__getFilePath(_fileName); this.__fileName = this.__filePath.split(path.sep).pop(); if (fs.existsSync(this.__filePath)) { const downloadedSize = this.__getFilesizeInBytes(this.__filePath); const totalSize = this.__total ? this.__total : 0; if ( typeof this.__opts.override === "object" && this.__opts.override.skip && (this.__opts.override.skipSmaller || downloadedSize >= totalSize) ) { this.emit("skip", { totalSize: this.__total, fileName: this.__fileName, filePath: this.__filePath, downloadedSize: downloadedSize, }); ...[truncated 3056 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Define a strict, configurable maximum download size appropriate for supported video workloads. 2. Reject responses whose declared `Content-Length` exceeds the configured limit before creating the output file. 3. Count bytes during streaming and immediately abort the response, destroy the request, close the file stream, and remove the partial file when the actual byte count crosses the limit. 4. Apply the byte counter even when `Content-Length` is present because the header may be inaccurate. 5. Configure separate safeguards for: - DNS and connection timeout - Time to first byte - Idle read timeout - Maximum overall download duration 6. Validate the response `Content-Type` against an explicit allowlist of supported audio and video types. Content-type checking should supplement, not replace, byte limits. 7. Check available disk space before starting large downloads and reserve sufficient headroom for the host. 8. Limit retry and resume behavior so repeated partial transfers cannot exceed a total per-task byte or time budget. 9. Store downloads in a dedicated, quota-controlled temporary directory rather than directly under the project tree. 10. Ensure partial files are synchronously or reliably removed after size-limit, timeout, and stream failures. 11. Add automated tests for oversized declared lengths, missing lengths, chunked endless responses, slow responses, inaccurate headers, and retry-based amplification. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (22)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The finding describes a skill marketed as speech-to-text and text transformation, but lacking any actual transcription, subtitle extraction, summarization, rewriting, or translation logic. In context, the skill is especially risky because users may supply local files, URLs, and API credentials to a tool whose true behavior is materially different from its presentation.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The finding describes a skill marketed as speech-to-text and text transformation, but lacking any actual transcription, subtitle extraction, summarization, rewriting, or translation logic. In context, the skill is especially risky because users may supply local files, URLs, and API credentials to a tool whose true behavior is materially different from its presentation.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The finding describes a skill marketed as speech-to-text and text transformation, but lacking any actual transcription, subtitle extraction, summarization, rewriting, or translation logic. In context, the skill is especially risky because users may supply local files, URLs, and API credentials to a tool whose true behavior is materially different from its presentation.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The finding describes a skill marketed as speech-to-text and text transformation, but lacking any actual transcription, subtitle extraction, summarization, rewriting, or translation logic. In context, the skill is especially risky because users may supply local files, URLs, and API credentials to a tool whose true behavior is materially different from its presentation.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The finding describes a skill marketed as speech-to-text and text transformation, but lacking any actual transcription, subtitle extraction, summarization, rewriting, or translation logic. In context, the skill is especially risky because users may supply local files, URLs, and API credentials to a tool whose true behavior is materially different from its presentation.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The finding describes a skill marketed as speech-to-text and text transformation, but lacking any actual transcription, subtitle extraction, summarization, rewriting, or translation logic. In context, the skill is especially risky because users may supply local files, URLs, and API credentials to a tool whose true behavior is materially different from its presentation.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The finding describes a skill marketed as speech-to-text and text transformation, but lacking any actual transcription, subtitle extraction, summarization, rewriting, or translation logic. In context, the skill is especially risky because users may supply local files, URLs, and API credentials to a tool whose true behavior is materially different from its presentation.

Natural-Language Policy Violations

Medium
Confidence
83% confidence
Finding
The README is entirely written in Chinese and the examples and prompt guidance assume Chinese-language use, but there is no statement offering an alternate language or letting users opt into a locale. This can violate language/locale policy when a skill effectively requires one language by default without user choice.

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
84% confidence
Finding
The skill declares access to an environment secret (`GUAIKEI_API_TOKEN`) but does not define an explicit tool/permission scope such as allowed tools or network boundaries in an enforceable way. In an agent setting, missing explicit scope weakens least-privilege guarantees and can let a skill gain broader execution context than reviewers or users expect.

Vague Triggers

Medium
Confidence
92% confidence
Finding
Broad trigger phrases such as common requests for text extraction or drafting can cause the agent to invoke this skill in situations the user did not specifically intend. Because this skill claims access to local files, URLs, and an external API, accidental invocation increases the chance of unintended data transfer or secret use.

Vague Triggers

Medium
Confidence
88% confidence
Finding
The invocation guidance prioritizes this skill for very broad categories like summaries, content analysis, and drafting, which can overshadow safer or more appropriate tools. In a skill that may upload media or call external APIs, overbroad routing increases the risk of unnecessary disclosure of user content and incorrect autonomous execution.

Whitespace Padding

Medium
Category
Prompt Injection
Content
当用户用自然语言下达指令时,按以下映射生成命令,保证识别与执行一致:

| 用户自然语言指令                                     | 生成的命令                                                                                                  |
| ---------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| 提取 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

Medium
Confidence
92% confidence
Finding
The file's docstrings, validation errors, and operation labels are all written in Chinese, which indicates a fixed language choice in user-visible and developer-facing text. Under the stated policy, forcing a specific language without opt-in is a natural-language policy violation unless the locale restriction is explicitly justified, which is not present here.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
This JavaScript file contains natural-language comments and user-facing messages entirely in Chinese, including thrown errors and generated help text. Because these strings define the CLI's user-visible language without any opt-in, fallback, or documented region-specific justification, they create a language/locale policy concern under the natural-language policy rule.

Missing User Warnings

Medium
Confidence
87% confidence
Finding
This code constructs and sends outbound HTTPS POST requests containing arbitrary JSON data and a TOKEN header. While the network behavior is clear in code, there is no confirmation prompt or user-facing warning in this file explaining that user/system data and credentials may be transmitted to a remote service.

Natural-Language Policy Violations

Medium
Confidence
98% confidence
Finding
The skill emits all user-facing status and warning text in Chinese, including warnings and recovery instructions, with no indication that users can choose another language. This is a natural-language locale policy issue because the file hard-codes a specific language for operational messaging without opt-in or documented justification.

Natural-Language Policy Violations

Low
Confidence
79% confidence
Finding
The description advertises translating content into English as a built-in capability, but does not mention preserving the user's language preference or requiring explicit user request for language changes. This can conflict with language/locale policy expectations when a skill changes output language without opt-in.

Natural-Language Policy Violations

Low
Confidence
88% confidence
Finding
This JavaScript file contains natural-language comments and runtime messages exclusively in Chinese, including user-facing status and error text. The policy only permits fixed language behavior when the skill offers a language choice or clearly documents a justified locale constraint, which is not evident here.

Natural-Language Policy Violations

Low
Confidence
90% confidence
Finding
This JavaScript file contains a Chinese-only doc comment and multiple Chinese user-facing status/error strings, which imposes a specific language without any opt-in or fallback. The policy explicitly flags language or locale constraints when the skill does not offer user choice or clearly document a justified region-specific requirement.

Natural-Language Policy Violations

Low
Confidence
95% confidence
Finding
The code presents user-visible error messages entirely in Chinese, including credential and support guidance, without offering any language selection or documenting a justified locale restriction. This can violate language/locale policy when the skill is not explicitly limited to Chinese-speaking users.

Natural-Language Policy Violations

Low
Confidence
95% confidence
Finding
The banner text is fixed to Chinese ("视频文案智能提取助手") and the file provides no indication that users can opt into another language or locale. Under the policy rule for natural-language violations, forcing a specific language without user choice is a reportable issue.

Static analysis

No suspicious patterns detected.