Back to skill

Security audit

dou-yin-data-insight

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to perform the advertised Douyin research tasks, but it handles credentials and saved result data in ways users should review first.

Review before installing if your Douyin research targets, comments, account URLs, or API token are sensitive. Prefer a version that sends the token in an Authorization header, lets you disable or choose output logging, and documents retention and privacy expectations clearly.

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

API Credential Transmitted in URL Query Strings

Content
View full analysis

Vulnerability Details

File Location: src/api/search.js:59-62, 104-107; src/api/post.js:23-25, 50-54; src/api/comment.js:38-40, 67-71; src/api/hot.js:19-21; src/utils/request.js:94-110, 123-137
Vulnerability Type: API credential exposure through URL query parameters
Risk Level: Medium

Vulnerable Code

The API modules insert the token into the query-parameter object:

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

Search-result polling repeats the token in the query string:

js
const params = {
  _: Date.now(),
  token: token,
  keyword: keyword,
  sort_type: sort,
  publish_time: time,
  filter_duration: duration,
  content_type: content,
  limit: limit,
};

The request utility serializes the complete parameter object 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);
}

The same behavior occurs for GET requests:

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("
...[truncated 2065 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove token from every query-parameter object in src/api/search.js, src/api/post.js, src/api/comment.js, and src/api/hot.js.

  2. Pass the credential in an HTTP authorization header, such as:

    js
    headers: {
      Authorization: `Bearer ${token}`,
      "Content-Type": "application/json",
      "Accept-Encoding": "identity",
    }
    
  3. Refactor getJson and postJson to accept authentication separately from ordinary query parameters.

  4. Ensure request and error logging redacts Authorization, tokens, and other credentials.

  5. Review server, reverse-proxy, and observability logs for previously retained token-bearing URLs.

  6. Rotate tokens that may already have been exposed through URL logging.

  7. Configure short token lifetimes, revocation support, quota limits, and narrowly scoped permissions where supported.

T09 · Insecure Skill Coding Practices

Note
Location
src/douyin/search-cli.js:258
Finding

Automatic Plaintext Persistence of Complete Retrieved Datasets

Content
View full analysis

Vulnerability Details

File Location: src/douyin/search-cli.js:258-261; src/douyin/comment-cli.js:159-162; src/douyin/post-cli.js:160; src/utils/log.js:5-40
Vulnerability Type: Insecure local storage and unnecessary data retention
Risk Level: Low

Vulnerable Code

Successful search results are automatically passed to the file writer:

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

Comment results are persisted in the same manner:

js
await log.taskWrite(
  `${startTime}_${url}_comment.json`,
  JSON.stringify(finalOutput, null, 2),
);

The file utility creates the log directory and writes the full content using default process permissions:

js
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);
  utils.printSuccess(`  → 已保存到 ${outputFilename}`);
} catch (error) {
  utils.printError(`日志写入失败: ${error.message}`);
}

Technical Analysis

Successful search, post, and comment operations persist the complete JSON result automatically. The retained data may include search terms, requested URLs or identifiers, content details, author information, comments, timestamps, and metadata.

The files are neither encrypted nor created with an explicitly restrictive mode. Their effective permissions therefore depend on the process umask and surrounding filesystem configuration. No retention period, automatic cleanup, redaction mechanism, or command-line opt-out is implemented.

The behavior is disclosed in readme.md:101-105, but it is not clearly stated in the primary execution and output contract in SKILL.md:147-157, which emphasizes JSON output through stdout ...[truncated 1359 chars]

Remediation
View remediation

Remediation Suggestions

  1. Make disk persistence opt-in through an explicit option such as --output <path> or --save.

  2. Do not create result files when the caller only requests stdout output.

  3. When persistence is enabled, create files with restrictive permissions:

    js
    await fs.promises.writeFile(outputFilename, content, {
      encoding: "utf8",
      mode: 0o600,
      flag: "wx",
    });
    
  4. Create the containing directory with restrictive permissions, such as mode 0700, where supported.

  5. Add configurable retention and cleanup behavior for generated files.

  6. Avoid including raw search keywords or identifiers in filenames; use a random identifier or a non-reversible digest instead.

  7. Document automatic or optional persistence prominently in SKILL.md, including the destination, stored fields, permissions, and retention behavior.

  8. Add logs/ to .gitignore to reduce accidental repository commits.

  9. Consider redacting unnecessary identifiers and metadata before storing results.

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

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

Undeclared outbound requests to a remote service using a bearer token are security-relevant because they create data egress risk and third-party trust dependencies. In this skill’s context, user-provided keywords, URLs, IDs, and retrieved content are sent to guaikei.com, so incomplete disclosure or missing network/tool scoping can lead operators to expose business research data or regulated content unintentionally.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

Undeclared outbound requests to a remote service using a bearer token are security-relevant because they create data egress risk and third-party trust dependencies. In this skill’s context, user-provided keywords, URLs, IDs, and retrieved content are sent to guaikei.com, so incomplete disclosure or missing network/tool scoping can lead operators to expose business research data or regulated content unintentionally.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

Undeclared outbound requests to a remote service using a bearer token are security-relevant because they create data egress risk and third-party trust dependencies. In this skill’s context, user-provided keywords, URLs, IDs, and retrieved content are sent to guaikei.com, so incomplete disclosure or missing network/tool scoping can lead operators to expose business research data or regulated content unintentionally.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

Undeclared outbound requests to a remote service using a bearer token are security-relevant because they create data egress risk and third-party trust dependencies. In this skill’s context, user-provided keywords, URLs, IDs, and retrieved content are sent to guaikei.com, so incomplete disclosure or missing network/tool scoping can lead operators to expose business research data or regulated content unintentionally.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

Undeclared outbound requests to a remote service using a bearer token are security-relevant because they create data egress risk and third-party trust dependencies. In this skill’s context, user-provided keywords, URLs, IDs, and retrieved content are sent to guaikei.com, so incomplete disclosure or missing network/tool scoping can lead operators to expose business research data or regulated content unintentionally.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

Undeclared outbound requests to a remote service using a bearer token are security-relevant because they create data egress risk and third-party trust dependencies. In this skill’s context, user-provided keywords, URLs, IDs, and retrieved content are sent to guaikei.com, so incomplete disclosure or missing network/tool scoping can lead operators to expose business research data or regulated content unintentionally.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

Undeclared outbound requests to a remote service using a bearer token are security-relevant because they create data egress risk and third-party trust dependencies. In this skill’s context, user-provided keywords, URLs, IDs, and retrieved content are sent to guaikei.com, so incomplete disclosure or missing network/tool scoping can lead operators to expose business research data or regulated content unintentionally.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

Undeclared outbound requests to a remote service using a bearer token are security-relevant because they create data egress risk and third-party trust dependencies. In this skill’s context, user-provided keywords, URLs, IDs, and retrieved content are sent to guaikei.com, so incomplete disclosure or missing network/tool scoping can lead operators to expose business research data or regulated content unintentionally.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

Undeclared outbound requests to a remote service using a bearer token are security-relevant because they create data egress risk and third-party trust dependencies. In this skill’s context, user-provided keywords, URLs, IDs, and retrieved content are sent to guaikei.com, so incomplete disclosure or missing network/tool scoping can lead operators to expose business research data or regulated content unintentionally.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

Undeclared outbound requests to a remote service using a bearer token are security-relevant because they create data egress risk and third-party trust dependencies. In this skill’s context, user-provided keywords, URLs, IDs, and retrieved content are sent to guaikei.com, so incomplete disclosure or missing network/tool scoping can lead operators to expose business research data or regulated content unintentionally.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

Undeclared outbound requests to a remote service using a bearer token are security-relevant because they create data egress risk and third-party trust dependencies. In this skill’s context, user-provided keywords, URLs, IDs, and retrieved content are sent to guaikei.com, so incomplete disclosure or missing network/tool scoping can lead operators to expose business research data or regulated content unintentionally.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

Undeclared outbound requests to a remote service using a bearer token are security-relevant because they create data egress risk and third-party trust dependencies. In this skill’s context, user-provided keywords, URLs, IDs, and retrieved content are sent to guaikei.com, so incomplete disclosure or missing network/tool scoping can lead operators to expose business research data or regulated content unintentionally.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill declares access to the environment via GUAIKEI_API_TOKEN and explicitly relies on that secret for external API calls, but it does not define any permissions or allowed-tools scope. This weakens least-privilege controls and makes it harder for a host agent to restrict or audit secret and tool access before execution.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

This JSON schema contains multiple user-facing natural-language fields such as title and description that are exclusively in Chinese. That imposes a specific language on users without opt-in or justification, which matches the policy category for language or locale violations.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This JSON schema contains user-facing natural-language fields such as title and descriptions exclusively in Chinese, but it does not indicate that the skill is China-specific or provide any user opt-in for language/locale. Under the stated policy, forcing a specific language without choice or justification is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The manifest context limits the skill to 抖音竞品研究、同赛道观察、内容角度/策略对比、品牌内容调研. Line L04 describes the package as supporting 实时热榜获取 and 热点监控/流量追踪, which expands the behavior toward trend monitoring and hot-list intelligence rather than just competitor/content analysis.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The package scripts expose a dedicated comment capability via src/douyin/comment-cli.js, but the manifest description mentions competitor research, content comparison, strategy comparison, and brand content investigation—not comment collection or comment analysis. Comment scraping is a materially different data collection capability and is not clearly justified by the stated scope.

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 automatic export of collected video, author, comment, and hot-list data into local logs, but does not clearly warn that comments, account identifiers, and other public-profile data may still constitute personal or sensitive data. This can lead operators to retain scraped data insecurely, increasing privacy, compliance, and secondary disclosure risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The README requires a third-party API token but does not clearly disclose that user queries, target account URLs, video URLs, and related metadata are sent to an external service. Users may unknowingly transmit sensitive research targets or monitoring interests off-platform, creating confidentiality and compliance exposure.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The README maps very common natural-language phrases such as '搜索/搜一下/找' and similar everyday wording directly to command execution. Broad triggers increase the chance that unrelated user requests are misrouted into scraping actions, causing unintended collection of Douyin data or execution of the wrong CLI workflow.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The intent-priority rules rely on ambiguous, overlapping keywords like '热点', '搜索', '视频', '主页', and '评论' to select different tools. In an agent setting, such loose routing can be exploited or accidentally triggered to invoke scraping functions the user did not clearly request, leading to unauthorized or overbroad data retrieval.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The changelog content is written in Chinese throughout, which can functionally force a specific language for users reading skill documentation. The file does not indicate that the skill is region-specific or provide any language/locale opt-in or alternative.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The changelog advertises capabilities beyond the stated skill scope, including general search, trending-topic queries, bulk collection of a creator’s published works, and comment scraping/analysis. This scope expansion increases the risk of undisclosed data collection, competitive intelligence abuse, and use of the skill for broad surveillance or scraping workflows that users and reviewers would not expect from the metadata alone.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This code file contains natural-language documentation and operation labels exclusively in Chinese, including the module description and task labels such as "创建任务" and "查询任务". Under the policy, forcing a specific language without user opt-in or documented justification is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The manifest describes a skill for Douyin competitive research, track observation, content-angle comparison, strategy comparison, and brand content research. This CLI instead retrieves raw comment data for a specific post and writes the full results to a local JSON file, which is a narrower data-extraction/logging behavior rather than an analysis or comparison capability described in the manifest.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.