Back to skill

Security audit

抖音评论获取助手

Security checks for vulnerabilities and agentic risk

Overview

This Douyin data tool largely matches its stated purpose, but it needs Review because it sends its API token in URL parameters and automatically saves collected social-media results locally.

Install only if you are comfortable sending Douyin keywords, URLs, identifiers, and your GUAIKEI_API_TOKEN to guaikei.com. Treat generated logs as potentially sensitive because they may contain usernames, IDs, comment text, and research targets; delete or protect them after use. Prefer a version that sends tokens in authorization headers and offers explicit --save/--no-save or output-path controls.

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

Warning
Location
src/utils/request.js:106
Finding
API Token Transmitted in URL Query Strings<![CDATA[ ## Vulnerability Details **File Location**: `src/api/search.js:59-62, 104-107`; `src/api/comment.js:38-41, 67-70`; `src/api/post.js:23-25, 50-52`; `src/api/hot.js:19-21`; `src/utils/request.js:106-118, 128-138` **Vulnerability Type**: Credential exposure through URL query parameters **Risk Level**: Medium ### Vulnerable Code The API modules place the token in the parameter object: ```js // src/api/search.js:59-62 const params = { _: Date.now(), token: token, }; ``` The request utility then serializes every parameter, including the token, into the URL: ```js // src/utils/request.js:106-118 const fullPath = `${path}?${querystring.stringify(params)}`; const jsonData = JSON.stringify(data); const options = { host: constants.BASE_URL, path: fullPath, method: "POST", headers: { "Content-Type": "application/json", "Accept-Encoding": "identity", "Content-Length": Buffer.byteLength(jsonData), }, }; ``` GET requests use the same behavior: ```js // src/utils/request.js:128-138 const fullPath = `${path}?${querystring.stringify(params)}`; const options = { host: constants.BASE_URL, path: fullPath, method: "GET", headers: { "Accept-Encoding": "identity" }, }; return await request(options); ``` ### Technical Analysis Although HTTPS encrypts the request in transit, it does not make query strings an appropriate location for bearer credentials. The token becomes part of the HTTP request target, such as: ```text /api/douyin/comment/info?_=...&token=<credential>&url=... ``` Request targets are routinely recorded by origin-server access logs, reverse proxies, API gateways, tracing platforms, monitoring agents, and diagnostic systems. Consequently, the token may be exposed to systems and personnel that should not receive authentication credentials. This behavior affects all implemented API capabilities: search, hot-list retrieval, creator-post retrieval, and comment retrieval. ### Attack Path 1. A user stores a valid creden ...[truncated 1015 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `token` from all URL parameter objects. 2. Transmit the credential in an authorization header, for example: ```js const options = { host: constants.BASE_URL, path: fullPath, method: "POST", headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json", "Accept-Encoding": "identity", "Content-Length": Buffer.byteLength(jsonData), }, }; ``` 3. Refactor `postJson`, `getJson`, and `requestApi` so the credential is passed separately from ordinary query parameters. 4. Configure the server, reverse proxies, and telemetry systems to redact authorization headers and sensitive request metadata. 5. Rotate tokens that have previously been transmitted in URLs, because they may already exist in historical logs. 6. Add automated tests that fail if `token`, `authorization`, or other credential fields appear in generated request paths. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
src/utils/log.js:27
Finding
Automatic Plaintext Persistence of Retrieved Social-Media Data<![CDATA[ ## Vulnerability Details **File Location**: `src/utils/log.js:27-35`; `src/douyin/search-cli.js:258-261`; `src/douyin/comment-cli.js:159-162`; `src/douyin/post-cli.js:160-162` **Vulnerability Type**: Insecure local storage and unrestricted retention of collected data **Risk Level**: Low ### Vulnerable Code The logging utility creates a persistent directory and writes content without explicitly restrictive file permissions: ```js // src/utils/log.js:27-35 const outputFilename = path.join( path.dirname(__filename), "..", "..", "logs", safeFilename, ); try { await fs.promises.mkdir(path.dirname(outputFilename), { recursive: true }); await fs.promises.writeFile(outputFilename, content); ``` Successful comment results are automatically saved in full: ```js // src/douyin/comment-cli.js:159-162 await log.taskWrite( `${startTime}_${url}_comment.json`, JSON.stringify(finalOutput, null, 2), ); ``` Successful search results are handled similarly: ```js // src/douyin/search-cli.js:258-261 await log.taskWrite( `${startTime}_${keyword}_${sort}_${time}_${duration}_${content}_search.json`, JSON.stringify(finalOutput, null, 2), ); ``` ### Technical Analysis Successful search, post, and comment operations automatically persist their complete structured output under the project-level `logs` directory. The stored records can include: - Search keywords and filter selections - Requested creator or content identifiers - Douyin URLs - Public usernames and account identifiers - Comment text and interaction data - Timestamps and complete API response records The files are written using permissions derived from the process umask rather than an explicitly restrictive mode. On systems with permissive defaults, other local users or processes may be able to read them. There is no CLI option to disable persistence, no configured expiration period, no cleanup mechanism, and no data-minimization step. The README discloses automatic JSON logging, so t ...[truncated 1146 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Make result persistence opt-in rather than automatic. 2. Add explicit controls such as `--save`, `--output <path>`, and `--no-save`. 3. Create the log directory with owner-only permissions: ```js await fs.promises.mkdir(logDirectory, { recursive: true, mode: 0o700, }); ``` 4. Write result files with owner-only permissions and reject symbolic-link targets: ```js await fs.promises.writeFile(outputFilename, content, { mode: 0o600, flag: "wx", }); ``` 5. Apply data minimization by omitting unnecessary user identifiers, request metadata, and full raw responses. 6. Implement a documented retention period and an automatic cleanup mechanism. 7. Warn users when files are saved and provide the exact path and deletion instructions. 8. Document that generated files may contain privacy-sensitive research data and should not be committed, synchronized, or shared without review. 9. Add `logs/` to `.gitignore` if repository use is expected. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • 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 (42)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
从提供的代码块看,只有 `src/api/search.js`,其功能集中在调用 `/api/douyin/general-search/keyword` 和 `/api/douyin/general-search/info` 两个接口,参数也完全对应关键词搜索、排序、发布时间、时长、内容类型和数量限制等搜索能力。这与声明中的第(1)项“关键词搜索视频/图文”是吻合的。但声明还强调第(2)热榜查询、第(3)博主作品抓取、第(4)视频评论分析,当前代码块中没有任何对应接口、函数、数据处理逻辑或资源访问痕迹。因此该描述对当前提供代码块而言明显过度声明了能力范围。不存在额外未声明的敏感能力;问题在于声明覆盖范围远大于实际实现。

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
从提供的代码块看,其核心功能仅限于“抖音作品评论获取/分析”。它不会执行关键词搜索、热榜查询或博主作品列表抓取,因此代码实际行为明显比描述更窄。评论获取这一项与声明中的第(4)项基本一致,但声明将技能整体描述为具备四大能力,而该代码块只覆盖其中一个子能力,导致描述与实际代码行为不完全匹配。代码中的写日志、token 校验、参数解析属于实现细节,不构成额外未声明能力。

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
代码片段仅实现了通用命令行参数解析与帮助文本生成(parseArgs、readValueAfterFlag、buildHelp),属于基础工具层代码。它没有显示出任何与抖音平台交互的逻辑,例如网络请求、解析抖音链接/aweme_id/sec_uid、获取热榜、抓取作品列表或评论数据等。因此,按当前提供的代码片段,其实际行为与声明的技能用途存在明显不一致。虽然这可能是某个更大项目中的辅助模块,但基于该片段本身,应判定为描述与行为不匹配。

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
声明描述的是面向抖音搜索、热榜、博主作品抓取和评论分析的数据采集/分析能力;而代码片段实际仅实现了本地日志文件写入辅助功能,没有任何与抖音、网络请求、搜索、热榜、博主作品抓取或评论获取相关的行为。虽然日志工具可能是技能内部的辅助实现,但就该代码片段本身而言,其行为与声明的核心能力不一致,且包含未在声明中体现的本地文件系统写入能力。因此应判定为描述与代码行为不匹配。

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The declared description presents a full-featured Douyin analytics and retrieval skill. However, the supplied code chunk does not interact with Douyin, perform network requests, parse links, retrieve comments, query hot lists, or fetch creator content. It simply reads package.json from the local filesystem and returns the package name. This is materially different from the declared primary purpose, so the description does not accurately represent the behavior of the provided code chunk.

Credential Access

High
Category
Privilege Escalation
Content
- 技能重命名为“douyin-search-keyword”。
- 在SKILL.md中添加了openclaw元数据、使用帮助、许可证、标签和示例,以实现更好的集成与文档化。
- 移除了两个本地文件(.env 和 scripts/last-search.json),以优化代码结构并提升安全性。
- 文档现已更加简洁且以用户为中心,重点在于提供清晰的使用说明和数据字段解释。
- 突出技能特性、合规要点及技术流程。
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Lp3

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

Vague Triggers

Medium
Confidence
89% confidence
Finding
The trigger list includes broad business-analysis phrases such as '短视频选题', '抖音舆情', and '抖音数据分析', which can cause the agent to invoke this skill for loosely related requests without clear user intent or sufficient identifiers. In a skill that sends requests to a third-party API and processes public social-media data, overbroad routing increases the chance of unintended data disclosure to the external service and unnecessary execution.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The README promotes collecting public Douyin videos, author information, comments, and writing structured logs, but it does not warn that these outputs can still contain personal or sensitive data such as usernames, profile identifiers, comment text, and behavioral metadata. This omission increases the chance that operators will collect, retain, or redistribute personal data without appropriate minimization, notice, access controls, or downstream handling safeguards.

Natural-Language Policy Violations

Medium
Confidence
85% confidence
Finding
The file title and all release-note content are written in Chinese, with no indication that language selection is optional or that this skill is region-specific. Under the policy, natural-language content that imposes a specific language without user opt-in can be a locale-policy violation.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
This is a markdown file, so SQP-2 applies to omissions in user-facing documentation. The document explains how to retrieve comment data, creator works, and search results at scale (up to 10,000 items) but does not warn users that these actions may involve third-party data collection, privacy considerations, or compliance with platform terms.

Description-Behavior Mismatch

Medium
Confidence
93% confidence
Finding
The CLI persists fetched Douyin comment data to a local JSON file without any visible consent, warning, retention control, or redaction. Comment datasets can contain personal data and sensitive content, so silent local storage increases privacy, compliance, and unintended disclosure risk if the host is shared, monitored, or later exfiltrated.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The code writes comment results to disk unconditionally and the CLI file does not provide any explicit notice before doing so. In the context of a comment-analysis skill, this is more dangerous because the collected data is user-generated content that may contain identifiers, opinions, or other sensitive material, making silent persistence a privacy and operational security issue.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
Natural-language strings throughout the file, including help text and runtime messages, force a specific language/locale for all users. The policy allows locale constraints only when users are given a choice or the restriction is clearly justified, neither of which is present here.

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
Several user-facing error messages are hard-coded in Chinese, including the authentication failure message and general request errors. This enforces a specific language for users without any visible language-selection mechanism or documented locale constraint.

Missing User Warnings

Medium
Confidence
84% confidence
Finding
This code issues outbound HTTPS GET and POST requests using caller-supplied params and data, which may include user or system data. While there is retry logging for failures, there is no confirmation prompt, user-facing notice, or inline warning here describing that data will be sent to a remote API.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
This JavaScript file contains natural-language comments and user-visible validation errors entirely in Chinese, including the strings emitted via utils.printError. Under the policy rule, forcing a specific language without user opt-in is a locale/language policy violation unless the tool is clearly documented as region-specific, which is not established in this file.

Natural-Language Policy Violations

Low
Confidence
89% confidence
Finding
The title and description fields, including the parameter description, are entirely in Chinese. Because this schema does not document that it is intended only for Chinese-speaking users or offer a language choice, it may impose a locale/language constraint without user opt-in.

Natural-Language Policy Violations

Low
Confidence
94% confidence
Finding
This JSON schema contains user-facing title and description strings exclusively in Chinese, including field descriptions, with no indication that language selection is optional. Under the policy scope for natural-language violations, forcing a specific language without user opt-in can be a locale-policy issue.

Natural-Language Policy Violations

Low
Confidence
89% confidence
Finding
This manifest-style JSON schema contains human-facing title and description fields entirely in Chinese, which effectively fixes the skill metadata to a specific language. Under the policy, language constraints should either be optional for the user or clearly documented as a justified regional limitation.

Natural-Language Policy Violations

Low
Confidence
95% confidence
Finding
The schema's natural-language fields are entirely in Chinese, including the title and parameter descriptions. Because no opt-in, language selection, or documented region-specific justification is present in this file, this appears to enforce a specific language/locale in user-facing metadata.

Vague Triggers

Low
Confidence
81% confidence
Finding
This JSON schema is a manifest-scoped file, so vague-trigger review applies. The description only states that it fetches a Douyin creator's works and explains CLI parameters, but it does not define specific invocation wording, scope constraints, or exclusion conditions, which can make activation behavior overly broad if this metadata is used for routing.

Natural-Language Policy Violations

Low
Confidence
92% confidence
Finding
This manifest-format file contains natural-language descriptions entirely in Chinese, including the title and every property description. Because the file does not indicate that the skill is intentionally region-specific or provide any user opt-in or alternative locale, it can violate a language/locale policy that forbids forcing a specific language by default.

Natural-Language Policy Violations

Low
Confidence
86% confidence
Finding
This manifest/schema uses only Chinese natural-language titles and descriptions for the skill inputs, but does not document that the skill is Chinese-language-only or limited to a Chinese locale. Under the policy, a language constraint should be explicit or offer user opt-in to avoid silently forcing a specific language.

Natural-Language Policy Violations

Low
Confidence
91% confidence
Finding
This JSON schema uses Chinese titles and descriptions throughout, such as the title and all property descriptions, which imposes a specific language on users or integrators without any opt-in or alternative locale. The stated policy flags language or locale constraints when they are forced and not documented as optional or region-specific.

Static analysis

Detected: suspicious.exposed_secret_literal

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
SKILL.md:24