Back to skill

Security audit

guaikei-xhs-acquisition

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly coherent for Xiaohongshu data research, but it automatically sends and stores access-bearing URLs and API credentials in ways users should review before installing.

Install only if you are comfortable sending Xiaohongshu keywords, note URLs, profile URLs, and retrieved public data to the Guaikei API. Treat GUAIKEI_API_TOKEN and xsec_token URLs as sensitive, and avoid running this in shared workspaces unless you can control or clean the generated logs directory.

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 Through URL Query Parameters

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/comment.js:20-23,46-50, and src/api/post.js:20-23,46-50
Vulnerability Type: API credential exposure through URL query strings
Risk Level: Medium

Vulnerable Code

The API modules place the credential in the parameter object:

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

The request implementation serializes that object directly into the URL for both POST and GET requests:

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": 
...[truncated 2075 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove token from all query-parameter objects.

  2. Pass the credential through a dedicated request option and send it using an authorization header, such as:

    js
    headers: {
      "Authorization": `Bearer ${token}`,
      "Content-Type": "application/json",
    }
    
  3. If the service uses a custom authentication scheme, use a dedicated secret header rather than a URL parameter.

  4. Configure the API origin, reverse proxies, gateways, and telemetry systems to redact authorization headers and historical token query parameters.

  5. Rotate tokens that have already been used by the affected implementation.

  6. Add automated tests asserting that generated request paths never contain token=.

  7. Avoid including credentials in exception messages, debug output, metrics labels, or request tracing.

T09 · Insecure Skill Coding Practices

Warning
Location
src/utils/log.js:26
Finding

Automatic Plaintext Persistence of URLs, Access Parameters, and Retrieved Data

Content
View full analysis

Vulnerability Details

File Location: src/utils/log.js:26-34; invoked with complete result objects from src/xiaohongshu/search-cli.js:188-210, src/xiaohongshu/detail-cli.js:141-160, src/xiaohongshu/comment-cli.js:141-160, and src/xiaohongshu/post-cli.js:143-162
Vulnerability Type: Insecure plaintext storage of potentially sensitive data
Risk Level: Medium

Vulnerable Code

The detail workflow includes the complete supplied URL and API response in the object passed to the logger:

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: {
    skill_version: constants.VERSION,
    runtime_version: process.versions.node,
    execution_time: Date.now() - startTime,
  },
  results: detailTask,
};
console.log(JSON.stringify(finalOutput, null, 2));
utils.printSuccess(`Detail task completed and returned results`);

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

The logging utility writes this content directly to a persistent plaintext file:

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

Equivalent full-result logging occurs in the search, comment, and profile-post CLIs.

Technical Analysis

Every successful operation is archived automatically beneath the project-level logs directory. The archived JSON can contain:

  • The complete user-suppli ...[truncated 2333 chars]
Remediation
View remediation

Remediation Suggestions

  1. Make result archival opt-in through an explicit command-line option such as --save.

  2. Do not include complete request URLs in logs. Parse URLs and remove sensitive query parameters, especially xsec_token, before serialization.

  3. Minimize stored results to fields required for the user's stated purpose instead of archiving complete API responses.

  4. Create the log directory with restrictive permissions and write files with an explicit owner-only mode:

    js
    await fs.promises.mkdir(logDirectory, {
      recursive: true,
      mode: 0o700,
    });
    await fs.promises.writeFile(outputFilename, content, {
      mode: 0o600,
      flag: "wx",
    });
    
  5. Implement configurable retention and automatic deletion of expired logs.

  6. Prevent the logs directory from being included in source control, CI artifacts, support bundles, or container images.

  7. Clearly notify users before persisting collected data and document the location, contents, permissions, and retention policy.

  8. For deployments that require long-term archival, encrypt stored datasets and keep encryption keys outside the project directory.

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

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

声明描述的核心能力是“小红书关键词搜索笔记”,包括排序、时间筛选、笔记列表和互动数据返回;而实际代码仅提供两个函数:创建评论采集任务和查询评论结果,输入是单个笔记链接(url)和评论数量(limit),调用的也是 /api/xiaohongshu/comment/url 与 /api/xiaohongshu/comment/info 评论接口。两者主功能明显不同:一个是关键词级内容发现/搜索,另一个是单笔记评论抓取。因此属于实质性描述与行为不一致。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

声明的核心能力是“关键词检索小红书公开笔记并按互动指标/时间进行筛选排序”,但代码片段的核心行为是调用 /api/xiaohongshu/detail/url 和 /api/xiaohongshu/detail/info 接口,针对给定笔记URL创建详情/评论抓取任务并获取结果。这属于不同的主要用途:搜索发现内容 vs. 查看单篇笔记详情与评论。代码也访问了与‘detail’相关的资源,而非搜索接口,因此描述不能准确代表该代码实际功能,构成明显不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

声明描述的核心能力是“关键词搜索小红书公开笔记”,并支持排序、时间筛选和关键词比较分析。但代码中只有两个接口:createPostTask 和 getPostTask,均围绕博主URL调用 /api/xiaohongshu/post/url 和 /api/xiaohongshu/post/info,用于创建和查询“已发布笔记任务”。文件注释也明确写的是“小红书博主详情、已发布笔记模块”。这说明实际功能是抓取某个博主的已发布笔记,而不是按关键词检索全站公开笔记。代码里也没有任何与关键词、点赞/评论/收藏排序、时间筛选、互动数据聚合分析相关的实现。因此该代码与声明用途存在明显的主功能不一致,并且实际具备了一个未声明的能力:按博主URL获取其已发布笔记。

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

根据提供的代码片段,实际行为仅限于输入 token 的格式校验和提示信息输出,不涉及访问小红书公开内容、关键词搜索、排序、时间筛选、返回笔记列表或互动数据等核心能力。因此,这段代码与声明描述的主要功能明显不一致。虽然 token 校验可能是某个更大系统的辅助实现细节,但就该代码片段本身来看,其实际用途是鉴权/配置检查,并额外包含联系微信获取私有 TOKEN 的未声明行为。

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 content-search and analytics skill, but the supplied code chunk merely reads package.json from the local filesystem to obtain the package name. This is materially unrelated to the declared end-user functionality. While this could be a small supporting utility within a larger project, based on this code chunk alone the actual behavior does not match the described capability.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

声明描述的是一个面向小红书公开笔记的关键词搜索与结果分析能力,核心行为应包括检索、排序、时间过滤以及返回笔记互动数据。但给出的代码片段只包含 URL 处理工具:将 URL 规范为 https、校验是否是笔记或主页链接、以及从 URL 生成名称。它没有体现任何搜索、抓取结果列表、互动数据统计或关键词比较逻辑。虽然处理的小红书域名与声明场景相关,但该代码的实际功能与声明的主要用途存在明显差异,因此应判定为不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

声明描述的是“小红书关键词搜索”能力,重点在于按关键词检索公开笔记,并支持排序、时间筛选,以及返回笔记列表与互动数据。但代码实际是 comment-cli.js,其输入是笔记链接(--url)和评论数量(--limit),会验证是否为小红书笔记URL,然后调用 createCommentTask/getCommentTask 获取该笔记的评论内容。整个流程没有任何关键词搜索、排序选项、时间筛选逻辑,也没有面向多个笔记的搜索结果列表输出。因此代码的主要功能与声明的主要用途明显不一致,属于实质性描述-行为不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

声明描述的是“小红书关键词搜索”能力:输入关键词后搜索公开笔记,并支持排序、时间筛选、对比热度等发现型场景。但代码实际实现的是 detail-cli,要求传入 --url 或位置参数中的笔记链接,并可指定评论数量 limit;随后调用 detail.createDetailTask 和 detail.getDetailTask 获取该笔记详情/评论结果。代码中没有任何关键词搜索、排序、时间过滤或多关键词对比逻辑。因此其主要目的与声明明显不一致,属于实质性能力不匹配。环境变量 token 属于实现细节,不是主要判定依据。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

声明描述的核心能力是“基于关键词搜索小红书公开笔记,并支持互动排序和时间筛选”。但实际代码要求输入的是小红书博主主页 URL(--url),还明确校验为 profile 链接,并调用 createPostTask/getPostTask 获取该主页下的笔记列表。代码中唯一可配置项是 limit,没有任何关键词、排序、时间范围或多关键词比较参数。因此其主要用途与声明存在实质性偏差。代码访问的小红书公开内容仍属同一平台,但资源对象从‘关键词搜索结果’变成了‘指定博主主页笔记’,属于能力和主用途不一致,应判定为 mismatch。

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 41)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 108)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 261)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 329)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 42)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
- "看这个小红书博主最近 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 272)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 329)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 110)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 284)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 329)May include surrounding context.

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

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The CLI schema and help text show this command accepts a Xiaohongshu creator profile URL and retrieves that creator's posts, which materially exceeds the stated skill purpose of keyword-based public note search and comparison. This kind of scope drift is dangerous because it enables collection of creator-specific datasets that users and reviewers would not expect from the manifest, undermining consent, review boundaries, and data-minimization guarantees.

Content

No source excerpt is available for this finding.

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.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The description explicitly says the skill may be used even when the user did not mention Xiaohongshu, as long as the context is general social-media content mining. This overbroad trigger can cause the agent to invoke a third-party data-acquisition skill in response to generic requests, resulting in unintended data disclosure to the external service, wrong-platform execution, or surprising behavior outside user intent. Because the skill sends queries to a third-party API and is scoped to a specific platform, ambiguous auto-routing materially increases misuse risk.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.