Back to skill

Security audit

guaikei-douyin-pull-comments-stream

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its Douyin data-collection purpose, but it needs Review because token handling and runtime output contradict important security promises.

Install only if you are comfortable with Guaikei receiving your Douyin search terms, URLs, and API token, and with fetched public data being saved locally by default. Use a low-privilege or disposable token if possible, avoid invoking it for ambiguous requests, and prefer a revised version that sends credentials in headers, removes runtime contact/marketing messages, and makes file export opt-in.

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:100
Finding

API Token Exposed in URL Query Strings

Content
View full analysis

Vulnerability Details

File Location: src/utils/request.js:100-107, 128-134; token-bearing parameters originate from src/api/search.js:59-62, 104-107, src/api/post.js:23-25, 50-53, src/api/comment.js:38-40, 67-70, and src/api/hot.js:19-22
Vulnerability Type: Sensitive credential exposure through request URLs
Risk Level: Medium

Vulnerable Code

js
const params = {
  _: Date.now(),
  token: token,
};
js
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),
  },
};

The same behavior occurs for GET requests:

js
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

The value of GUAIKEI_API_TOKEN is inserted into the params object and serialized directly into the URL query string. Although the connection uses HTTPS, transport encryption does not prevent the complete request URL from being retained after TLS termination.

Query strings are commonly recorded by web-server access logs, reverse proxies, API gateways, application performance monitoring systems, error diagnostics, and traffic-analysis infrastructure. Consequently, systems or personnel that should only have access to operational logs may also receive a reusable authentication token.

Authentication secrets should not be placed in URLs. They should be transmitted through an authorization header or another dedicated secret-bearing header, with explicit redaction in diagnostics.

Attack Path

  1. A user configures a va ...[truncated 892 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove token from every URL parameter object.

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

    js
    headers: {
      Authorization: `Bearer ${token}`,
      "Content-Type": "application/json",
      "Accept-Encoding": "identity",
    }
    
  3. Refactor getJson() and postJson() so credentials are accepted separately from ordinary query parameters.

  4. Configure API servers, proxies, and monitoring systems to redact Authorization and any legacy token parameters.

  5. Do not include request headers or token-bearing URLs in error messages or debug output.

  6. Rotate existing tokens because they may already have been retained in infrastructure logs.

  7. Add automated tests asserting that generated request paths never contain token, api_token, or the configured secret value.

other

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

Undisclosed Runtime Advertising and Contact Injection in Authentication Errors

Content
View full analysis

Vulnerability Details

File Location: src/utils/token.js:23-30; src/utils/request.js:49-56
Vulnerability Type: Undisclosed promotional redirection through runtime error output
Risk Level: Low

Vulnerable Code

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

  utils.printInfo("已使用配置的私有TOKEN");
  return token;
}

A rejected remote token produces an additional personal contact message:

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

Technical Analysis

SKILL.md:40-44, SKILL.md:103, and SKILL.md:144 explicitly state that authentication failures will produce only a neutral error and that runtime output will not contain websites, contact information, or marketing language.

The implementation contradicts those declared controls. A locally invalid or missing token prints the vendor website, while an HTTP 401 or 403 response embeds a personal WeChat contact number in the propagated authentication error. The CLI catches the error and includes error.message in Agent-visible output, so the contact message can reach both the user and any automation consuming command results.

This is not command execution or privilege escalation. It is a trust and output-integrity issue because behavior concealed by the declared specification redirects users toward an external promotional or personal-contact channel.

Attack Path

Missing or malformed token path:

  1. The Skill is invoked without a correctly formatted GUAIKEI_API_TOKEN.
  2. skillToken() rejects the value.
  3. The function writes the vendor website to standard error.
  4. The Agent or user receives an unsol ...[truncated 869 chars]
Remediation
View remediation

Remediation Suggestions

  1. Replace both authentication-failure messages with the neutral message documented by the Skill, such as:

    js
    utils.printError(
      "GUAIKEI_API_TOKEN is not configured or has an invalid format. The Skill has been paused.",
    );
    
  2. Ensure HTTP 401 and 403 responses create an AuthError containing only a stable error code and neutral explanation.

  3. Keep vendor websites, sales language, quota-upgrade instructions, and personal contact information exclusively in clearly identified user documentation.

  4. Do not copy arbitrary upstream error text directly into structured Agent output without sanitization.

  5. Add regression tests that invoke the missing-token and rejected-token paths and assert that output contains no URLs, phone numbers, messaging-platform references, or promotional language.

  6. Reconcile SKILL.md with implementation behavior and enforce the documented runtime-output policy during code review.

Vulnerability Patterns
  • 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
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (47)

Tp4

High
Category
MCP Tool Poisoning
Confidence
84% confidence
Finding

The skill states that it automatically saves logs under logs/ with timestamped filenames, but this local file-writing behavior is not clearly declared in permissions/scope. Undeclared filesystem writes can create privacy and operational risk by persisting user queries, URLs, and scraped content on disk where they may be accessed later or retained longer than expected.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill states that it automatically saves logs under logs/ with timestamped filenames, but this local file-writing behavior is not clearly declared in permissions/scope. Undeclared filesystem writes can create privacy and operational risk by persisting user queries, URLs, and scraped content on disk where they may be accessed later or retained longer than expected.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill states that it automatically saves logs under logs/ with timestamped filenames, but this local file-writing behavior is not clearly declared in permissions/scope. Undeclared filesystem writes can create privacy and operational risk by persisting user queries, URLs, and scraped content on disk where they may be accessed later or retained longer than expected.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill states that it automatically saves logs under logs/ with timestamped filenames, but this local file-writing behavior is not clearly declared in permissions/scope. Undeclared filesystem writes can create privacy and operational risk by persisting user queries, URLs, and scraped content on disk where they may be accessed later or retained longer than expected.

Content

No source excerpt is available for this finding.

Vague Triggers

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill says it should trigger even when a user only says vague phrases like '查一下' or '帮我看看' without naming Douyin. Overbroad invocation criteria can cause unintended activation, sending unrelated user requests or context into a data-collection workflow and increasing the chance of unnecessary external requests, token use, and logging.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill explicitly depends on the environment variable GUAIKEI_API_TOKEN, but the manifest does not declare any tool scope, permissions, or allowed-tools boundary for environment access. Missing capability declarations weaken least-privilege controls and make it harder for a host agent to safely reason about what the skill needs before invocation.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The generalized trigger condition expands invocation to broad short-video research scenarios even without platform mention. In an agent setting, such broad routing can mis-handle user intent and cause unexpected collection, processing, or storage of requests that were not meant for this skill, making accidental data exposure more likely.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The phrase "纯中文界面" indicates the skill forces a specific language/locale. The file does not provide user opt-in, alternative language support, or a clear justification that the locale restriction is necessary for a region-specific compliance purpose.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The manifest explicitly says the skill is not responsible for downloading videos, but this response schema defines play_addr as both a playback address and a '视频下载地址' (video download address). That indicates the skill exposes download-oriented data as part of its declared API surface, which goes beyond the stated description.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill advertises data export and later documents that logs are automatically saved under a local logs directory, but this persistence behavior is not clearly surfaced as an upfront warning near initial usage. Because the tool collects scraped comments, account data, and search results, silent default storage increases the risk of retaining sensitive or regulated data without user awareness.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The README maps very common phrases like “搜索 / 搜一下 / 找 …” to scraping actions, and the skill metadata explicitly says even vague requests like “查一下”“帮我看看” should trigger Douyin use. This can cause overbroad activation from ordinary conversation and lead the agent to scrape external-platform data the user did not clearly and specifically request.

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 use broad triggers such as “热搜 / 热点 / 榜单 / 今天什么火” and “搜索 / 搜一下 / 找 + 关键词” with insufficient scope constraints. In context, this makes unintended invocation more likely, especially because the skill is designed to collect and export third-party platform data, including comments and account content.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This code sends a token and a user-provided video URL to remote API endpoints via requestApi, which is a privacy- and security-relevant network operation. Although the functions have developer-facing docstrings, there is no user-facing disclosure, confirmation, or visible warning in this file about transmitting these values off-box.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The comment retrieval path places both the token and video URL into GET query parameters, which are more likely to be exposed via logs, proxies, browser history, monitoring tools, and upstream infrastructure. Even if HTTPS is used, sensitive values in URLs often persist in places operators do not expect, increasing risk of token leakage and unintended disclosure of user-requested targets.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The CLI persists the full fetched comment payload to a local JSON file after already printing it, creating an undeclared secondary storage channel for potentially sensitive or regulated data. In this skill context, users expect retrieval/query behavior for Douyin comments, not durable local retention, so this increases privacy and data handling risk if the host environment is shared or logs are later collected.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

Writing comment results to a local JSON file without explicit user notice or consent creates a quiet data retention behavior that users may not anticipate. Because the skill is framed as a query/research utility, silent persistence makes the behavior more dangerous by expanding the data footprint beyond the immediate command output.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

This code uses Chinese-only natural-language strings in comments, error messages, and success output, such as the main function description and runtime messages. Under the policy rule, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is clearly documented and justified, which is not evident in this file.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

The calls to post.createPostTask and post.getPostTask send the normalized Douyin URL and query parameters to an external service using an API token. This file logs progress but does not clearly warn the user that supplied input and related system-authenticated requests will be sent over the network.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The CLI persists fetched post results to a local JSON file even though the skill is described as a lookup/retrieval tool, creating data at rest that users may not expect. This increases privacy and data-handling risk because scraped platform content and request metadata can remain on disk, be accessed by other local users/processes, or be collected later without clear consent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The code writes fetched post data and associated request metadata to a local JSON file without any explicit warning in this file, which can surprise users and create unintended retention of scraped data. Even if the content is publicly sourced, the aggregation plus timestamps and query context may be sensitive in some environments.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This JavaScript file contains user-facing descriptions, help text, and operational messages entirely in Chinese, including argument descriptions and output notices. Under the policy rule, forcing a specific language without user opt-in or a documented regional justification is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This file contains natural-language content exclusively in Chinese, including comments, thrown error messages, and generated help text. Per the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is explicitly justified, which is not present here.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

This code returns user-facing natural-language messages such as "请求失败" in Chinese, and similar Chinese-only strings appear throughout the file. Because the skill does not offer a language choice or document a justified locale restriction here, this creates a language/locale policy violation under the rule for natural-language policy issues.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The AuthError message is entirely in Chinese and directs the user to a specific support contact, which assumes a Chinese-speaking locale. The file does not provide any user language selection or indicate that the skill is restricted to that locale, so this is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This file contains user-facing status and warning messages only in Chinese, including the warning and success/info outputs. That can violate language/locale policy when the skill is used in a broader environment, because it forces a specific language without any visible opt-in or alternative locale handling.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.