Back to skill

Security audit

guaikei·小红书笔记详情

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its Xiaohongshu public-data purpose, but it handles credentials and saved results in ways users should review before installing.

Install only if you are comfortable sending Xiaohongshu keywords, note/profile URLs, limits, and a Guaikei API token to www.guaikei.com. Treat the API token as sensitive, rotate it if exposed, and review or clean the logs/ directory because successful runs save result data locally by default.

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

API Credential Exposed in HTTP Query Strings

Content
View full analysis

Vulnerability Details

File Location: src/utils/request.js:76-98; credential-bearing calls originate from src/api/search.js:20-28,49-59, src/api/detail.js:17-25,43-50, src/api/comment.js:17-24,43-49, and src/api/post.js:17-24,43-49
Vulnerability Type: API credential exposure through URL query parameters
Risk Level: Medium

Vulnerable Code

src/api/search.js:20-28:

js
async function createSearchTask(token, keyword, type, sort, time, limit) {
  return await withRetry(
    async () => {
      return await postJson(
        "/api/xiaohongshu/note-search/keyword",
        { _: Date.now(), token: token },
        { keyword, type, sort, time, limit },
      );
    },

src/api/search.js:49-59:

js
async function getSearchTask(token, keyword, type, sort, time, limit) {
  return await withRetry(
    async () => {
      const res = await getJson("/api/xiaohongshu/note-search/info", {
        _: Date.now(),
        token: token,
        keyword,
        type,
        sort,
        time,
        limit,
      });

src/utils/request.js:76-98:

js
async function postJson(path, params, data) {
  if (!path || typeof path !== "string") {
    throw new Error("path 必须是非空字符串");
  }
  if (!params || typeof params !== "object") {
    throw new Error("params 必须是对象");
  }
  if (!data || typeof data !== "object") {
    throw new Error("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",
      "Content-Length": Buffer.byteLength(jsonData),
    },
  };
  return await request(options, jsonData);
}

src/utils/request.js:101-119:

js
async function getJson(path, para
...[truncated 2795 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove token from every query-parameter object.

  2. Transmit the credential in a dedicated header, preferably:

    js
    headers: {
      "Authorization": `Bearer ${token}`,
      "Content-Type": "application/json",
    }
    
  3. Refactor postJson() and getJson() to accept the token separately from ordinary query parameters, preventing accidental future serialization.

  4. Configure API servers, reverse proxies, monitoring platforms, and error-reporting systems to redact authentication headers and sensitive query parameters.

  5. Avoid including complete request URLs in exceptions, traces, or debug logs.

  6. Rotate credentials that may already have appeared in access or observability logs.

  7. Add automated tests asserting that generated request paths never contain token, secret, or authorization values.

T09 · Insecure Skill Coding Practices

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

Fetched Content Is Automatically Persisted as Plaintext Without an Explicit Opt-In

Content
View full analysis

Vulnerability Details

File Location: src/utils/log.js:5-38; invoked by src/xiaohongshu/search-cli.js:208-211, src/xiaohongshu/detail-cli.js:158-161, src/xiaohongshu/comment-cli.js:158, and src/xiaohongshu/post-cli.js:160
Vulnerability Type: Insecure local storage and undisclosed data retention
Risk Level: Low

Vulnerable Code

src/xiaohongshu/detail-cli.js:158-161:

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

src/xiaohongshu/search-cli.js:208-211:

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

src/utils/log.js:5-38:

js
async function taskWrite(filename, content) {
  if (!filename || typeof filename !== "string") {
    utils.printError("日志文件名必须是非空字符串");
    return;
  }
  if (!content || typeof content !== "string") {
    utils.printError("日志内容必须是非空字符串");
    return;
  }
  let safeFilename = filename
    .replace(/[\\/:*?"<>|]/g, "_")
    .replace(/\.\.+/g, "_")
    .replace(/^\.+|\.+$/g, "");
  if (safeFilename.length > 200) {
    safeFilename = safeFilename.substring(0, 200);
  }
  if (safeFilename === "") {
    safeFilename = `log_${Date.now()}`;
  }
  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

All four successful command flows call taskWrite() automatically. The complete structured result is stored beneath the project-level logs/ directory, in ...[truncated 2133 chars]

Remediation
View remediation

Remediation Suggestions

  1. Make file persistence opt-in through a clearly documented option such as --output <path>; default to stdout-only operation.

  2. If automatic logging must remain, clearly disclose the stored fields, location, retention period, and privacy implications before execution.

  3. Redact xsec_token and other sensitive query parameters from request metadata and returned URLs before writing.

  4. Create directories and files with restrictive permissions:

    js
    await fs.promises.mkdir(directory, {
      recursive: true,
      mode: 0o700,
    });
    await fs.promises.writeFile(outputFilename, content, {
      mode: 0o600,
      flag: "wx",
    });
    
  5. Introduce configurable retention and secure cleanup of expired output files.

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

  7. Document that local files may be included in backups, source archives, or build artifacts, and add logs/ to .gitignore.

  8. Consider field-level minimization or encryption when results must be retained.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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 (43)

Tp4

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding

The declared description is narrowly scoped to public Xiaohongshu data operations. However, the code shown contains only generic constants and points to www.guaikei.com rather than a Xiaohongshu-related endpoint or identifier. While configuration alone is not a capability by itself, the referenced base domain is inconsistent with the declared single-platform purpose, and the chunk provides no indication of Xiaohongshu-specific behavior. Therefore this is best classified as a description-behavior mismatch with high confidence based on the supplied snippet.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

声明描述的是一个面向小红书公开数据处理的专用技能,范围限定在小红书内容查询相关能力;而代码片段实际只是通用的 CLI 参数解析与帮助文本构建工具,不执行任何小红书数据访问、搜索、详情读取、评论获取或博主作品处理。虽然这类工具代码可能作为实现细节被下游小红书功能复用,但就当前代码片段本身而言,其主要目的与声明的技能用途不一致,因此构成描述与行为不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

声明描述的是面向小红书公开内容抓取/处理的技能能力与适用范围;而实际代码并未体现任何小红书平台相关逻辑、搜索/详情/评论/博主作品处理逻辑,也没有平台判定或数据访问行为。相反,该代码提供了本地文件系统日志写入能力,属于未在声明中体现的通用持久化/文件操作能力。虽然日志功能可能是辅助实现细节,但在当前提供的代码片段中,其实际行为与声明的主要用途明显不一致,因此应判定为描述与代码行为不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared purpose is a Xiaohongshu public-data skill, but the supplied code chunk is a generic utility that accesses the local filesystem to read package metadata. It does not implement note search, details, comments, creator content retrieval, or any Xiaohongshu-specific behavior. Filesystem access is also not implied by the declared purpose. This is therefore a material description-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

声明描述的是一个面向小红书公开内容获取的领域技能,而代码实际只是底层通用工具库 retry.js,实现重试逻辑、延迟等待和错误处理。该代码既不访问小红书,也不处理任何平台数据,不体现声明中的平台范围、数据类型或触发条件。虽然这类工具函数可能作为技能内部支持实现存在,但就所提供代码块本身来看,其实际行为与声明的主要用途明显不一致,因此应判定为描述与代码不匹配。

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 37)May include surrounding context.

md
- "看这篇笔记的详情和评论区: node src/xiaohongshu/detail-cli.js --url 'https://www.xiaohongshu.com/explore/xxx?xsec_token=yyy' --limit 100"

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 70)May include surrounding context.

md
- "看这篇笔记的详情和评论区: node src/xiaohongshu/detail-cli.js --url 'https://www.xiaohongshu.com/explore/xxx?xsec_token=yyy' --limit 100"

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 90)May include surrounding context.

md
- "看这篇笔记的详情和评论区: node src/xiaohongshu/detail-cli.js --url 'https://www.xiaohongshu.com/explore/xxx?xsec_token=yyy' --limit 100"

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 38)May include surrounding context.

md
- "看这位博主最近 20 条作品: node src/xiaohongshu/post-cli.js --url 'https://www.xiaohongshu.com/user/profile/xxx?xsec_token=yyy' --limit 20"

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 72)May include surrounding context.

md
- "看这位博主最近 20 条作品: node src/xiaohongshu/post-cli.js --url 'https://www.xiaohongshu.com/user/profile/xxx?xsec_token=yyy' --limit 20"

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 92)May include surrounding context.

md
- "看这位博主最近 20 条作品: node src/xiaohongshu/post-cli.js --url 'https://www.xiaohongshu.com/user/profile/xxx?xsec_token=yyy' --limit 20"

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 39)May include surrounding context.

md
- "只拉这篇笔记的评论做舆情: node src/xiaohongshu/comment-cli.js --url 'https://www.xiaohongshu.com/explore/xxx?xsec_token=yyy' --limit 100"

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 71)May include surrounding context.

md
- "只拉这篇笔记的评论做舆情: node src/xiaohongshu/comment-cli.js --url 'https://www.xiaohongshu.com/explore/xxx?xsec_token=yyy' --limit 100"

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 91)May include surrounding context.

md
- "只拉这篇笔记的评论做舆情: node src/xiaohongshu/comment-cli.js --url 'https://www.xiaohongshu.com/explore/xxx?xsec_token=yyy' --limit 100"

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The manifest says this skill only handles Xiaohongshu public data operations such as note search, detail, comments, and creator works. In contrast, the package description and keywords claim capabilities like competitor monitoring, high-value KOL screening, precise marketing, account growth, and user profiling, which imply broader analytics and marketing functions beyond simple public-data retrieval.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

This code sends the user's API token and note URL to a remote API via postJson, which is a safety-relevant network transmission of potentially sensitive data. While the JSDoc documents parameters for developers, there is no user-facing warning, confirmation, or visible disclosure in this file about transmitting that data.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

This function performs a network call that includes the API token, note URL, and limit in the request parameters, but the file provides no user-facing notice that this data is being transmitted externally. Internal comments and error logs are not sufficient disclosure to the end user under this rule.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This JavaScript file contains natural-language comments and user-facing CLI output entirely in Chinese, including errors and help text. Because the file does not offer a language choice or document that the tool is intentionally limited to a Chinese-speaking or region-specific context, it appears to impose a specific language without user opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The user-facing messages are hard-coded in Chinese and there is no indication that the skill offers a language choice or is intentionally limited to a Chinese-speaking context. This can violate language/locale policy because the skill imposes a specific language on all users without opt-in.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This code builds GET and POST HTTPS requests and sends caller-supplied params and data to a remote host via https.request, but there is no confirmation prompt, user-facing log/print, or explanatory comment/docstring warning that user or system data may be transmitted externally. Because this is a reusable request utility, the network transmission behavior is not disclosed here even though it can carry arbitrary data.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The comments and user-visible error strings are consistently in Chinese, which imposes a specific language on users. Under the policy, locale constraints should either be optional for users or clearly documented as region-specific and justified; this file provides neither.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The CLI persists the full request and fetched results to a local JSON file, which can include queried URLs, note identifiers, comments, and other scraped content without explicit user warning or opt-in. On shared machines, CI runners, or multi-user environments, this creates unnecessary data retention and increases the chance of sensitive or regulated content being exposed through local artifacts.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The CLI persists the full fetched results to a local JSON file automatically, and those results may contain scraped public-content metadata, URLs, comments, or other user-related information. Even if the source data is public, silently creating local artifacts increases privacy, retention, and secondary exposure risk because the file may remain on disk, be synced, or be read by other local users/processes without the operator realizing it.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The manifest explicitly says the skill is for public Xiaohongshu data and not for login-state data. Requiring and reading GUAIKEI_API_TOKEN introduces credential handling/authenticated access behavior that is not explained by the stated purpose, especially since the manifest does not mention external service authentication.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.exposed_secret_literal

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
SKILL.md:15