Back to skill

Security audit

抖音用户主页采集

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it says, but it handles account tokens and paid collection over unsafe defaults that users should review before installing.

Install only if you accept using this provider's paid remote service and understand that, by default, your saved bearer token may be sent over plain HTTP. Prefer setting an HTTPS base URL with valid certificates before login or collection, avoid enabling insecure TLS, review the saved token file, and manually confirm any collect command because the CLI itself does not enforce a charge-confirmation step.

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

Error
Location
src/config.js:17
Finding

Bearer Token Transmitted Over Plaintext HTTP by Default

Content
View full analysis

Vulnerability Details

File Location: src/config.js:17-20, src/client.js:52-72
Vulnerability Type: Plaintext transmission of authentication credentials
Risk Level: High

Technical Analysis

The Skill uses a plaintext HTTP endpoint as its default service URL:

js
// Security note: the service certificate is not ready, so HTTP remains the default.
// The original source comments explicitly acknowledge this transport risk.
const DEFAULT_BASE_URL = 'http://st.aidata366.com';

Authenticated API requests attach the account bearer token to requests made against that URL:

js
async request(method, apiPath, opts = {}) {
  const { body, headers = {}, timeoutMs = REQUEST_TIMEOUT_MS } = opts;
  // Plaintext HTTP with a token only emits a warning; it does not stop the request.
  if (!_httpWarned && this.token && this.baseUrl.startsWith('http://')) {
    _httpWarned = true;
    process.stderr.write('[warn] 当前服务地址为明文 http,token 会明文传输,建议确认网络安全或切换 https\n');
  }

  const ctrl = new AbortController();
  const timer = setTimeout(() => ctrl.abort(), timeoutMs);
  let res;
  let payload = null;
  try {
    res = await fetch(this.baseUrl + '/api/v1' + apiPath, {
      method,
      headers: {
        ...(body ? { 'Content-Type': 'application/json' } : {}),
        ...(this.token ? { Authorization: `Bearer ${this.token}` } : {}),
        ...headers,
      },
      body: body ? JSON.stringify(body) : undefined,
      signal: ctrl.signal,
    });

The warning does not provide a technical security boundary. Authenticated operations such as quota, collect, query, export, and logout therefore transmit the bearer credential and associated API traffic without transport encryption under the default configuration.

This crosses the trust boundary between the local machine and the remote service over the intervening network. The behavior is disclosed in `SKILL. ...[truncated 1392 chars]

Remediation
View remediation

Remediation Suggestions

  1. Change the default service endpoint to HTTPS with a certificate that passes normal hostname and chain validation.
  2. Reject authenticated requests to non-HTTPS endpoints rather than merely emitting a warning.
  3. If plaintext transport is required for local development, restrict it to loopback addresses and require an explicit development-only override.
  4. Do not recommend disabling TLS certificate verification as a production workaround. Provision and renew a valid server certificate instead.
  5. Consider revoking or rotating tokens previously used over plaintext transport.
  6. Add a regression test verifying that requests containing an authorization token fail before network transmission when the destination uses HTTP.

T09 · Insecure Skill Coding Practices

Warning
Location
cli.js:217
Finding

Credit-Charging Collection Operation Does Not Enforce User Confirmation

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:67-75, cli.js:217-247
Vulnerability Type: Missing executable authorization gate for a billed operation
Risk Level: Medium

Technical Analysis

The Skill documentation requires the agent to quote the expected charge and wait for explicit user confirmation:

text
1. **查余额**:`node cli.js quota` 确认点数充足(余额 < 预扣点数会被 3001 拒绝)。
2. **报价确认(必须)**:向用户明确以下信息并**等用户确认后**再提交:
   - 主页链接、采集页数(1~10,每页约 20 条)
   - 预估点数:`页数 × 5`
   - 计费规则:**预扣 页数×5,按实采 ceil(M/20)×5 结算退差**
   - **未经用户确认不要执行 collect。**
3. **提交并等待**:`node cli.js collect --url <主页链接> --pages <N> --wait --timeout 600`

However, the executable collection path does not require a confirmation flag, confirmation token, interactive approval, or quote acknowledgment before submitting the billed task:

js
async function cmdCollect(opts) {
  const cfg = resolveConfig(opts);
  requireToken(cfg);
  const profileUrl = validateProfileUrl(opts.url);

  if (opts.pages !== undefined && !/^\d+$/.test(String(opts.pages))) {
    throw new UsageError(`--pages 需为正整数(1~${MAX_PAGES})`);
  }
  const pages = opts.pages !== undefined
    ? Math.max(1, Math.min(parseInt(opts.pages, 10), MAX_PAGES))
    : DEFAULT_PAGES;

  // Read the price and calculate the estimate, but do not require approval.
  const { price } = await fetchPrice(cfg.baseUrl);
  const estimatedPoints = pages * price;

  const items = [{ id: 1, payload: { profile_url: profileUrl, pages } }];
  const idemSource = `${profileUrl}|${pages}` + (opts.force ? `|#force:${Date.now()}` : '');
  const idempotencyKey = crypto.createHash('sha256').update(idemSource).digest('hex').slice(0, 32);

  process.stderr.write(
    `提交抖音主页采集任务: url="${profileUrl}" 页数=${pages} (约 ${pages * BILL_UNIT} 条)\n` +
    `计费: 预扣 ${pages}×${price}=${estimatedPoints} 点 (每页约 ${BILL_UNIT} 条=${price} 点), ` +
    `按实采量结算退差, 零结果/失败/主页不可见全额返还 (幂等键 
...[truncated 2094 chars]
Remediation
View remediation

Remediation Suggestions

  1. Split collection into quote and commit phases. The quote phase should return the URL, page count, current unit price, maximum charge, and a short-lived server-bound quote identifier.
  2. Require an explicit argument such as --confirm-quote <quote-id> before submitTask() can run.
  3. Validate that the confirmed quote still matches the requested URL, page count, account, and current price.
  4. If a two-phase server API is unavailable, require an explicit local flag such as --confirm-charge <amount> and reject execution when the supplied amount differs from the freshly calculated charge.
  5. Make quotation or dry-run behavior the default and require a separate explicit commit operation.
  6. Apply the same confirmation requirement to --force, with a distinct warning that it bypasses content deduplication and may create another billed task.
  7. Add automated tests proving that collect cannot call submitTask() without a valid confirmation artifact.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (18)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill presents itself as a scraper/export tool, but it also reads and writes user-level config, migrates tokens, honors environment overrides, and sends credentials to an external service over configurable transport. This is especially dangerous because the document explicitly states the default endpoint is plain HTTP, so tokens may be exposed in transit or mishandled locally.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill presents itself as a scraper/export tool, but it also reads and writes user-level config, migrates tokens, honors environment overrides, and sends credentials to an external service over configurable transport. This is especially dangerous because the document explicitly states the default endpoint is plain HTTP, so tokens may be exposed in transit or mishandled locally.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The manifest is narrowly scoped to Douyin user-homepage video harvesting. The presence of '/comments/sessions' APIs for a separate comments-session workflow, explicitly documented as 'xhs_comments', introduces a cross-platform comment collection capability that is not justified by the stated purpose of this skill.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill invokes shell, network, and environment-backed behaviors but does not declare any explicit tool scope or allowed-tools boundary. That makes its effective capabilities broader than what a reviewer or runtime policy can easily constrain, increasing the chance of unintended command execution, network access, or secret exposure.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The trigger phrases are broad enough to match common requests about Douyin profiles, creator videos, and scraping, which can cause the skill to activate in situations where the user did not intend this specific third-party workflow. Because the skill performs login, billing, and external network operations, overbroad triggering raises the risk of unintended data transfer or charges.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

Embedding registration, login, token persistence, and quota/billing flows expands the skill far beyond simple data collection and introduces credential and financial-risk surfaces. In context, this is more dangerous because the same skill also instructs the agent to handle authentication state and saved tokens, creating opportunities for misuse or leakage.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This code presents its primary documentation, usage text, prompts, and operational messages entirely in Chinese, which imposes a specific language on users. Under the policy, forcing a specific language without user choice is a natural-language policy violation unless the locale restriction is explicitly documented and justified.

Content

No source excerpt is available for this finding.

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
99% confidence
Finding

allowInsecureTls disables TLS certificate verification process-wide by setting NODE_TLS_REJECT_UNAUTHORIZED=0, allowing man-in-the-middle interception or modification of all subsequent HTTPS requests in the process. In a skill that sends bearer tokens and potentially sensitive scraping/session data to backend APIs, this can expose credentials and collected data, and the process-wide scope makes unrelated requests unsafe too.

Content

Scanner excerpt · src/client.js (reported line 17)May include surrounding context.

js
/** 忽略 HTTPS 证书校验 (服务端自签/域名不匹配证书时由 insecure 配置开启)。进程级。 */
function allowInsecureTls() {
  process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
}

/** 业务错误: code 为后端错误码 (1001/1002/3001/...) */

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The manifest describes a skill for collecting a Douyin creator homepage video list and exporting CSV. However, this client also supports logout/session creation, user profile retrieval, generic platform task submission, Xiaohongshu-style comment sessions, and Douyin comment-session workflows, which are materially broader capabilities than homepage video-list scraping.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

Even within Douyin, the manifest describes collecting a creator’s published video list and associated metadata, not interactive comment-session acquisition. These comment-session endpoints add a distinct data-collection mode and broader content access than the skill claims to perform.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This skill includes a shared configuration and credential-management module for multiple XHS-related skills, which exceeds the narrow stated purpose of Douyin profile scraping. Over-broad credential handling increases the attack surface and creates a risk that secrets or settings from unrelated tools are accessed or reused without the user's clear understanding.

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 comments and stderr messages intended for operators/users in Chinese, including the migration notice at L075-L076. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is explicitly justified or configurable.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The code reads credentials from another skill's legacy config store and copies them into this skill automatically. This violates least privilege and trust boundaries between tools, and could expose or silently reuse tokens that the user never intended to authorize for this skill or backend.

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 comment and multiple user-facing strings define the output convention and operational guidance entirely in Chinese, including error/help text shown to users. This creates a locale-specific behavior without any visible opt-in, fallback, or justification 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
89% confidence
Finding

The file presents the skill name, summary, instructions, and required user-facing scripts entirely in Chinese, including language the agent is told to send verbatim to users. This can impose a specific language/locale on users without an explicit choice or documented justification.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The file instructs the agent to direct users to customer service for registration, recharge, and bulk purchasing, including phone and WeChat contact details. This is not a direct capability required to collect Douyin profile videos and expands the skill into customer-support/sales handling outside its stated operational purpose.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The natural-language description in package.json is entirely in Chinese and does not indicate that language selection is optional or that the skill is intended only for a Chinese-speaking or region-specific audience. This can violate language/locale policy guidance when a skill implicitly enforces one language without opt-in or justification.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

The module silently defaults to a remote service endpoint over plain HTTP and supports bearer-style token configuration, while the manifest presents the skill as a local scraping/export utility. This creates a transparency and security problem because scraped data and credentials may be transmitted to a remote backend without clear disclosure, and HTTP permits interception or tampering in transit.

Content

No source excerpt is available for this finding.