Back to skill

Security audit

guaikei-douyin-json-comments-export

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its Douyin public-data purpose, but its runtime code contradicts its own neutral authentication-error policy and handles the API token in a riskier URL-query form.

Review before installing. The skill is not showing destructive behavior or host persistence, but it will send your Guaikei token and Douyin query inputs to www.guaikei.com, saves result exports locally, and currently has misleading authentication-error behavior compared with its own policy. Use a limited token if possible, avoid sensitive search terms, and delete exported logs when no longer needed.

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

Runtime Authentication Errors Inject Promotional Contact Information Contrary to the Declared Skill Policy

Content
View full analysis

Vulnerability Details

File Location: src/utils/token.js:21-31, src/utils/request.js:49-57, and src/douyin/search-cli.js:164-190
Vulnerability Type: Runtime instruction and output-policy hijacking
Risk Level: Medium

Vulnerable Code

src/utils/token.js:21-31:

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

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

src/utils/request.js:49-57:

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

src/douyin/search-cli.js:164-190:

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

SKILL.md explicitly states that missing or invalid tokens must produce a neutral error and prohibits runtime website links, contact information, and marketing language. The executable implementation contradicts that policy.

When a token is locally missing o ...[truncated 1876 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove all websites, telephone numbers, social-media contacts, and promotional wording from runtime code.

  2. Replace both authentication paths with one fixed neutral message, such as:

    js
    const AUTH_MESSAGE =
      "GUAIKEI_API_TOKEN is missing, malformed, expired, or unauthorized. Check the configured environment variable.";
    
  3. Return a stable machine-readable error code such as AUTH_ERROR without embedding onboarding or sales instructions.

  4. Keep support and token-acquisition information exclusively in documentation that users choose to open.

  5. Do not propagate raw remote authentication messages into user-facing JSON. Map HTTP 401 and 403 responses to the fixed local error.

  6. Add automated tests that invoke the missing-token and rejected-token paths and assert that stdout and stderr contain no domain names, contact numbers, social-media identifiers, or marketing phrases.

  7. Review all CLI handlers to ensure that they apply the same sanitized error mapping.

T09 · Insecure Skill Coding Practices

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

API Token Is Systemically Transmitted in URL Query Strings

Content
View full analysis

Vulnerability Details

File Location: src/utils/request.js:91-107 and src/utils/request.js:126-136; callers include src/api/search.js:58-75, 103-119, src/api/comment.js:37-51, 66-78, src/api/post.js:22-34, 49-60, and src/api/hot.js:19-22
Vulnerability Type: Sensitive credential exposure through request URLs
Risk Level: Medium

Vulnerable Code

src/utils/request.js:91-107:

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 = {

src/utils/request.js:126-136:

js
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 = {

Representative callers in src/api/search.js:58-75 and src/api/search.js:103-119:

js
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,
  "创建任务",
);
js
const params = {
  _: Date.now(),
  token: token,
  keyword: keyword,
  sort_typ
...[truncated 2987 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove token from every query-parameter object.

  2. Send the credential in an HTTP authorization header:

    js
    headers: {
      Authorization: `Bearer ${token}`,
      "Content-Type": "application/json",
      "Accept-Encoding": "identity",
      "Content-Length": Buffer.byteLength(jsonData),
    }
    
  3. Refactor postJson(), getJson(), and requestApi() so the token is passed separately from ordinary query parameters.

  4. Ensure authentication headers are redacted by server, proxy, tracing, and error-reporting configurations.

  5. Avoid transmitting search terms and Douyin URLs in GET query strings where practical. Use POST bodies when these values may be sensitive or excessively long.

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

  7. Review and sanitize server-side access logs, backups, observability data, and retained traces containing token=.

  8. Add tests that intercept outgoing request options and fail if URL paths contain token, api_key, or equivalent credential fields.

  9. Document the external data flow clearly: API tokens, search keywords, Douyin URLs, requested limits, and related parameters are sent to www.guaikei.com.

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 (38)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill states that logs are automatically written to a local logs/ directory, but that filesystem write behavior is not clearly surfaced in the high-level purpose. Hidden or under-declared disk writes matter because scraped data and operational metadata may be retained locally, creating privacy, retention, and accidental disclosure risks.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill states that logs are automatically written to a local logs/ directory, but that filesystem write behavior is not clearly surfaced in the high-level purpose. Hidden or under-declared disk writes matter because scraped data and operational metadata may be retained locally, creating privacy, retention, and accidental disclosure risks.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill states that logs are automatically written to a local logs/ directory, but that filesystem write behavior is not clearly surfaced in the high-level purpose. Hidden or under-declared disk writes matter because scraped data and operational metadata may be retained locally, creating privacy, retention, and accidental disclosure risks.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
83% confidence
Finding

The skill explicitly depends on the environment variable GUAIKEI_API_TOKEN but does not declare tool scope or permissions boundaries in the skill manifest. That creates an unnecessary capability gap: the skill can rely on ambient environment access without transparent declaration, which weakens reviewability and least-privilege enforcement.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The implicit trigger examples are broad enough to match ordinary research or analysis requests such as competitor research and trending-topic discovery. Over-broad activation can cause the agent to invoke data-collection behavior without sufficiently specific user intent, increasing the chance of unnecessary external queries, token use, or collection of third-party data.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This JSON schema includes user-facing natural-language titles and descriptions exclusively in Chinese, such as the title and field descriptions. Under the language/locale policy, forcing a specific language without opt-in or documented justification is a policy concern for any file type.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The README explains how to fetch public Douyin videos, author data, comments, and hot-list data, and later notes that output is saved under a local logs directory, but it does not prominently warn at the point of use that public account/video/comment data will be collected and exported to JSON files. This can lead users to unintentionally retain scraped personal or quasi-personal data locally, increasing privacy, compliance, and secondary disclosure risk if logs are shared, backed up, or committed to repositories.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The CLI writes fetched comment data to a local JSON file automatically after successful execution, but does not provide an explicit warning or require opt-in at the point of persistence. Even though the data is described as public Douyin comment data, local storage creates a secondary disclosure risk on shared machines, CI runners, or agent environments where output files may be retained, indexed, or exfiltrated later.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
81% confidence
Finding

The code reads process.env.GUAIKEI_API_TOKEN, which is access to sensitive credentials and falls within the rule's safety-critical operations for code files. In this file there is no nearby user-facing disclosure, prompt, or explanatory comment indicating that the skill will read an environment token for authentication.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The manifest describes capabilities around searching, scraping, analyzing, and querying Douyin public data, but does not mention persistent local export/storage behavior. This file not only fetches post data but also saves the full result set to disk via log.taskWrite, which is an additional operational behavior beyond simple retrieval and analysis.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The CLI silently persists retrieved results to a local JSON file without any user-facing notice or consent in this file. Even if the source data is public, silent local storage can create privacy, retention, and data-governance risks, especially when run in shared environments or automation pipelines where generated files may be overlooked and later exposed.

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 full search output to a local JSON log file using a filename derived from user-controlled input, but there is no clear user-facing notice or consent before data is stored. In a data-collection skill, this increases privacy and operational risk because query terms and returned public-data results may remain on disk longer than users expect and could be accessed by other local users, backup systems, or later processes.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

This file contains natural-language strings exclusively in Chinese in comments, thrown errors, and generated help text. That enforces a specific language experience for users and developers without any opt-in or justification, which matches the locale-policy violation criteria.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This code emits all visible error messages in Chinese, and later success/failure messages are also Chinese-only. That creates a natural-language locale constraint without offering a user language choice or documenting that the skill is intentionally region-specific.

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 message is presented only in Chinese and includes remediation text intended for users. This forces a specific language/locale without opt-in or documented justification, 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
94% confidence
Finding

The file contains user-facing status and warning messages only in Chinese, including the warning about token configuration and the informational message about using a private token. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is explicitly documented and 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
91% confidence
Finding

This JavaScript file contains natural-language comments and error/output strings exclusively in Chinese, including validation errors and formatted result messages. Under the policy rule for language/locale, this constitutes a forced language experience unless the skill explicitly offers user opt-in or documents that it is intentionally region-specific.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The environment section states "纯中文界面", which indicates a fixed language/locale requirement. Under the policy, forcing a specific language without user opt-in or a clearly justified documented regional constraint is a natural-language policy issue.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

This JSON schema is a manifest-type file, so natural-language policy checks apply. The title and descriptions at L04-L05, L12, and L16 force a specific language presentation without any user opt-in or justification that the skill is intentionally Chinese-only.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

This JSON schema contains user-facing natural-language fields such as the title and descriptions exclusively in Chinese. Under the stated policy, forcing a specific language without opt-in is a locale/language policy violation unless the constraint is explicitly documented and justified, 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
91% confidence
Finding

This JSON schema includes human-readable title and description text only in Chinese, which imposes a specific language on users of the skill metadata. The file does not indicate that the schema is intentionally China-specific or provide any alternative language or opt-in, so it may violate language/locale policy expectations.

Content

No source excerpt is available for this finding.

Vague Triggers

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

This manifest-style JSON describes command-line input for fetching a creator's works, but the description and parameter text do not state any explicit trigger phrases, scope limits, or negative examples. In a skill ecosystem, such broad natural-language descriptions can contribute to unintended invocation because they do not clarify when the skill should or should not be used.

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 only Chinese natural-language titles and descriptions for the API output schema, which can amount to an implicit language requirement for users or downstream tooling consuming the skill documentation. There is no accompanying indication that Chinese is optional, configurable, or justified as a region-specific constraint.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

This JSON manifest contains human-readable title and description fields only in Chinese, which effectively forces a specific language for users or downstream tools consuming the schema metadata. The policy allows locale constraints only when documented and justified or when users are given a language choice, neither of which is present here.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

This markdown file presents all instructions, parameter descriptions, and examples only in Chinese. Under the policy, forcing a specific language without user opt-in can be a natural-language policy violation unless the locale constraint is explicitly documented and justified.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.