Back to skill

Security audit

guaikei-douyin-authors-for-benchmarking

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent Douyin public-data CLI skill, with the main caveats that it uses a Guaikei API token and saves fetched results locally.

Install only if you are comfortable sending Douyin queries, URLs or IDs, and your GUAIKEI_API_TOKEN to Guaikei. Treat generated logs as retained datasets: review or delete them when finished, and avoid running the skill in shared directories if comments, creator identifiers, or research topics are sensitive.

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

API Credential Exposed in URL Query Parameters

Content
View full analysis

Vulnerability Details

File Location: src/utils/request.js:122-139; credential parameters originate from src/api/search.js:104-119, src/api/post.js:50-59, src/api/comment.js:67-77, and src/api/hot.js:19-22
Vulnerability Type: T09: Insecure Skill Coding Practices
Risk Level: Medium

Evidence

javascript
async function getJson(path, params) {
  if (!path || typeof path !== "string") {
    throw new SkillError("PATH_INVALID", "path must be a non-empty string");
  }
  if (!params || typeof params !== "object") {
    throw new SkillError("PARAM_INVALID", "params must be an object");
  }
  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);
}

The API modules include the secret token in the parameter object passed to this function. For example:

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,
  "Query task",
);

Technical Analysis

getJson() serializes every property in params into the request URL. Because the API modules place GUAIKEI_API_TOKEN in that object, requests are sent in the form:

text
/api/douyin/...?...&token=SECRET

HTTPS protects the request target while it is transmitted over the network, but it does not prevent the URL from being recorded at either endpoint. Full request URLs are frequently retained by reverse proxies, load balancers, web-server access logs, application-performance monitoring systems, debuggin ...[truncated 1442 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove token from every URL parameter object.

  2. Send the credential through a standard authorization header:

    javascript
    const options = {
      host: constants.BASE_URL,
      path: fullPath,
      method: "GET",
      headers: {
        Authorization: `Bearer ${token}`,
        "Accept-Encoding": "identity",
      },
    };
    
  3. Refactor the request interface so authentication is passed separately from ordinary query parameters, preventing accidental serialization.

  4. Configure proxies, servers, and monitoring systems to redact sensitive query parameters while legacy clients remain supported.

  5. Ensure errors and retry logs never include the request options, complete URL, authorization header, or token.

  6. Rotate existing tokens if infrastructure logs may already contain request URLs.

  7. Add automated tests asserting that generated request paths never contain token=.

T09 · Insecure Skill Coding Practices

Note
Location
src/utils/log.js:25
Finding

Automatic Persistence of Retrieved Data with Default File Permissions

Content
View full analysis

Vulnerability Details

File Location: src/utils/log.js:25-35; invoked by src/douyin/search-cli.js:258-261, src/douyin/post-cli.js:160, and src/douyin/comment-cli.js:159
Vulnerability Type: T09: Insecure Skill Coding Practices
Risk Level: Low

Evidence

The output path is fixed under the project directory, but the file is created without an explicit restrictive permission mode:

javascript
const outputFilename = path.join(
  path.dirname(__filename),
  "..",
  "..",
  "logs",
  safeFilename,
);

try {
  await fs.promises.mkdir(path.dirname(outputFilename), { recursive: true });
  await fs.promises.writeFile(outputFilename, content);

Successful search results are printed and then automatically persisted:

javascript
console.log(JSON.stringify(finalOutput, null, 2));
utils.printSuccess(
  `Search task completed with ${finalOutput.results.length} results`,
);

await log.taskWrite(
  `${startTime}_${keyword}_${sort}_${time}_${duration}_${content}_search.json`,
  JSON.stringify(finalOutput, null, 2),
);

Equivalent persistence occurs for successful post and comment operations.

Technical Analysis

Successful API responses are written automatically to logs/ in addition to being returned through standard output. The stored JSON can contain search interests, Douyin identifiers, author information, public comments, request metadata, and complete retrieved datasets.

fs.promises.writeFile() is called without an explicit mode, so effective permissions depend on the operating system and process umask. In an environment with a permissive umask or shared project directory, other local users or services may be able to read the generated files.

Search keywords are also incorporated into filenames. Although taskWrite() sanitizes separators, traversal sequences, and reserved filename characters, the resulting filename can still disclose the user's research topic ...[truncated 1500 chars]

Remediation
View remediation

Remediation Suggestions

  1. Make local persistence opt-in through an explicit option such as --output or --save.

  2. Clearly document that successful results may be stored locally, including the location and retention policy.

  3. Create directories and files with restrictive permissions:

    javascript
    await fs.promises.mkdir(path.dirname(outputFilename), {
      recursive: true,
      mode: 0o700,
    });
    
    await fs.promises.writeFile(outputFilename, content, {
      mode: 0o600,
      flag: "wx",
    });
    
  4. Use opaque generated filenames instead of embedding search keywords or target identifiers.

  5. Provide configurable retention and secure deletion controls.

  6. Prevent generated logs from being included in source-control commits, build artifacts, support bundles, or backups unless explicitly requested.

  7. Warn users when execution occurs in a directory whose permissions permit access by other accounts.

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
99% confidence
Finding

代码内容仅为通用参数解析器(args.js),属于底层 CLI 辅助组件。它不包含任何与抖音相关的搜索、热榜、评论、作品抓取、数据分析、舆情监控或热点追踪逻辑,也没有网络请求、API 调用、数据抓取或数据处理行为。根据评估标准,虽然这可能是某个更大技能中的支持性实现细节,但就该“代码块实际行为”而言,其主要功能与声明的技能用途明显不一致,因此应判定为描述与行为不匹配。

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding

The skill requires access to the environment variable GUAIKEI_API_TOKEN but does not declare an explicit tool scope such as permissions or allowed-tools. That makes the privilege boundary implicit rather than enforced, increasing the chance the runtime grants broader access than necessary or that reviewers cannot easily verify what sensitive resources the skill needs.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The natural-language trigger examples are broad enough that an orchestrator or agent could invoke the skill on loosely related requests without strong user intent confirmation. In a skill that sends user queries to a third-party API, unintended invocation can cause unnecessary data disclosure, token usage, and confusing or privacy-impacting external calls.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The README explicitly states that search, post, and comment results are automatically saved as JSON logs in a local logs directory, but it does not clearly warn users that scraped public data, including comment content, will be persisted to disk. This creates a data handling and privacy risk because operators may assume the tool is transient while it is actually retaining potentially sensitive scraped datasets that can later be exposed, copied, or mishandled.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

This markdown file documents commands that retrieve a creator's published works and comment data, which can affect privacy expectations and involve collecting third-party platform data. The description provides syntax and examples but includes no warning or disclosure about responsible use, privacy considerations, or compliance constraints.

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 Douyin comment data to a local JSON file automatically after completing the request, with no opt-in, warning, or way to disable persistence in this file. Comment data can contain personal or sensitive user-generated content, so silent local retention increases privacy, compliance, and accidental disclosure risk, especially on shared systems or in automated pipelines.

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’s user-facing natural-language strings, including status and error messages, are consistently written in Chinese. This can violate a language/locale policy when the skill does not provide user opt-in, fallback, or documentation that it is intentionally limited to Chinese-speaking users.

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 the full fetched results to a local JSON file using a filename derived from user input, but this behavior is not disclosed to the user in the command help or runtime prompts. Because the tool is explicitly used for collecting Douyin author/content data, the output may contain scraped public data, operational research, or identifiers that users may not expect to be persistently stored on disk, increasing privacy and data-retention risk.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The manifest describes a tool for retrieving and analyzing public Douyin data such as search results, rankings, comments, and author works. This file creates directories and writes arbitrary content into a local logs folder, which is not part of the user-facing data acquisition/analysis scope described in the manifest.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The authentication error string is hard-coded in Chinese and includes no mechanism for selecting language or honoring user locale. This creates a natural-language policy issue because the skill enforces a specific language without user opt-in or documented locale justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The user-facing warning and status strings are entirely in Chinese, and the file provides no indication that language selection is optional or that the skill is intentionally limited to a Chinese-speaking context. This can violate language/locale policy when users are not given an explicit choice or opt-in.

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's user-facing error messages and comments are entirely in Chinese, and the keyword cleaning logic explicitly permits Chinese characters while shaping accepted input around that locale. This imposes a language/locale constraint in natural-language behavior without offering a user choice or documenting that the skill is region-specific.

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 contains user-facing natural-language strings entirely in Chinese, including the title and parameter descriptions. Because the file does not indicate that the skill is region-specific or provide any language choice, it may impose a language/locale constraint without user opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

This JSON schema uses Chinese-only natural-language title and description text, which can impose a specific language on downstream users or tools consuming the schema. The file does not indicate that the schema is intentionally region-specific or provide any language choice, so it may violate a language/locale policy requiring opt-in or justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

This JSON schema uses Chinese natural-language strings for the title and field descriptions throughout the file, but it does not document that the skill is Chinese-only or offer any language/locale choice. That can violate the language/locale policy when users are not given an explicit opt-in or justification for the locale constraint.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

Natural-language policy checks apply to all file types. The title and description force a Chinese-language interface for this skill artifact, and there is no indication that the skill is region-specific or that users can opt into another language.

Content

No source excerpt is available for this finding.

Vague Triggers

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

This is a manifest/schema file, so vague-trigger checks apply. The description allows two different identifier types in one field but does not specify accepted patterns, examples, or exclusion conditions, which makes activation/input matching broader and less predictable.

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 is a manifest/config-style file, so SQP-3 applies. The human-readable schema title and description are written only in Chinese, which can constitute a language/locale policy issue when no opt-in, alternative locale, or justification is provided for restricting the skill's metadata to a single language.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The schema title and description are written entirely in Chinese, and the field descriptions throughout the file follow the same pattern. For an all-file-types language policy check, this can be a natural-language locale constraint because the file presents a single enforced language with no opt-in, alternative locale, or documented region-specific justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

This JSON schema uses Chinese-only natural-language titles and descriptions throughout, such as the title and property descriptions, with no indication that the skill is intentionally region-specific or that users can opt into this locale. Under the policy rule for language/locale, forcing a specific language without user choice can be 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
83% confidence
Finding

The file presents all operational guidance and command-mapping instructions exclusively in Chinese, which can impose a language constraint on users and downstream agents. Under the policy, forcing a specific language without user opt-in or a documented justification is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

All headings, parameter descriptions, and examples are presented in Chinese, which effectively forces a specific language for users of this skill documentation. The file does not indicate that Chinese is optional, nor does it justify the locale restriction as 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 function sends the provided video URL and authentication token to an external API via requestApi, which is a data-transmitting network operation. While the code has developer-facing comments, there is no visible confirmation prompt, user-facing log/print, or explicit warning in this file about transmitting that data.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

This function performs a GET request that includes the token and video URL in request parameters, sending user-supplied and credential-like data to an external endpoint. The file contains no user-visible notice, prompt, or warning explaining that this transmission occurs.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

The natural-language content in comments and JSDoc is entirely Chinese and presents the skill interface in a single language, with no indication that language choice is optional or that the module is intentionally region-specific. Under the stated policy, forcing a specific language without user opt-in can be a locale-policy violation.

Content

No source excerpt is available for this finding.