Back to skill

Security audit

Guaikei Douyin Search And Analyze

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly aligned with Douyin public-data analysis, but it needs review because runtime behavior contradicts its own safety claims and handles the API token unsafely.

Install only if you are comfortable sending Douyin keywords, URLs, request parameters, and the GUAIKEI_API_TOKEN to guaikei.com. Treat generated logs as retained local data, avoid collecting more comments or posts than needed, follow Douyin terms and privacy laws, and rotate the token if it may have been exposed.

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/request.js:51
Finding

Hard-Coded Promotional Solicitation Injected into Agent-Consumable Authentication Errors

Content
View full analysis

Vulnerability Details

File Location: src/utils/request.js:51-56; propagated through src/douyin/search-cli.js:172-198, src/douyin/comment-cli.js:83-103, src/douyin/post-cli.js:84-104, and src/douyin/hot-cli.js:21-39
Vulnerability Type: Runtime output manipulation and promotional instruction injection
Risk Level: Medium

Vulnerable Code

Authentication failures are converted into an error containing a hard-coded external contact:

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

The CLI then places the unfiltered message into both diagnostic output and the JSON response consumed by an agent:

js
} catch (error) {
  utils.printError(`搜索失败: ${error.message}`);
  const errorOutput = {
    status: "error",
    error_code: error.code || "UNKNOWN",
    message: error.message,
    timestamp: new Date().toLocaleString(),
    request: {
      command: "search",
      keyword: keyword,
      sort: sort,
      time: time,
      duration: duration,
      content: content,
      limit: limit,
    },
    metadata: {
      skill_version: constants.VERSION,
      runtime_version: process.versions.node,
      execution_time: Date.now() - startTime,
    },
    results: null,
  };
  const exitCode = error.name === "AuthError" ? 3 : 1;
  process.stdout.write(JSON.stringify(errorOutput, null, 2) + "\n", () =>
    process.exit(exitCode),
  );
  return;
}

Technical Analysis

The runtime implementation embeds a phone or WeChat contact in an authentication error and passes the message directly into agent-consumable JSON. Equivalent propagation exists in all four CLI entry points.

This conflicts with the Skill contract in SKILL.md, which states that authentication failures must produce only a neut ...[truncated 1566 chars]

Remediation
View remediation

Remediation Suggestions

  1. Replace the hard-coded message with a neutral authentication failure:
    js
    const e = new AuthError(
      "GUAIKEI_API_TOKEN is missing, invalid, or expired.",
    );
    
  2. Do not include phone numbers, social-media identifiers, website links, payment instructions, or token-acquisition guidance in runtime errors.
  3. Define stable, non-promotional error codes separately from display messages, such as AUTH_REQUIRED.
  4. Sanitize remote and locally constructed error messages before placing them in agent-consumable JSON.
  5. Add automated tests covering HTTP 401 and 403 responses. Tests should reject runtime output containing phone numbers, URLs, contact instructions, or promotional phrases.
  6. Apply the same centralized error formatter to all CLI entry points so that future messages cannot bypass the policy.

T09 · Insecure Skill Coding Practices

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

API Credential Transmitted in URL Query Parameters

Content
View full analysis

Vulnerability Details

File Location: src/utils/request.js:94-120 and src/utils/request.js:123-143; callers include src/api/search.js:50-80,95-123, src/api/comment.js:37-55,66-82, src/api/hot.js:16-24, and corresponding post API methods
Vulnerability Type: Sensitive credential exposure through URL query strings
Risk Level: Medium

Vulnerable Code

API methods place the token in the request parameter object:

js
async function createSearchTask(
  token,
  keyword,
  sort,
  time,
  duration,
  content,
  limit,
) {
  const params = {
    _: Date.now(),
    token: token,
  };

  const data = {
    keyword,
    sort_type: sort,
    publish_time: time,
    filter_duration: duration,
    content_type: content,
    limit: limit,
  };

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

The shared request utility serializes those parameters directly into the URL:

js
async function postJson(path, params, data) {
  if (!path || typeof path !== "string") {
    throw new SkillError("PATH_INVALID", "path 必须是非空字符串");
  }
  if (!params || typeof params !== "object") {
    throw new SkillError("PARAM_INVALID", "params 必须是对象");
  }
  if (!data || typeof data !== "object") {
    throw new SkillError("DATA_INVALID", "data 必须是对象");
  }
  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",
    headers: {
      "Content-Type": "application/json",
      "Accept-Encoding": "identity",
      "Content-Length": Buffer.byteLength(jsonData),
    },
  };

  return await request(options, jsonData);
}

GET requests use the same unsafe construc ...[truncated 2877 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove token from all URL parameter objects.
  2. Send the credential in a dedicated authorization header:
    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 and getJson to accept authentication separately from ordinary query parameters.
  4. Ensure logs, traces, exceptions, and debug output redact the authorization header.
  5. Rotate existing tokens because historical server or proxy logs may already contain them.
  6. Configure the API gateway and application server to redact sensitive query keys during migration.
  7. Add tests that inspect outbound request paths and fail if a token or other secret appears in the URL.
  8. Prefer short-lived, scoped tokens with server-side revocation and usage monitoring.
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 it 'does not read/write user private files,' yet it also specifies automatic logging to a local logs/ directory and local directory creation. Undeclared filesystem writes increase the attack surface for data leakage, log injection, and persistence of sensitive operational details, especially if logs accidentally capture inputs, URLs, or error payloads.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill states it 'does not read/write user private files,' yet it also specifies automatic logging to a local logs/ directory and local directory creation. Undeclared filesystem writes increase the attack surface for data leakage, log injection, and persistence of sensitive operational details, especially if logs accidentally capture inputs, URLs, or error payloads.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill states it 'does not read/write user private files,' yet it also specifies automatic logging to a local logs/ directory and local directory creation. Undeclared filesystem writes increase the attack surface for data leakage, log injection, and persistence of sensitive operational details, especially if logs accidentally capture inputs, URLs, or error payloads.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill states it 'does not read/write user private files,' yet it also specifies automatic logging to a local logs/ directory and local directory creation. Undeclared filesystem writes increase the attack surface for data leakage, log injection, and persistence of sensitive operational details, especially if logs accidentally capture inputs, URLs, or error payloads.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill states it 'does not read/write user private files,' yet it also specifies automatic logging to a local logs/ directory and local directory creation. Undeclared filesystem writes increase the attack surface for data leakage, log injection, and persistence of sensitive operational details, especially if logs accidentally capture inputs, URLs, or error payloads.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill states it 'does not read/write user private files,' yet it also specifies automatic logging to a local logs/ directory and local directory creation. Undeclared filesystem writes increase the attack surface for data leakage, log injection, and persistence of sensitive operational details, especially if logs accidentally capture inputs, URLs, or error payloads.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill states it 'does not read/write user private files,' yet it also specifies automatic logging to a local logs/ directory and local directory creation. Undeclared filesystem writes increase the attack surface for data leakage, log injection, and persistence of sensitive operational details, especially if logs accidentally capture inputs, URLs, or error payloads.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
83% confidence
Finding

The skill explicitly relies on an environment variable (GUAIKEI_API_TOKEN) but does not declare a corresponding tool scope or permissions model. This creates hidden capability requirements and weakens reviewability, making it easier for a skill to access sensitive runtime secrets without clear operator awareness.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The activation rule instructs use of the skill even when the user does not explicitly mention Douyin, which broadens invocation beyond clear user intent. Over-broad triggering can cause unnecessary external queries, inappropriate data handling, and unanticipated token use, especially when multiple short-video platforms or generic research contexts are possible.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

Explicitly directing invocation 'even if Douyin is not mentioned' makes the trigger scope ambiguous and can cause the agent to route unrelated requests into a networked, token-using skill. In context, this is more dangerous because the skill accesses public-platform data and uses an API token, so accidental activation expands external data exposure and resource use.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The schema explicitly documents video_url as containing both playback and download addresses, which conflicts with the skill metadata stating it is not for download-related use. In a Douyin scraping/search skill, exposing download URLs materially enables downstream consumers to use the skill for video retrieval beyond the declared scope, weakening policy boundaries and increasing abuse risk.

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 states the skill is not applicable to video downloading, but this response schema documents play_addr as both a playback address and a video download address. That broadens the apparent behavior beyond searching/analyzing public Douyin information into facilitating media retrieval.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The documentation explicitly enables bulk collection of Douyin creator content and comments, including fetching up to 10,000 items, but provides no notice about privacy, consent, platform terms, retention, or downstream use restrictions. In a scraping/analytics skill, that omission materially increases the risk of over-collection, profiling, or non-compliant handling of user-generated content, especially comments that may contain personal data.

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 a token and user-supplied video URL to external API endpoints when creating a comment task. Although the functions have developer-facing docstrings, there is no user-facing confirmation, warning, or disclosure in this file that potentially sensitive identifiers and URLs are being transmitted.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The CLI persists fetched comment data to a local JSON file after completing a read/search action, creating a secondary copy of potentially sensitive or regulated content without clearly signaling that behavior. This expands the data exposure surface because comments may contain personal data, and the file can remain on disk longer than the user expects or be accessible to other local processes/users.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

Writing comment results to a local file without explicit notice or confirmation can violate user expectations for a search/analysis skill and may silently retain personal or sensitive information from public comments. Even if the source data is public, undisclosed local retention increases privacy and compliance risk and can lead to accidental disclosure through backups, shared workstations, or later reuse.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This code uses Chinese-only natural-language strings in comments, errors, and success messages such as '获取抖音热榜失败' and '抖音热榜任务完成'. That enforces a specific language/locale experience without any visible user opt-in or documented locale constraint, which matches the language-policy violation criteria.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
81% confidence
Finding

The script reads an API token from the environment and uses it to create and fetch a remote post task, transmitting the provided Douyin URL and request parameters to an external service. Although network access is central to the tool's purpose, this file does not include a user-facing disclosure that input data is sent to a remote API.

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 fetched Douyin post data to a local JSON file after completing a read/search operation. This creates undeclared local data retention, which can expose scraped content, queried targets, and execution metadata to other local users, backup systems, or downstream tooling without the user's awareness.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The program silently writes fetched results to a local JSON file without an explicit user-facing warning or consent mechanism. Even if the data is public, silent persistence changes the privacy and security posture by creating a durable artifact that may be discoverable by other software or users on the host.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The AuthError string is entirely in Chinese and includes user guidance, which imposes a specific language on users without opt-in. Under the policy, language-specific instructions are a natural-language policy violation unless the skill offers a language choice or clearly documents a justified locale restriction.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This file contains natural-language comments and console messages exclusively in Chinese, including the user warning and status output. Because the skill does not provide any user opt-in or indicate that it is intentionally limited to a Chinese-speaking audience, it may violate language/locale policy expectations.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This JavaScript file uses Chinese-only natural-language comments, validation errors, and formatted output messages throughout. Under the policy, forcing a specific language without user opt-in or a documented justified locale constraint is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

This JSON schema uses Chinese-only natural-language title and description fields for the schema and its properties. For a general-purpose skill artifact, this imposes a specific language/locale without indicating user opt-in or a documented region-specific constraint.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

The schema title and description are written only in Chinese, which can indicate a fixed language assumption without any stated user opt-in or documented locale restriction. Under the policy, hard-coded language constraints can be a natural-language policy issue when no choice or justification is provided.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.