Back to skill

Security audit

guaikei-douyin-intel-exchange

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it claims, but it has review-worthy issues around broad automatic activation, third-party API/token exposure, runtime promotional messages, and local retention of collected social-media data.

Install only if you are comfortable sending Douyin search terms, account/video URLs, and your GUAIKEI_API_TOKEN to guaikei.com, and with results being saved locally in logs by default. Treat generic trend/search requests carefully so the skill is only invoked for intended Douyin work, and avoid using it to obtain or redistribute downloadable media URLs.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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)

T01 · Skill Instruction Hijacking

Warning
Location
src/utils/token.js:23
Finding

Runtime Authentication Errors Inject Undisclosed Promotional and Contact Messaging

Content
View full analysis

Vulnerability Details

File Location: src/utils/token.js:23-29; src/utils/request.js:50-57; contradictory security requirement in SKILL.md:31-39
Vulnerability Type: Runtime output manipulation and violation of declared skill behavior
Risk Level: Medium

Evidence

The skill explicitly states that invalid-token errors must be neutral and must not include contact details, website links, or promotional language:

text
## ⚠️ 令牌管理规范

令牌无效时**仅输出中性错误**,不输出联系方式、官网链接或营销话术。

✅ GUAIKEI_API_TOKEN 未配置或格式无效,技能已暂停。
   请检查环境变量 GUAIKEI_API_TOKEN 是否已设置有效令牌。

❌ 禁止:输出微信/官网链接/营销话术("一键解锁""早配置早享受"等)

However, the missing or malformed token path prints a promotional website:

javascript
function skillToken(token) {
  if (!isValidToken(token)) {
    utils.printWarn("警告: 你的 GUAIKEI_API_TOKEN 未正确配置,技能已暂停. ");
    utils.printSuccess("\t快速获取通道: www.guaikei.com");
    return "";
  }

The HTTP authentication failure path also embeds a telephone/WeChat contact in the exception:

javascript
} else if (res.statusCode === 401 || res.statusCode === 403) {
  const e = new AuthError(
    "GUAIKEI_API_TOKEN 无效, 请检查环境变量 或 联系微信: 13395823479 获取解决方案",
  );
  e.noRetry = true;
  reject(e);
}

Technical Analysis

The executable implementation contradicts the skill's declared safety and token-management policy. Users and agents reviewing SKILL.md are told that authentication failures produce only neutral diagnostic messages, while both invalid-token paths inject acquisition or contact messaging at runtime.

The server-controlled authentication path is particularly significant. A 401 or 403 response from www.guaikei.com causes the hard-coded contact message to be placed in an AuthError. CLI entry points subsequently copy error.message into the JSON response written to standard output and print it through the logging utility. Consequently, the promotional content can enter both human ...[truncated 1757 chars]

Remediation
View remediation

Remediation Suggestions

  1. Replace all invalid-token output with the neutral message promised by SKILL.md.

  2. Remove the website from src/utils/token.js and the telephone/WeChat contact from src/utils/request.js.

  3. Use a stable machine-readable error such as:

    javascript
    new AuthError(
      "GUAIKEI_API_TOKEN is missing, invalid, or rejected. Check the configured environment variable.",
    );
    
  4. Keep token acquisition information exclusively in readme.md, as the skill policy declares.

  5. Add automated tests covering:

    • Missing tokens.
    • Malformed tokens.
    • HTTP 401 responses.
    • HTTP 403 responses.
    • JSON standard output and standard-error output.
  6. Make the tests fail if runtime authentication errors contain URLs, telephone numbers, social-media contacts, or acquisition language.

  7. Review every user-visible error supplied by the remote service before forwarding it to agent output. Prefer locally defined neutral messages for authentication and authorization failures.

T09 · Insecure Skill Coding Practices

Warning
Location
src/utils/request.js:94
Finding

API Credential Is Transmitted in URL Query Strings

Content
View full analysis

Vulnerability Details

File Location: src/utils/request.js:94-100; token-bearing call sites in src/api/search.js:59-62,104-113, src/api/comment.js:38-41,67-72, src/api/post.js:23-26,50-55, and src/api/hot.js:19-22
Vulnerability Type: Sensitive credential exposure through URL query parameters
Risk Level: Medium

Evidence

The common request utility serializes the supplied parameter object directly into the request URL:

javascript
params.skill_name = skillName();

const fullPath = `${path}?${querystring.stringify(params)}`;
const jsonData = JSON.stringify(data);

const options = {
  host: constants.BASE_URL,
  path: fullPath,
  method: "POST",
};

GET requests use the same query-string construction:

javascript
params._ = Date.now();

const fullPath = `${path}?${querystring.stringify(params)}`;
const options = {
  host: constants.BASE_URL,
  path: fullPath,
  method: "GET",
  headers: { "Accept-Encoding": "identity" },
};

Every API module places the secret token in that parameter object. For example:

javascript
const params = {
  _: Date.now(),
  token: token,
};

return await requestApi(
  "POST",
  "/api/douyin/general-search/keyword",
  params,
  data,
  constants.CREATE_MAX_ATTEMPTS,
  "创建任务",
);

The corresponding result request also exposes the token in its URL:

javascript
const params = {
  _: Date.now(),
  token: token,
  keyword: keyword,
  sort_type: sort,
  publish_time: time,
  filter_duration: duration,
  content_type: content,
  limit: limit,
};

const response = await requestApi(
  "GET",
  "/api/douyin/general-search/info",
  params,
  null,
  constants.QUERY_MAX_ATTEMPTS,
  "查询任务",
);

Technical Analysis

querystring.stringify(params) converts the API token into a URL component such as:

text
/api/douyin/general-search/info?token=SECRET&keyword=.
...[truncated 2453 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove token from every query-parameter object.

  2. Send the credential through an authorization header, for example:

    javascript
    headers: {
      Authorization: `Bearer ${token}`,
      "Content-Type": "application/json",
      "Accept-Encoding": "identity",
    }
    
  3. Refactor postJson() and getJson() so authentication is accepted separately from ordinary request parameters. This prevents future callers from accidentally serializing credentials into URLs.

  4. Ensure redirects are either disabled or restricted to the trusted API origin so authorization headers cannot be forwarded to an unintended host.

  5. Configure server, proxy, CDN, APM, and tracing systems to redact Authorization, legacy token parameters, and other credential fields.

  6. Rotate existing API tokens because historical access logs may already contain them.

  7. Purge or restrict access to legacy URL logs, observability records, and backups according to the provider’s retention capabilities.

  8. Add tests asserting that generated request paths never contain token=, while the required authorization header is present.

  9. Use short-lived, revocable, least-privilege tokens where supported, and implement server-side rate limits and anomaly monitoring to reduce replay impact.

Vulnerability Patterns
  • 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
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (54)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

从提供的代码看,只有 createSearchTask 和 getSearchTask 两个接口,分别调用 /api/douyin/general-search/keyword 和 /api/douyin/general-search/info,明显对应抖音通用关键词搜索。processSearchResults 只是对搜索结果补充 author_url 和 create_time_str,属于搜索结果后处理。声明中强调“搜、扒、翻、追四个动作覆盖搜索、博主作品、评论、热榜”,但当前代码片段只覆盖“搜”,没有看到针对博主作品列表、评论数据、热榜数据的接口访问或处理逻辑。因此描述对能力范围有明显夸大,属于描述与实际行为不符。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

从代码看,src/douyin/post-cli.js 的核心行为是解析 --url 和 --limit 参数,校验抖音用户主页 URL 或 sec_uid,调用 post.createPostTask 与 post.getPostTask 获取指定博主的作品列表,然后将结果以 JSON 输出并写入日志。这与声明中的“四个动作覆盖搜索、博主作品、评论、热榜”不一致:当前代码只覆盖“博主作品”这一项,缺少搜索、评论、热榜相关实现。因此存在描述与实际行为不匹配,属于声明范围明显大于该代码片段实际能力的情况。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

声明描述的是一个面向抖音内容分析的技能,核心能力应涉及抖音数据查询或处理。而提供的代码只是通用参数解析器(parseArgs、readValueAfterFlag、buildHelp),负责处理命令行输入和帮助文案生成,不访问抖音、不执行搜索、不读取评论、不获取热榜,也不分析博主作品。这不是仅仅‘支持性实现细节’,因为当前代码块本身的功能与声明的业务目的明显不一致,且完全缺少声明中最核心的能力,因此应判定为描述与行为不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

声明描述的是一个面向抖音数据检索/分析的技能,核心能力应涉及搜索、抓取博主作品、查看评论或热榜等。实际代码却只是一个本地日志写入工具,没有任何与抖音、搜索、评论、热榜、博主分析相关的行为。虽然日志功能可能是辅助实现细节,但在当前提供的代码片段中,唯一可见能力就是文件系统写入,这与声明的主要用途明显不一致,因此应判定为描述与行为不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

声明描述的是一个面向抖音内容搜索与分析的技能,核心能力应涉及查询抖音相关数据(热门内容、博主、评论、热榜等)。但提供的代码片段只是在本地通过 fs 读取 package.json,并返回包名。这属于内部元数据读取/辅助工具,不体现任何与抖音数据访问、搜索、分析或评论处理相关的行为。虽然这可能是技能内部的辅助函数,但就该代码片段本身而言,其实际行为与声明用途明显不一致,应判定为不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

声明描述的是一个覆盖“搜、扒、翻、追”四类抖音分析动作的综合技能,但所给代码片段只实现了热榜数据的消息格式化输出,没有体现搜索、博主作品抓取/分析、评论查看/分析等能力。虽然热榜属于声明范围之一,但当前代码的实际行为明显比声明范围窄,无法支撑整体描述中的主要能力集合。因此描述与代码行为存在明显不一致。

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding

The skill explicitly depends on an environment variable (GUAIKEI_API_TOKEN) but does not declare tool scope or permissions for environment access. This creates an authorization gap where the runtime may expose sensitive capabilities implicitly, making review and containment harder if the skill is expanded or misused.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill says it should be used even when the user does not mention Douyin, which makes invocation boundaries overly broad and increases the chance the agent routes unrelated research requests into this skill. That can cause unexpected third-party data access, overcollection, and user-surprising behavior, especially because the skill performs external data retrieval and logging.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

Generic trigger phrases like '帮我做短视频竞品调研' or '最近什么热门' are broad enough to match many normal research tasks unrelated to Douyin. In an agentic environment, this can lead to inappropriate skill execution, unnecessary API use with protected tokens, and unintended collection of platform-specific data without clear user intent.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The schema explicitly describes video_url as including both playback and download addresses, which conflicts with the skill metadata stating it is not intended for downloading material. This mismatch can enable downstream agents or integrators to use the skill for content acquisition beyond its declared scope, increasing the risk of policy bypass, copyright misuse, or unauthorized media downloading.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest explicitly says the skill is not suitable for downloading素材, implying a read-only intel/research scope around search, creators, comments, and trending content. However, the schema documents play_addr as both a playback address and a '视频下载地址', which indicates the skill exposes downloadable media URLs beyond the stated purpose.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The README advertises automatic JSON log generation and later states files are saved under the logs directory, but it does not prominently warn that collected video, author, and comment data will be persisted locally by default. This creates a real risk of unintentional retention of potentially sensitive or regulated content, especially on shared machines or in synced working directories. The issue is more serious in this skill because it handles large-scale collection of public comments and creator data, which may still carry privacy and compliance obligations when stored.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill requires a GUAIKEI_API_TOKEN and sends search terms, creator identifiers, video URLs, comments, or hot-list requests to an external service, but the README does not clearly warn users that their inputs and targets are transmitted off-platform. Users may reasonably assume local processing because the README emphasizes Node.js local execution and convenience. Lack of explicit disclosure undermines informed consent and can expose sensitive research interests, monitored accounts, or target URLs to a third party.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The README defines natural-language triggers such as "搜索 / 搜一下 / 找" and states the skill should be used even when the user did not explicitly mention Douyin. Those broad phrases can cause unintended activation in unrelated contexts, resulting in external requests and data collection without clear user intent. In a skill that queries third-party services, overbroad routing is a real safety issue because it can transmit user queries or target URLs unexpectedly.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The intent-recognition rules prioritize broad terms like "热搜 / 热点 / 榜单 / 今天什么火" and "搜索 / 搜一下 / 找 + 关键词" without sufficient scope constraints. This can misroute everyday user requests into Douyin scraping/search actions, especially since the skill description says it should trigger even if the user did not mention Douyin. The danger is amplified because the skill performs external data retrieval and may write results to logs, so accidental invocation has privacy and consent implications.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This markdown file documents commands for retrieving a creator's published works and video comment data, which can affect privacy expectations and involve collection of user-generated content. The description provides usage details but does not include any warning or disclosure about handling public social-media data, respecting platform terms, or potential privacy impact.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

This code sends the user-provided search keyword and a skill token to an external API via requestApi, which is a network operation involving potentially sensitive data. Although the functions have technical docstrings, there is no visible user warning, confirmation, or user-facing notice here that search terms and token-derived access data will be transmitted.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The query function performs a GET request containing the token and keyword in request parameters, which transmits user/system data over the network. In this file there is no user-facing disclosure, prompt, or warning that these values will be sent during result retrieval.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

This file contains natural-language comments exclusively in Chinese, and the skill does not indicate that the locale is user-selectable or that the skill is intentionally limited to a Chinese-speaking audience. Under the policy, forcing a specific language without opt-in can be a natural-language policy violation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This code accesses a sensitive credential via process.env.GUAIKEI_API_TOKEN and then uses it to create and fetch a remote comment task. While the file logs URL activity, it does not provide a user-facing warning or explanatory comment about credential use or the outbound API interaction, which matches the code-file missing-warning criteria.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The code persists the final output to disk using log.taskWrite, which is a file write affecting local user data/storage. Although success messages are printed, there is no visible disclosure before the write that results will be saved to a file, and this file itself does not document that behavior.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

Natural-language strings throughout the file, including status and error messages, are fixed in Chinese. This can violate language/locale policy when users are not offered a language option or informed that the skill is Chinese-only.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

The CLI reads an API token from the environment and uses it to send the requested Douyin target and query parameters to an external backend. For a skill described as read-only Douyin intelligence retrieval, undisclosed backend exfiltration of user-supplied targets expands the trust boundary and can leak usage data, analyst targets, or sensitive research activity to a third party.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The script persists fetched results to a local JSON file after completing the request, even though the skill description frames the behavior as interactive retrieval. This creates silent local data retention of scraped content and targets, which can expose research subjects, internal investigations, or user activity to other local users, backup systems, or later compromise.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The CLI writes the fetched post dataset to a local file without any clear user-facing notice that data will be stored. Silent persistence is risky because users may believe the tool is ephemeral while it actually leaves recoverable artifacts containing collected content and request metadata.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.