Back to skill

Security audit

guaikei-rednote-public-data

Security checks for vulnerabilities and agentic risk

Overview

The skill matches its stated Xiaohongshu public-data purpose, but users should review its credential handling and automatic local result storage before installing.

Install only if you are comfortable sending Xiaohongshu keywords or URLs and your GUAIKEI_API_TOKEN to guaikei.com. Use a dedicated, revocable token, monitor quota use, and delete or protect the generated logs because they may contain full retrieved datasets and token-bearing Xiaohongshu URLs.

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

Content
View full analysis

Vulnerability Details

File Location: src/utils/request.js:76-98, src/utils/request.js:101-119, src/api/comment.js:20-23, src/api/detail.js:20-23, src/api/post.js:20-23, src/api/search.js:23-26
Vulnerability Type: Credential exposure through URL query parameters
Risk Level: Medium

Vulnerable Code

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

API call sites explicitly place the credential in the params object:

js
return await postJson(
  "/api/xiaohongshu/detail/url",
  { _: Date.now(), token: token },
  { url: url, limit: limit },
);

The same pattern is used by the search, post, and comment API modules. Polling requests also include the token in GET parameters:

js
const res = await getJson("/api/xiaohongshu/detail/info", {
  _: Date.now(),
  token: token,
  url: url,
  limit: limit,
});

getJson serializes those parameters into the request URL:

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.n
...[truncated 2639 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove token from every query-parameter object in src/api/search.js, detail.js, post.js, and comment.js.

  2. Pass the token separately to the HTTP utility and transmit it through an authorization header:

    js
    const options = {
      host: constants.BASE_URL,
      path: fullPath,
      method: "POST",
      headers: {
        Authorization: `Bearer ${token}`,
        "Content-Type": "application/json",
        "Content-Length": Buffer.byteLength(jsonData),
      },
    };
    
  3. Ensure server-side access logs, reverse proxies, tracing systems, and error-reporting platforms redact legacy token query parameters.

  4. Do not include credentials in thrown errors, telemetry, debug output, or structured result objects.

  5. Rotate existing API tokens if URLs containing them may already have been retained.

  6. Add automated tests asserting that generated request paths never contain token=, while the authorization header is present.

  7. Consider short-lived, revocable credentials with narrowly scoped permissions to reduce the impact of future disclosure.

T09 · Insecure Skill Coding Practices

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

Automatic Local Retention of Sensitive Query URLs and Retrieved Data

Content
View full analysis

Vulnerability Details

File Location: src/xiaohongshu/detail-cli.js:135-163, src/utils/log.js:24-35; equivalent successful-result storage exists in search-cli.js, comment-cli.js, and post-cli.js
Vulnerability Type: Insecure local storage and excessive sensitive-data retention
Risk Level: Low

Vulnerable Code

The complete request URL and returned content are included in the successful output and passed to the logging function:

js
const finalOutput = {
  status: "success",
  error_code: "OK",
  message: "Details 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(`Details task completed and results returned`);

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

The logging utility automatically creates the directory and writes the content without specifying restrictive permissions:

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

Technical Analysis

Successful operations are automatically persisted beneath the package's logs/ directory. The serialized object contains the original Xiaohongshu URL and the complete returned dataset. Xiaohongshu URLs accepted by this Skill commonly include an `xsec_to ...[truncated 2342 chars]

Remediation
View remediation

Remediation Suggestions

  1. Make local persistence opt-in through a flag such as --output or --save; do not save successful responses by default.

  2. Redact sensitive URL parameters before printing or writing data. At minimum, remove or replace xsec_token, token, and other authentication-like parameters:

    js
    function redactUrl(rawUrl) {
      const parsed = new URL(rawUrl);
      for (const key of ["xsec_token", "token", "access_token"]) {
        if (parsed.searchParams.has(key)) {
          parsed.searchParams.set(key, "[REDACTED]");
        }
      }
      return parsed.toString();
    }
    
  3. Recursively sanitize URLs appearing inside returned result objects, not only the top-level request URL.

  4. Create the log directory with mode 0o700 and result files with mode 0o600:

    js
    await fs.promises.mkdir(path.dirname(outputFilename), {
      recursive: true,
      mode: 0o700,
    });
    await fs.promises.writeFile(outputFilename, content, {
      mode: 0o600,
      flag: "wx",
    });
    
  5. Document the exact storage location, retained fields, and security implications in SKILL.md and the README.

  6. Provide configurable retention and a cleanup command, and exclude logs/ from source-control and packaging workflows.

  7. Avoid storing the full result if only a summary is needed. Apply data minimization to reduce the consequences of local disclosure.

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

Tp4

High
Category
MCP Tool Poisoning
Confidence
87% confidence
Finding

The declared description is narrowly scoped to Xiaohongshu public-data retrieval. However, the supplied code references a different domain, www.guaikei.com, and contains only generic constants for retries, timeouts, and versioning. While configuration files alone do not prove the full skill purpose, this chunk does indicate access to a resource inconsistent with the declared Xiaohongshu-only scope and does not substantiate the claimed platform-specific behavior. Therefore this is a likely description-behavior mismatch based on the visible code.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

声明描述的是一个面向小红书公开数据访问的专用技能,强调平台范围、适用场景和数据类型;但实际代码只是通用的参数解析与帮助文档构建工具,没有任何与小红书、公开数据、搜索、详情、评论、博主作品或平台链接识别相关的行为。虽然这类工具代码可能作为实现细节被其他小红书功能复用,但就该代码片段本身而言,其主要目的与声明严重不一致,属于 materially different primary purpose。

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 is for a Xiaohongshu public-data skill, but the actual code chunk only implements a utility that accesses the local filesystem to read package.json and return the package name. This is not a supporting implementation detail clearly tied to Xiaohongshu data access in the supplied chunk, and it demonstrates behavior unrelated to the declared platform-specific purpose. Therefore, the code and description do not match.

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 56)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 67)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 78)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 117)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 230)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 57)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 79)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 129)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 230)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 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 67)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 80)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 141)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 230)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.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The README says all task results are automatically saved to disk but does not clearly warn users that collected note/comment/account data may persist locally and remain accessible after the run. In a data-collection skill, silent persistence increases the risk of unintended exposure through shared machines, backups, or later exfiltration, even if the source data is nominally public.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The manifest limits the skill to handling public Xiaohongshu data operations such as note search, details, comments, and creator posts. The changelog states the skill added “评论情绪分析” (comment sentiment analysis), which is an additional analysis capability not reflected in the manifest description and therefore expands behavior beyond the declared scope.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The manifest describes concrete public-data access functions: note search, detail retrieval, comments, and creator works. The changelog additionally advertises “竞品分析、KOL筛选和趋势监控等核心商业分析功能,” which are higher-level analytical/monitoring capabilities not mentioned in the manifest and represent a broader stated behavior.

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