Back to skill

Security audit

guaikei-xhs-note-finder

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it says, but it handles an API token in URL query strings and automatically saves retrieved data and Xiaohongshu URL tokens to local plaintext logs.

Install only if you are comfortable sending Xiaohongshu URLs, search terms, and your GUAIKEI_API_TOKEN to the third-party guaikei.com API. Treat the token as sensitive, rotate it if exposed, and review or delete the generated logs because they may contain Xiaohongshu xsec_token URL parameters and collected public 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

Warning
Location
src/utils/request.js:87
Finding

API Credential Exposed in HTTPS URL Query Strings

Content
View full analysis

Vulnerability Details

File Location: src/utils/request.js:76-119; credential parameters originate from src/api/search.js:23-26,52-59, src/api/detail.js:20-23,46-50, src/api/post.js:20-23,46-50, and src/api/comment.js:20-23,46-50
Vulnerability Type: Authentication credential disclosure through URL query parameters
Risk Level: Medium

Vulnerable Code

Credential-bearing parameters are serialized directly into request URLs:

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);
}

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);
}

Every API module supplies the token as one of these query parameters. For example:

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

Remediation Suggestions

  1. Remove token from all query-parameter objects.
  2. Transmit the credential in an authentication header, preferably:
    js
    headers: {
      "Authorization": `Bearer ${token}`,
      "Content-Type": "application/json"
    }
    
  3. Refactor postJson and getJson so credentials are accepted separately from ordinary query parameters and cannot be serialized into a URL accidentally.
  4. Configure servers, proxies, and monitoring systems to redact authorization data and sensitive Xiaohongshu URL parameters.
  5. Add automated tests asserting that generated request paths never contain token, api_key, or similar credential names.
  6. Rotate credentials previously used by affected versions if infrastructure URL logs may have been accessible to unauthorized parties.
  7. Apply short token lifetimes, least-privilege scopes, rate limits, and server-side revocation support to reduce the impact of future exposure.

T09 · Insecure Skill Coding Practices

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

Automatic Plaintext Persistence of Retrieved Data and Sensitive URL Tokens

Content
View full analysis

Vulnerability Details

File Location: src/utils/log.js:5-38; call sites at src/xiaohongshu/search-cli.js:188-211, src/xiaohongshu/detail-cli.js:143-161, src/xiaohongshu/post-cli.js:145-163, and src/xiaohongshu/comment-cli.js:143-161
Vulnerability Type: Sensitive data stored in plaintext with default filesystem permissions
Risk Level: Low

Vulnerable Code

The log writer automatically creates a local directory and writes the supplied content without explicitly restricting file permissions:

js
async function taskWrite(filename, content) {
  if (!filename || typeof filename !== "string") {
    utils.printError("Log filename must be a non-empty string");
    return;
  }
  if (!content || typeof content !== "string") {
    utils.printError("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}`);
  }
}

Successful commands pass the complete request metadata and API response to this function. For example:

js
const finalOutput = {
  status: "success",
  error_code: "OK",
  message: "Detail task completed",
  timestamp: new Date().toLocaleString(),
  request: {
    command: "detail",
    url: url,
    limit: limit,
  },
  skill_metadata: 
...[truncated 2692 chars]
Remediation
View remediation

Remediation Suggestions

  1. Make disk logging opt-in through an explicit option such as --save-output.
  2. Remove or redact xsec_token and other sensitive query parameters before printing or writing request URLs.
  3. Create the log directory with mode 0o700 and files with mode 0o600:
    js
    await fs.promises.mkdir(directory, { recursive: true, mode: 0o700 });
    await fs.promises.writeFile(outputFilename, content, { mode: 0o600 });
    
  4. Warn users clearly when output is persisted and display the exact destination.
  5. Support a configurable output directory outside the source tree.
  6. Add retention controls and a cleanup command so stale output can be removed safely.
  7. Avoid storing complete responses by default; save only fields explicitly requested by the user.
  8. For environments requiring durable storage, consider encryption at rest and prevent log directories from being committed, backed up, or synchronized unintentionally.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (60)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

声明的核心用途是账号/博主层面的竞品分析,需要先抓取博主公开作品列表,再配合详情与评论进行综合分析。但该代码片段只调用 /api/xiaohongshu/detail/url 和 /api/xiaohongshu/detail/info 两个接口,输入也是单个笔记链接 url 与评论数量 limit,功能集中在单篇笔记详情及评论任务的创建和查询。虽然它处理的是公开小红书数据,也没有显示访问私密或登录态数据,但其主要能力明显比声明更窄,缺少“博主公开作品列表抓取”这一声明中的关键部分,因此描述不能准确代表该代码块的实际行为。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

声明的核心能力是“基于博主主页链接抓取公开作品列表,并结合详情与评论进行账号级分析”。但实际代码仅包含 note-search 搜索模块:创建关键词搜索任务、查询搜索结果,并给结果拼接笔记/用户主页URL。这说明其主要用途是内容搜索,不是博主账号画像或竞品账号监控。虽然代码访问的仍是小红书公开内容,且未涉及登录态或私密数据,但其主要功能与声明用途存在明显偏差,属于实质性描述不符。

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

声明的核心用途是小红书公开账号内容抓取与竞品分析,但实际代码只处理API TOKEN的有效性检查和提示信息,主目的与声明严重不符。虽然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
98% confidence
Finding

The declared description says the skill scrapes and analyzes public Xiaohongshu creator content, including posts, details, and comments, to assess content performance. However, the supplied code chunk does none of that. It simply accesses the local filesystem, loads package.json, and returns the package name. That is a materially different behavior and an undeclared capability relative to the description. While this may be a small utility file rather than the whole skill, based on the supplied chunk alone, the behavior does not match the declared purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

声明描述的是一个面向小红书博主竞品分析的数据采集与分析技能,核心能力应包括根据博主主页链接获取公开作品、进一步读取笔记详情和评论并进行分析。但提供的代码片段只是在本地验证和清洗搜索关键词,限制关键词长度、字符类型、是否包含链接,并对搜索选项进行取值校正。这属于输入校验的辅助模块,而非所声明技能的核心行为。虽然单个代码片段可能只是整体系统中的一部分,但就该片段本身来看,其实际行为与声明的主要用途存在明显偏离,因此应判定为不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

声明描述的是“博主级别”的小红书竞品分析能力:抓取博主公开作品列表,再结合笔记详情和评论,恢复其整体内容节奏与互动表现。而代码实际仅实现了一个针对“单条笔记链接”的评论抓取 CLI:它解析 --url 和 --limit 参数,校验是否为笔记链接,调用 comment.createCommentTask / getCommentTask 获取评论数据,并输出 JSON 结果。代码中没有博主主页链接处理、作品列表抓取、笔记详情聚合、发文节奏分析或内容风格分析逻辑。因此其主要目的与声明存在明显偏差。虽然抓取公开笔记评论与声明中的“评论”部分相关,但仅是整体宣称能力中的一个子步骤,不能代表完整声明。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

声明描述的是一个账号级的小红书竞品分析技能,核心能力应包括:从博主主页抓取公开作品列表,再结合多篇笔记详情与评论进行聚合分析。而这段代码的主功能明显更窄:它是 detail-cli,只接受单个“笔记链接”参数,校验为 note URL,调用 detail.createDetailTask/getDetailTask 获取单篇笔记详情和评论,最后输出结果并写文件。代码中没有任何博主页抓取、作品列表枚举、跨多笔记汇总、节奏/风格/互动分析逻辑。因此该代码行为与声明的主要用途存在实质性不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
90% confidence
Finding

声明描述的是一个较完整的竞品分析型技能:不仅要抓取公开作品列表,还要配合笔记详情与评论,还原发文节奏、内容风格和互动表现。而这段代码实际只是一个 CLI 包装层,用于提交并获取“博主笔记任务”结果,核心可见行为局限于 URL 参数解析、主页链接校验、调用 post.createPostTask / post.getPostTask、输出 JSON 结果及写本地日志。从该代码块本身看,不足以支持“评论抓取”“详情抓取”“分析还原”这些声明中的关键能力,因此声明范围明显大于当前代码实际体现的行为,构成描述与行为不一致。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

声明描述的核心用途是“博主/竞品账号分析”,输入应偏向博主主页链接,并围绕该账号的作品、详情和评论做聚合分析。而实际代码仅是 search-cli:接受关键词及筛选参数,调用 search.createSearchTask / getSearchTask 执行搜索,返回匹配内容列表并写日志。其主要功能是内容搜索,不是博主账号分析。虽然二者都与小红书公开内容有关,但主目标、输入形式和输出能力都存在明显差异,因此属于描述与行为不一致。

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 40)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 107)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 260)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 328)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 41)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 108)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 271)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 328)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 109)May include surrounding context.

md
| 看某篇小红书笔记的评论数据 | `src/xiaohongshu/comment-cli.js` | 笔记 URL | 该笔记的评论内容、评论者信息、互动数据 |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| 看某篇小红书笔记的评论数据 | `src/xiaohongshu/comment-cli.js` | 笔记 URL | 该笔记的评论内容、评论者信息、互动数据 |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| 看某篇小红书笔记的评论数据 | `src/xiaohongshu/comment-cli.js` | 笔记 URL | 该笔记的评论内容、评论者信息、互动数据 |

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.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The manifest description and the full markdown guidance are written only in Chinese, which effectively forces a specific language for use and troubleshooting. Under the policy, language constraints should either offer user choice/opt-in or be clearly justified as region-specific; this file does not state such a justification.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The manifest describes a skill focused on fetching a blogger’s public works list together with note details and comments for competitor-account/content-performance analysis. In contrast, the README advertises additional capabilities such as keyword search for trending topics, KOL筛选, and market trend monitoring, which materially broadens the skill from account analysis to general Xiaohongshu data mining and trend prediction.

Content

No source excerpt is available for this finding.