Back to skill

Security audit

guaikei-douyin-data-feed

Security checks for vulnerabilities and agentic risk

Overview

The skill appears purpose-built for Douyin public-data retrieval, but it has review-worthy issues around broad activation, token handling, automatic local logs, and runtime messages that contradict its own security claims.

Install only if you are comfortable sending Douyin URLs, keywords, limits, and your GUAIKEI_API_TOKEN to the Guaikei API, and with retrieved public data being saved locally in logs. Review token scope, rotate tokens if needed, clear logs on shared machines, and avoid letting ambiguous prompts trigger this skill without confirming the user wants Douyin data.

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

T09 · Insecure Skill Coding Practices

Error
Location
src/api/search.js:58
Finding

Authentication Token Exposed in URL Query Strings

Content
View full analysis

Vulnerability Details

File Location: src/api/search.js:58-77, with equivalent behavior in src/api/comment.js:37-52, src/api/post.js:22-35, and src/api/hot.js:16-22
Vulnerability Type: Sensitive credential exposure through URL query parameters
Risk Level: High

Vulnerable Code

javascript
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 these parameters directly into the request URL:

javascript
const fullPath = `${path}?${querystring.stringify(params)}`;
const options = {
  host: constants.BASE_URL,
  path: fullPath,
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Accept-Encoding": "identity",
    "Content-Length": Buffer.byteLength(jsonData),
  },
};

Query operations additionally place the token and user-supplied search details or Douyin URLs in GET query strings:

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

Technical Analysis

GUAIKEI_API_TOKEN is a bearer-like service credential, but the application transmits it as a token URL query parameter rather than in an authorization header. HTTPS protects the complete request in transit, but it does not prevent the URL from being recorded after TLS termination.

Query strings are commonly retai ...[truncated 2087 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove token from every query-parameter object.

  2. Send the credential through a request header, preferably:

    javascript
    headers: {
      Authorization: `Bearer ${token}`,
      "Content-Type": "application/json",
      "Accept-Encoding": "identity",
    }
    
  3. Update both GET and POST request helpers so authentication is handled centrally and cannot accidentally be serialized into a URL.

  4. Ensure server, CDN, WAF, proxy, and APM configurations redact Authorization, cookies, and any legacy token parameter.

  5. Avoid placing user search terms and submitted resource URLs in GET query strings when they can be sent in a POST body.

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

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

  8. Document the exact third-party data transmission, retention policy, and credential revocation procedure.

T01 · Skill Instruction Hijacking

Warning
Location
src/utils/token.js:23
Finding

Runtime Promotional Output Overrides the Declared Neutral Authentication-Failure Policy

Content
View full analysis

Vulnerability Details

File Location: src/utils/token.js:23-31 and src/utils/request.js:50-56
Vulnerability Type: Promotional output injection into agent-visible error handling
Risk Level: Medium

Vulnerable Code

When the token is absent or fails local format validation, the runtime prints a promotional acquisition channel:

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

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

When the remote service returns HTTP 401 or 403, the runtime embeds a phone/WeChat contact in the authentication error:

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

The CLI propagates error.message into machine-readable stdout, for example in src/douyin/search-cli.js:173-196:

javascript
} catch (error) {
  utils.printError(`搜索失败: ${error.message}`);
  const errorOutput = {
    status: "error",
    error_code: error.code || "UNKNOWN",
    message: error.message,
    // ...
  };
  const exitCode = error.name === "AuthError" ? 3 : 1;
  process.stdout.write(JSON.stringify(errorOutput, null, 2) + "\n", () =>
    process.exit(exitCode),
  );
}

Technical Analysis

SKILL.md explicitly states that an invalid token must produce only a neutral error and prohibits runtime output containing contact details, website links, marketing language, or payment guidance. The implementation violates that declared security boundary in two independent authentication-failure paths.

This behavior is particularly relevant in an agent skill because stderr and structured stdout can be consumed by an AI agent and ...[truncated 2377 chars]

Remediation
View remediation

Remediation Suggestions

  1. Replace both authentication-failure messages with a fixed neutral message, such as:

    javascript
    "GUAIKEI_API_TOKEN is missing or invalid; the skill has stopped."
    
  2. Remove all website addresses, phone numbers, social-media contacts, acquisition guidance, sales language, and payment guidance from runtime code.

  3. Keep optional support and enrollment information exclusively in user documentation.

  4. Map HTTP 401 and 403 to a stable error code such as AUTH_REQUIRED without propagating arbitrary remote or promotional text.

  5. Centralize authentication error construction so every CLI returns the same sanitized response.

  6. Add regression tests for missing, malformed, expired, and rejected tokens. Tests should assert that stdout and stderr contain no URLs, phone numbers, contact instructions, or marketing phrases.

  7. Configure agent integrations to treat tool errors as untrusted data and avoid automatically following URLs or contact instructions contained in tool output.

T09 · Insecure Skill Coding Practices

Warning
Location
src/config/constants.js:19
Finding

Query Operations Can Retry for Twenty Attempts Despite the Documented Three-Attempt Limit

Content
View full analysis

Vulnerability Details

File Location: src/config/constants.js:19-29 and src/utils/retry.js:12-30
Vulnerability Type: Excessive retry and resource-consumption behavior
Risk Level: Medium

Vulnerable Code

Query operations are configured for twenty attempts:

javascript
/**
 * 查询任务最大重试次数
 */
QUERY_MAX_ATTEMPTS: 20,

/**
 * 重试间隔时间 (毫秒)
 */
RETRY_INTERVAL: 2000,

The retry helper applies exponential backoff capped at sixty seconds:

javascript
async function withRetry(fn, maxAttempts, errorHandler) {
  let lastError;
  for (let attempt = 0; attempt < maxAttempts; attempt++) {
    try {
      return await fn(attempt);
    } catch (error) {
      lastError = error;
      if (error && error.noRetry) {
        throw error;
      }
      if (errorHandler) errorHandler(attempt, error);
      if (attempt < maxAttempts - 1) {
        const delay = Math.min(
          Math.pow(2, attempt) * constants.RETRY_INTERVAL,
          60000,
        );
        await new Promise((resolve) => setTimeout(resolve, delay));
      }
    }
  }
  throw lastError || new Error(`重试${maxAttempts}次后失败`);
}

Query API calls use this twenty-attempt setting, for example:

javascript
const response = await requestApi(
  "GET",
  "/api/douyin/general-search/info",
  params,
  null,
  constants.QUERY_MAX_ATTEMPTS,
  "查询任务",
);

Technical Analysis

The documentation states that network timeouts should stop after at most three attempts. The implementation instead permits twenty attempts for search, post, comment, and hot-list query operations.

Errors are retried unless they carry the custom noRetry property. Network failures, timeouts, connection resets, response parsing failures, and retryable API errors can therefore keep the process active through the full twenty-attempt loop.

With a 20-second request timeout and exponential delays capped at 6 ...[truncated 1825 chars]

Remediation
View remediation

Remediation Suggestions

  1. Enforce the documented maximum of three total attempts for network failures:

    javascript
    QUERY_MAX_ATTEMPTS: 3
    
  2. Distinguish task polling from failure retries. A pending task should use a bounded polling policy, while actual network or parsing errors should have a separate, lower retry limit.

  3. Add a maximum wall-clock deadline for the complete operation, not only a timeout for each request.

  4. Retry only explicitly transient conditions such as selected 5xx, 429, ETIMEDOUT, and connection-reset errors.

  5. Honor Retry-After for rate limiting and add randomized jitter to avoid synchronized retry storms.

  6. Do not retry authentication, validation, malformed-response, or deterministic application errors.

  7. Add cancellation support so the calling agent can abort abandoned tasks.

  8. Apply concurrency and per-user rate limits in the orchestration layer.

  9. Add tests that verify the actual attempt count and total deadline for each error class.

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

The skill states that logs are automatically saved to logs/ and static analysis indicates local filesystem writes, but the manifest does not prominently scope or constrain this write behavior. Undeclared file writes increase operational risk because they create persistent artifacts that may capture user queries, fetched content, or error details in ways reviewers and operators may not expect.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill states that logs are automatically saved to logs/ and static analysis indicates local filesystem writes, but the manifest does not prominently scope or constrain this write behavior. Undeclared file writes increase operational risk because they create persistent artifacts that may capture user queries, fetched content, or error details in ways reviewers and operators may not expect.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill states that logs are automatically saved to logs/ and static analysis indicates local filesystem writes, but the manifest does not prominently scope or constrain this write behavior. Undeclared file writes increase operational risk because they create persistent artifacts that may capture user queries, fetched content, or error details in ways reviewers and operators may not expect.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill states that logs are automatically saved to logs/ and static analysis indicates local filesystem writes, but the manifest does not prominently scope or constrain this write behavior. Undeclared file writes increase operational risk because they create persistent artifacts that may capture user queries, fetched content, or error details in ways reviewers and operators may not expect.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill states that logs are automatically saved to logs/ and static analysis indicates local filesystem writes, but the manifest does not prominently scope or constrain this write behavior. Undeclared file writes increase operational risk because they create persistent artifacts that may capture user queries, fetched content, or error details in ways reviewers and operators may not expect.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill states that logs are automatically saved to logs/ and static analysis indicates local filesystem writes, but the manifest does not prominently scope or constrain this write behavior. Undeclared file writes increase operational risk because they create persistent artifacts that may capture user queries, fetched content, or error details in ways reviewers and operators may not expect.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill states that logs are automatically saved to logs/ and static analysis indicates local filesystem writes, but the manifest does not prominently scope or constrain this write behavior. Undeclared file writes increase operational risk because they create persistent artifacts that may capture user queries, fetched content, or error details in ways reviewers and operators may not expect.

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 saved to logs/ and static analysis indicates local filesystem writes, but the manifest does not prominently scope or constrain this write behavior. Undeclared file writes increase operational risk because they create persistent artifacts that may capture user queries, fetched content, or error details in ways reviewers and operators may not expect.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The skill states that logs are automatically saved to logs/ and static analysis indicates local filesystem writes, but the manifest does not prominently scope or constrain this write behavior. Undeclared file writes increase operational risk because they create persistent artifacts that may capture user queries, fetched content, or error details in ways reviewers and operators may not expect.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill explicitly relies on an environment variable (GUAIKEI_API_TOKEN) but does not declare any tool scope or permissions boundary for environment access. This creates an unnecessary trust gap: a runtime may grant broader access than intended, and reviewers cannot easily verify least-privilege expectations from the manifest alone.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill says it should be used even when the user does not mention Douyin, which makes activation overly broad and increases the chance of misrouting unrelated requests into a third-party data-access workflow. Overbroad triggering can cause unintended external queries, unnecessary token use, logging of unrelated user prompts, and incorrect handling of requests that belong to other platforms or contexts.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Common phrases like '热点', '榜单', or '评论' are highly ambiguous and can collide with many unrelated user intents. In this context, broad phrase matching is more dangerous because the skill performs networked data retrieval and persistent logging, so false activation can send unintended queries to external services and store irrelevant user input.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The README says collected Douyin data is automatically exported to local JSON logs, but it does not prominently warn that comments, author metadata, or other scraped content may be sensitive and persist on disk. This increases the risk of unintended retention, secondary sharing, or exposure of scraped data on shared machines or in backups.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The README instructs users to set GUAIKEI_API_TOKEN but does not clearly disclose that requests are sent to an external service operated via guaikei.com. Users may assume the tool is purely local, while in reality authenticated data access depends on a third-party service, creating consent, trust, and credential-handling risks.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The invocation examples use very broad everyday trigger phrases such as '搜索 / 搜一下 / 找', which can cause over-triggering and accidental execution when a user is speaking generally rather than intentionally invoking the skill. Because the skill performs external data collection and may write logs, unintended activation can lead to unauthorized queries and unnecessary data retention.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The intent rule maps broad phrases like '热搜 / 热点 / 榜单 / 今天什么火' directly to the Douyin hot-list command without requiring an explicit Douyin context. This makes accidental or mistaken invocation more likely, especially since these phrases are commonly used for general web, news, or other-platform queries.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The changelog expands the skill from the declared four user-facing capabilities to a broader 'general search interface' including social data search. This indicates scope drift and possible hidden or undeclared data-access behavior, which can mislead reviewers and enable broader collection or retrieval than users or platform governance expect.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

Describing the feature as 'bulk scraping competitor account content' goes beyond normal end-user assistance and signals collection at scale. At-scale scraping raises policy, privacy, and abuse concerns because it can facilitate surveillance, unauthorized aggregation, or commercial misuse of creator content.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

This code performs HTTP requests that transmit a skill token and a user-supplied video URL to external API endpoints, which is a safety-relevant data transmission. While the functions have developer-facing docstrings, there is no user-facing warning, confirmation, or visible logging in this file to disclose that these values are being sent over the network.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The task-status lookup sends the token, video URL, and requested limit in a GET request, which is a network operation involving potentially sensitive or user-provided data. This file does not include any visible user warning, confirmation, or runtime disclosure for that transmission.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This file's natural-language content, including the module description, parameter documentation, and retry log message, is entirely in Chinese. The policy allows locale constraints only when the skill offers language choice or clearly documents a justified region-specific limitation, which is not present in this file.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This file contains natural-language strings and comments such as the module description and parameter docs exclusively in Chinese, and the request labels later in the file are also Chinese. Under the stated policy, forcing a specific language without user opt-in or a documented regional justification is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The CLI persists fetched comment data to a local JSON file automatically after successful execution, and the output may contain user-generated content or other sensitive business data. Because there is no explicit user consent, warning, opt-in flag, or retention control, this creates a privacy and data-handling risk, especially on shared systems or in automation environments where local artifacts may be harvested or retained unexpectedly.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This code reads a credential from process.env.GUAIKEI_API_TOKEN and uses it to create and fetch a remote task, which means user-provided input and system-held credentials are transmitted over the network. While the function names and comments describe the business purpose, this file does not include a user-facing disclosure, confirmation, or warning about credential use or remote transmission.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The CLI writes the full retrieved Douyin post results to a local JSON log file after completing what is described as a query-style retrieval action. This creates undisclosed data persistence on disk, which can expose scraped content, metadata, and user query context to other local users, backups, or later unintended processing.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.