Back to skill

Security audit

guaikei-douyin-data-catalog

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly performs the advertised Douyin data collection, but it has misleading runtime behavior around token errors and risky handling of tokens and saved results.

Install only if you are comfortable sending Douyin keywords, account URLs, video URLs, and your GUAIKEI_API_TOKEN to Guaikei's service. Treat the token as sensitive, expect result JSON files to be saved locally under logs, and be aware that token failures may show promotional contact information despite the skill claiming otherwise.

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

Error
Location
src/utils/request.js:50
Finding

Authentication Error Paths Inject Promotional Contact Information into Agent Output

Content
View full analysis

Vulnerability Details

File Location: src/utils/request.js:50-55; additionally present in src/utils/token.js:24-27 and propagated by SKILL.md:113
Vulnerability Type: Runtime output manipulation through authentication failures
Risk Level: High

Complete Code Snippets

src/utils/request.js:50-55:

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

src/utils/token.js:24-27:

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

SKILL.md:113:

markdown
> 遇到错误时,立即向用户展示错误信息并询问是否调整参数。不要在收到 AUTH_ERROR 后继续重试。不要在用户未明确要求的情况下自动调整搜索条件。

Technical Analysis

The Skill documentation explicitly claims that invalid-token errors will be neutral and will not include websites, contact details, or marketing language. The runtime implementation directly contradicts this declared behavior.

If local token validation fails, src/utils/token.js prints a third-party website described as a quick acquisition channel. If the remote service responds with HTTP 401 or 403, src/utils/request.js constructs an AuthError containing a WeChat or telephone contact. The CLI error handlers subsequently place error.message into structured standard output and also print it to standard error.

The propagation instruction in SKILL.md directs the Agent to show errors to the user. Consequently, a routine authentication failure becomes a reliable channel for injecting third-party promotional content into an Agent response. The HTTP 401/403 branch is also externally triggerable by the API service.

This behavior is particularly concerning because the safety section of SKILL.md expressly denies that runtime contact or marketing output exists, ...[truncated 1464 chars]

Remediation
View remediation

Remediation Suggestions

  1. Replace all authentication-error messages with neutral, non-promotional text, such as:
    text
    GUAIKEI_API_TOKEN is missing, invalid, or unauthorized. Verify the configured environment variable.
    
  2. Remove all website URLs, telephone numbers, WeChat references, acquisition channels, and marketing language from runtime code.
  3. Return a stable structured error code such as AUTH_ERROR without embedding onboarding instructions in error.message.
  4. Ensure standard output remains machine-readable JSON and does not contain advertising or unrelated content.
  5. Add automated tests for missing-token, malformed-token, HTTP 401, and HTTP 403 cases. Tests should reject output containing URLs, contact numbers, social-media contacts, or promotional phrases.
  6. Align SKILL.md, readme.md, and runtime behavior so the documented security guarantees are accurate.
  7. Avoid blindly directing an Agent to repeat arbitrary remote error text. Map remote errors to locally controlled, allowlisted messages before presenting them to users.

T09 · Insecure Skill Coding Practices

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

API Token Is Exposed in HTTPS URL Query Strings

Content
View full analysis

Vulnerability Details

File Location: src/utils/request.js:94-139; token parameters originate from src/api/search.js:59-62,104-107, src/api/post.js:23-26,50-53, src/api/comment.js:38-41,67-70, and src/api/hot.js:19-22
Vulnerability Type: Sensitive credential exposure through URL query parameters
Risk Level: Medium

Complete Code Snippets

Representative token construction in src/api/search.js:59-62:

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

Request construction in src/utils/request.js:94-139:

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);
}

async function getJson(path, params) {
  if (!path || typeof path !== "string") {
    throw new SkillError("PATH_INVALID", "path 必须是非空字符串");
  }
  if (!params || typeof params !== "object") {
    throw new SkillError("PARAM_INVALID", "params 必须是对象");
  }
  params._ = Date.now();

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

  return await request(options);
}

...[truncated 2300 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove the token from all query-parameter objects.
  2. Send authentication through a dedicated header, preferably:
    js
    headers: {
      Authorization: `Bearer ${token}`,
      "Content-Type": "application/json",
      "Accept-Encoding": "identity",
    }
    
  3. Refactor getJson and postJson to accept authentication separately from ordinary request parameters, preventing accidental URL serialization.
  4. Configure servers, proxies, gateways, and monitoring systems to redact authorization headers and other secret-bearing fields.
  5. Review historical access logs, diagnostics, and backups for exposed tokens. Restrict access to those records and delete them according to the applicable retention policy.
  6. Rotate all tokens that have previously been transmitted through query strings.
  7. Add tests that inspect constructed request paths and fail if keys such as token, secret, api_key, or authorization appear in the URL.
  8. Use short-lived, revocable, least-privilege tokens and enforce server-side rate and quota controls to reduce replay impact.
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 (38)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill declares content-analysis functionality but also states that it automatically archives logs to a local logs/ directory with filenames derived from timestamps, keywords, and parameters. Undeclared filesystem writes can create data-retention and privacy risk, especially if search terms, account URLs, or comments contain sensitive business research data.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill declares content-analysis functionality but also states that it automatically archives logs to a local logs/ directory with filenames derived from timestamps, keywords, and parameters. Undeclared filesystem writes can create data-retention and privacy risk, especially if search terms, account URLs, or comments contain sensitive business research data.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill declares content-analysis functionality but also states that it automatically archives logs to a local logs/ directory with filenames derived from timestamps, keywords, and parameters. Undeclared filesystem writes can create data-retention and privacy risk, especially if search terms, account URLs, or comments contain sensitive business research data.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill declares content-analysis functionality but also states that it automatically archives logs to a local logs/ directory with filenames derived from timestamps, keywords, and parameters. Undeclared filesystem writes can create data-retention and privacy risk, especially if search terms, account URLs, or comments contain sensitive business research data.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding

The skill requires access to the environment variable GUAIKEI_API_TOKEN but does not explicitly declare tool scope or permissions. This weakens least-privilege guarantees and can cause the runtime to expose more capability than is documented, making review and sandboxing harder.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill says it should be used even when the user did not mention Douyin, for broad requests like competitor analysis or 'what is trending.' That overly broad implicit trigger can cause unintended activation on generic business-analysis prompts, leading to unnecessary external data access, token use, and collection of platform-specific data outside user intent.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The implicit trigger examples are generic enough to match many unrelated requests, such as broad trend analysis or content ideation tasks. In an agent system, this can route prompts to a data-collection skill without clear consent or relevance, increasing privacy, compliance, and least-surprise risks.

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 describes video_url as both playback and download addresses, which conflicts with the skill metadata stating it does not handle video downloading. This mismatch can enable downstream agents or integrators to expose or rely on download functionality that the skill claims to prohibit, increasing the risk of policy bypass, copyright/compliance issues, and unintended data handling.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The manifest explicitly states the skill does not process video publishing or downloading. However, the schema describes play_addr as both a playback address and a '视频下载地址', which indicates the skill exposes download-capable output as part of its search response.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The README states that scraped Douyin data is automatically exported to JSON logs, but it does not prominently warn that those files may contain personal data, comment content, account identifiers, or other sensitive business research material. This creates a realistic risk of unintended retention, local exposure, accidental sharing, or secondary misuse of collected data, especially because the skill is designed for bulk scraping and analysis.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The CLI writes fetched comment data to a local JSON file automatically after successful execution, but this file contains user-generated content and potentially sensitive research data with no consent prompt, opt-in flag, or visibility control in this file. In shared workstations, CI runners, or multi-user environments, this creates an unnecessary data-at-rest exposure and may leak collected comment datasets beyond the user's immediate session.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The CLI persists fetched Douyin post data to a local JSON file by default, but there is no visible user consent, warning, or opt-in control before writing the data to disk. In this skill’s context, the fetched results may include account content and metadata that can be sensitive in enterprise or shared environments, creating an avoidable confidentiality and data-retention risk if local files are exposed, synced, or left behind.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The CLI persists full search output to a local JSON file containing user-supplied keywords and returned Douyin data without an explicit opt-in or prominent disclosure. In shared environments, CI runners, or multi-user systems, this can unintentionally retain sensitive research terms or collected data longer than the user expects, increasing privacy and data-handling risk.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file contains user-facing error messages in Chinese only, and later also emits a success message in Chinese. For a general utility module, this hard-codes a specific language without offering user opt-in or documenting a locale-specific scope, which matches the natural-language policy violation criteria.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The success and failure messages are emitted only in Chinese, which enforces a specific language for runtime interaction. The file does not indicate that the skill is region-specific or that users can choose their preferred language.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The AuthError string is hard-coded in Chinese and directs users to a specific WeChat contact, which imposes a language/locale expectation in natural-language output. This can violate language/locale policy when the skill does not offer users a choice or document that it is intentionally region-specific.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This JavaScript file contains user-facing natural-language strings exclusively in Chinese, including validation errors and function documentation. Because the file does not offer a language/locale option or document that the skill is intentionally region-specific, it may violate the language/locale policy requiring user opt-in or clear justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

This JSON schema contains all human-facing title and description fields in Chinese only, such as the title and parameter descriptions. Under the policy for natural-language violations, a fixed language choice without user opt-in can be considered a locale/language policy issue when no alternative or opt-in is provided.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The schema title and description are written only in Chinese, which imposes a specific language in user-facing natural-language metadata. The policy allows locale constraints only when they are explicitly documented and justified or when users are given a language choice, which is not present here.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The schema title and description are written only in Chinese, which imposes a specific language in user-facing metadata. Under the policy, language constraints should either be optional for the user or clearly documented as region-specific and justified; this file provides no such opt-in or justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

The schema title and field descriptions are written entirely in Chinese, which imposes a specific language in user-facing metadata. There is no indication that the skill is China-specific or that users can opt into another language, so this appears to violate the language/locale-choice policy.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The schema title and description are written only in Chinese, which imposes a specific language in natural-language metadata without indicating user choice or a justified locale constraint. Under the policy, language-specific instructions or metadata should either offer choice or clearly document why the locale is required.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The title and field descriptions are written entirely in Chinese, which can amount to a language/locale policy issue if the skill is expected to operate in a general multilingual environment. The file does not indicate that Chinese is an intentional, region-specific constraint or that users can opt into another language.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

The schema title and description are written only in Chinese, and all field descriptions in the file follow the same fixed locale. For a general-purpose skill asset, this indicates a language constraint without any visible user opt-in or documentation that the skill is region-specific.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The file tells users to set GUAIKEI_API_TOKEN before running the skill, which involves handling a credential. Although a later FAQ briefly says not to leak the token, the main setup instructions lack a clear warning that the token is sensitive and should not be committed, shared, or logged.

Content

No source excerpt is available for this finding.