Back to skill

Security audit

guaikei-xhs-see-details

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to perform the Xiaohongshu data collection it advertises, but it handles credentials and saved results in ways users should review first.

Install only if you are comfortable sending Xiaohongshu links, keywords, and your GUAIKEI API token to guaikei.com, and with collected results being saved locally in plaintext logs. Use a dedicated low-privilege token if possible, avoid running on shared machines for sensitive research, and periodically delete or protect the generated logs.

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 URL Query Strings

Content
View full analysis

Vulnerability Details

File Location: src/utils/request.js:76-96, 101-119; credential parameters originate from src/api/search.js:20-28, 49-61, src/api/detail.js:17-25, 43-52, src/api/comment.js:17-25, 43-52, and src/api/post.js:17-25, 43-52
Vulnerability Type: API credential exposure through query strings
Risk Level: Medium

Vulnerable Code

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

js
async function postJson(path, params, data) {
  if (!path || typeof path !== "string") {
    throw new Error("path must be a non-empty string");
  }
  if (!params || typeof params !== "object") {
    throw new Error("params must be an object");
  }
  if (!data || typeof data !== "object") {
    throw new Error("data must be an object");
  }
  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, params) {
  if (!path || typeof path !== "string") {
    throw new Error("path must be a non-empty string");
  }
  if (!params || typeof params !== "object") {
    throw new Error("params must be an object");
  }
  params._ = Date.now();

  const fullPath = `${path}?${querystring.stringify(params)}`;
  const options = {
    host: constants.BASE_URL,
    path: fullPath,
    method: "GET",
    headers: {
      "Content-Type": "application/json",
    },
  };
  return await request(options);
}

Representative credential source in src/api/detail.js:17-25, 43-52:

js
async function createDetailTask(token, url, limit) {
  return await withRetry(
  
...[truncated 2664 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove token from all query-parameter objects.

  2. Pass the token in an HTTP authorization header, preferably using a standard scheme:

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

  4. Ensure server, proxy, gateway, and telemetry configurations redact authorization headers and any legacy token query parameter.

  5. Rotate credentials that may already have appeared in operational logs.

  6. Define token expiration, revocation, and least-privilege policies.

  7. Add automated tests that fail if sensitive parameter names such as token, api_key, or secret appear in generated request URLs.

T09 · Insecure Skill Coding Practices

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

Collected Records Automatically Persisted in Plaintext with Default Permissions

Content
View full analysis

Vulnerability Details

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

Vulnerable Code

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

js
async function taskWrite(filename, content) {
  if (!filename || typeof filename !== "string") {
    utils.printError("The log filename must be a non-empty string");
    return;
  }
  if (!content || typeof content !== "string") {
    utils.printError("The log content must be a non-empty string");
    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(`Saved to ${outputFilename}`);
  } catch (error) {
    utils.printError(`Log write failed: ${error.message}`);
  }
}

Representative invocation in src/xiaohongshu/detail-cli.js:158-161:

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

The search, comment, and post commands invoke the same logging function for their successful results.

Technical Analysis

Every successful collection is serialized as plaintext JSON and automatically written beneath the project-level logs/ directory. No explicit file mod ...[truncated 2186 chars]

Remediation
View remediation

Remediation Suggestions

  1. Make local file persistence opt-in through an explicit option such as --output.

  2. Clearly disclose file creation, location, contents, and retention behavior in user documentation.

  3. Create the output directory and files with restrictive permissions:

    js
    await fs.promises.mkdir(outputDirectory, {
      recursive: true,
      mode: 0o700,
    });
    
    await fs.promises.writeFile(outputFilename, content, {
      mode: 0o600,
      flag: "wx",
    });
    
  4. Redact sensitive query parameters, including xsec_token, before printing or persisting URLs.

  5. Avoid storing unnecessary request metadata and minimize the returned fields written to disk.

  6. Provide configurable retention and secure deletion procedures.

  7. Add logs/ to .gitignore to reduce accidental source-control publication.

  8. For datasets requiring confidentiality, support encryption at rest with keys stored separately from the output files.

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

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

声明描述的核心能力是“围绕某个博主主页进行公开作品列表抓取,并结合详情和评论做账号/竞品分析”。但代码片段的实际功能是调用 /api/xiaohongshu/note-search/keyword 和 /api/xiaohongshu/note-search/info 两个接口,创建并查询‘关键词搜索’任务。它处理的是搜索词、内容类型、排序、发布时间、数量等检索维度,并把结果中的 note/user 标识拼成可访问URL。这与‘给定博主主页链接,抓取该博主作品列表并分析表现’存在明显偏差。代码没有展示博主主页解析、作品列表抓取、笔记详情抓取、评论抓取或节奏/风格/互动分析逻辑。因此该代码块与声明用途存在实质性不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

声明描述的是一个面向小红书竞品分析的数据抓取与内容表现分析技能;而实际代码仅是 src/utils/args.js 中的通用 CLI 参数解析器。它处理命令行选项、布尔参数、位置参数、重复参数检测、必填检查和帮助信息输出。这与声明的核心能力和主要用途明显不符。虽然参数解析可能作为更大系统的辅助模块存在,但就当前提供的代码片段而言,其实际行为与技能描述没有直接对应关系,因此应判定为描述与代码行为不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

声明描述的是一个用于抓取和分析小红书公开内容的技能,但提供的代码片段实际只负责本地TOKEN格式校验和错误提示,属于访问控制/配置管理功能。该代码没有表现出任何与小红书数据抓取、内容分析、评论处理或竞品监控直接相关的行为。因此就该代码片段而言,实际行为与声明用途存在明显不一致。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

声明描述的是一个面向小红书公开内容抓取与竞品分析的技能,而提供的代码片段实际只是本地日志写入辅助模块,没有任何抓取小红书作品、详情、评论、账号分析或网络访问行为。虽然日志功能可能是支持性实现细节,但当前代码片段本身的实际行为与声明的主要用途明显不一致,且展示了未声明的本地文件写入能力。因此应判定为描述与代码行为不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description describes a network/data-collection and analysis skill for Xiaohongshu public creator content. The actual code chunk is a simple utility that uses fs and path to locate package.json, read it from the local filesystem, parse it, and return the package name. That behavior is materially different from the declared purpose and accesses a different resource type (local package metadata rather than Xiaohongshu content). This is not merely a supporting implementation detail for the declared behavior based on the supplied chunk; the chunk itself implements an unrelated utility function.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

声明描述的是一个面向小红书博主竞品分析的数据抓取与分析技能,核心能力应包括基于博主主页链接获取公开作品、进一步获取笔记详情与评论,并据此进行内容表现分析。但给出的代码块只是一个通用的输入校验模块:检查搜索关键词是否合法、清洗关键词字符、规范化搜索选项参数。它甚至明确拒绝包含 http 的输入,这与声明中“给了博主主页链接即可适用”的触发方式相矛盾。虽然这可能是某个更大系统中的辅助模块,但就该代码块实际行为而言,与声明的核心用途存在明显不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

声明的核心能力是“博主公开作品列表 + 笔记详情与评论”的账号级分析,面向博主主页/竞品账号监控场景;而这段代码的核心行为是单条笔记详情与评论抓取。它要求传入的是笔记链接(isNoteUrl),命令名也是 detail,返回的是单条 note 的 detailTask,并未展示任何博主主页解析、作品列表枚举、跨多篇内容汇总或节奏/风格分析逻辑。因此其主要用途与声明存在实质偏差。代码没有明显越权到私密数据或登录态,但其实际范围明显比声明的账号分析技能更窄且对象不同。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

声明描述的是一个较完整的竞品分析型技能:不仅要抓取公开作品列表,还要配合笔记详情与评论,还原发文节奏、内容风格和互动表现。但这段代码实际只实现了一个 post-cli:接收博主主页链接和数量限制,校验 URL,调用 createPostTask/getPostTask 获取“主页笔记任务”结果,并输出 JSON。就当前可见代码而言,它没有展示评论获取、详情获取、统计分析或竞品分析逻辑。因此,代码行为相比声明明显更窄,主要是“获取博主主页笔记结果”,不能充分支撑所宣称的完整分析用途。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

声明的核心用途是“博主/竞品账号分析”,输入应偏向博主主页链接或账号对象,输出应包含作品列表并配合详情、评论进行账号层面的内容与互动分析。代码却是一个通用关键词搜索工具,主要能力是根据 keyword/type/sort/time/limit 发起搜索任务并返回结果。两者主目标明显不同:一个是账号分析抓取,另一个是关键词搜索。代码中也没有任何迹象表明它会解析博主主页、枚举某博主全部公开作品、补充详情与评论,或生成分析结论。因此属于明显的描述-行为不一致。日志写入属于次要实现细节,但也说明其实际行为与“纯分析技能”描述不完全一致。

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 38)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 54)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 58)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 76)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 149)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 39)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 55)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 76)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 152)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 40)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 56)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 58)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 76)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 155)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
90% confidence
Finding

The skill declares access to a sensitive environment variable (GUAIKEI_API_TOKEN) but does not define any explicit tool scope or permission boundary. That increases the chance of over-broad execution in agent environments and makes secret use less auditable, especially because the skill forwards user-supplied inputs to a third-party API.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger rules are broad enough that an agent may invoke this skill whenever a user shares a Xiaohongshu link or vaguely asks about content performance, even without clear consent to send data to an external API. In an agent setting, over-broad auto-invocation can cause unintended third-party data disclosure and surprise network actions.

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:16