Back to skill

Security audit

小红书评论分步采集

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it claims, but it handles account tokens, paid quota, and commenter data with unsafe default network security and weak enforcement of paid-step consent.

Review carefully before installing. Use it only if you are comfortable sending Xiaohongshu links, collected comments, exports, and account tokens to the configured backend. Prefer an HTTPS base URL before logging in, avoid `insecure=true`, explicitly approve each paid collection step, and protect or delete exported CSV files because they contain commenter personal data.

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 Credentials Are Transmitted over Plaintext HTTP by Default

Content
View full analysis

Vulnerability Details

File Location: src/config.js:17, with credential transmission at src/client.js:48-71 and cli.js:329-331
Vulnerability Type: Plaintext transmission of authentication credentials
Risk Level: High

Technical Analysis

The built-in service URL uses plaintext HTTP:

js
const DEFAULT_BASE_URL = 'http://st.aidata366.com';

This value becomes the effective service URL unless the user explicitly supplies an override:

js
return {
  baseUrl: overrides.baseUrl || process.env.XHS_PLATFORM_BASE_URL || file.base_url || DEFAULT_BASE_URL,
  token: overrides.token !== undefined ? overrides.token : (file.token || ''),
  insecure: process.env.XHS_PLATFORM_INSECURE === '1' || file.insecure === true,
};

Authenticated API requests add the user's bearer token to the request headers regardless of whether the URL uses HTTP or HTTPS:

js
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 CSV export path also sends the same credential over the configured URL:

js
const res = await fetch(
  `${cfg.baseUrl}/api/v1/comments/sessions/${encodeURIComponent(sessionId)}/export`,
  { headers: { Authorization: `Bearer ${cfg.token}` }, signal: dlCtrl.signal });

The client emits a warning when HTTP is used, but it does not block the request. Consequently, the persistent account token crosses the local-machine trust boundary through an unauthenticated and unencrypted network channel.

This is not evidence that the configured server intentionally steals credentials. It is a reachable transport-security vulnerability that allows an independent network-path attacker to capture or modify them.

Attack Path

  1. The user registers or logs in, causing an account bearer tok ...[truncated 1350 chars]
Remediation
View remediation

Remediation Suggestions

  1. Replace the production default with an HTTPS endpoint that has a valid, hostname-matching certificate.
  2. Refuse to attach bearer credentials to plaintext HTTP requests.
  3. Permit HTTP only for explicitly recognized loopback development targets such as 127.0.0.1, localhost, or ::1, and avoid using production credentials in that mode.
  4. Treat the existing stderr message only as supplemental notice, not as a security control.
  5. Validate the effective URL using the standard URL parser rather than a string-prefix check.
  6. Prevent HTTPS-to-HTTP redirect downgrades for authenticated requests.
  7. If the service cannot immediately support HTTPS, use a mutually authenticated secure tunnel rather than sending credentials directly over the public Internet.
  8. After deploying secure transport, revoke or rotate tokens that may previously have traversed plaintext networks.

T09 · Insecure Skill Coding Practices

Warning
Location
cli.js:245
Finding

Paid Collection Operations Do Not Enforce the Documented User-Confirmation Gate

Content
View full analysis

Vulnerability Details

File Location: cli.js:245-266, with the required confirmation documented at SKILL.md:38
Vulnerability Type: Missing authorization enforcement for chargeable operations
Risk Level: Medium

Technical Analysis

The Skill instructions establish a user-consent boundary: the Agent must report the estimated number of pages and must not invoke any paid step operation until the user confirms.

However, the executable entry point does not technically enforce that boundary. The page and expansion branches require only a syntactically valid session ID and an account token:

js
async function cmdStep(opts) {
  const sessionId = requireSessionId(opts);
  const cfg = resolveConfig(opts);
  requireToken(cfg);
  const client = new ApiClient({ baseUrl: cfg.baseUrl, token: cfg.token });
  let data;
  if (opts.expand) {
    const root = opts.root;
    if (!root) throw new UsageError('step --expand requires --root');
    data = await client.stepCommentSession(sessionId, 'expand', root);
  } else {
    data = await client.stepCommentSession(sessionId, 'page');
  }
  printOk(data);
}

The resulting request immediately invokes the chargeable server operation:

js
stepCommentSession(sessionId, type, rootCommentId = '') {
  return this.request('POST', `/comments/sessions/${encodeURIComponent(sessionId)}/step`, {
    body: { type, root_comment_id: rootCommentId }, timeoutMs: 200000,
  });
}

There is no confirmation flag, approval token, interactive prompt, dry-run mode, per-session spending limit, or server-issued authorization artifact tied to the proposed charge. The confirmation requirement therefore depends entirely on the Agent following prose instructions.

Warnings printed before or after the request do not enforce consent. In particular, output explaining that the operation costs one point is emitted as informational text rather than requiring an affirmative response before the network request.

Attack Path

  1. A fr ...[truncated 1478 chars]
Remediation
View remediation

Remediation Suggestions

  1. Enforce consent in the executable or server-side transaction path rather than relying exclusively on Skill documentation.
  2. After start, return a cost summary without enabling paid operations until an explicit approval action is recorded.
  3. Require a short-lived, single-use approval token for each paid step. Bind it to:
    • The authenticated account.
    • The session ID.
    • The operation type (page or expand).
    • The root comment ID when applicable.
    • The exact maximum charge.
  4. Invalidate the approval token after one operation so that approval cannot authorize an unbounded loop.
  5. Add configurable per-session and per-command spending limits.
  6. Provide a non-chargeable preview or dry-run response that reports the pending action and cost.
  7. Ensure retries are idempotent so network failures cannot cause duplicate deductions.
  8. Keep the conversational confirmation instructions as defense in depth, but do not treat them as the primary authorization control.
Vulnerability Patterns
  • 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
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (7)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill exposes shell, network, and environment-backed behavior but does not declare any explicit tool scope or allowed-tools boundary. In practice this means an agent could invoke broad command execution and network access without a narrowly constrained permission model, increasing the chance of misuse, command abuse, or unintended access to local config/token material such as ~/.xhs-platform/config.json.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The trigger phrases are very broad and include generic terms around comments, public opinion, and exporting comments, which can cause the skill to activate in situations beyond the user's clear intent. Because this skill can collect and export personal data fields from commenters, overbroad invocation increases the risk of unnecessary data collection and privacy-impacting actions being launched in the wrong context.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill prominently advertises collection and export of commenter data, including nickname, comment content, and IP location, without an upfront privacy warning at the top-level description where invocation decisions are made. This makes it easier for agents or users to begin data collection without first being clearly informed that personal data is involved, raising compliance and privacy handling risks.

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 file contains extensive natural-language instructions, usage text, and status messages exclusively in Chinese, including required user guidance and operational prompts. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is explicitly justified, which is not present here.

Content

No source excerpt is available for this finding.

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
97% confidence
Finding

The function disables TLS certificate verification globally by setting NODE_TLS_REJECT_UNAUTHORIZED=0, which allows HTTPS connections to proceed without validating the server identity. This enables man-in-the-middle attacks against all subsequent HTTPS requests in the process, including authenticated API calls carrying bearer tokens, and is especially risky in a networked data-collection skill that communicates with backend services.

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/...) */

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

Natural-language comments and user-facing guidance in this file are written exclusively in Chinese, including operational warnings and migration notices. This indicates a language-specific policy choice without any visible opt-in or alternative language support, which matches the language/locale policy violation category.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

This file's documentation and multiple user-facing error/help messages are written only in Chinese, indicating the skill communicates in a fixed language. The policy for this category flags language/locale constraints when the skill does not offer a user choice or document a justified region-specific limitation.

Content

No source excerpt is available for this finding.