Back to skill

Security audit

redbook

Security checks for vulnerabilities and agentic risk

Overview

This is a real Xiaohongshu automation tool, but it handles live account cookies and has unsafe install-time and credential-routing behavior that users should review before installing.

Install only if you are comfortable giving this CLI access to live Xiaohongshu/RedNote session cookies and account actions. Back up or check ~/.claude/skills/redbook before npm install, avoid saved cookie files on shared/cloud systems, keep REDBOOK_EDITH_HOST and REDBOOK_CREATOR_HOST unset unless you fully trust the environment, and do not render untrusted markdown with the card renderer.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Tool Hijacking and SpoofingModifies or replaces tools so legitimate-looking calls execute attacker logic
  • 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
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
src/lib/platform.ts:60
Finding

Session Cookie Exfiltration Through Unrestricted API Host Overrides

Content
View full analysis
{ return { "user-agent": USER_AGENT, "content-type": "application/json", cookie: cookiesToString(this.cookies), origin: this.platform.homeUrl, referer: `${this.platform.homeUrl}/`, }; } private async mainApiGet( uri: string, params?: Record ): Promise { const fullUri = buildGetUri(uri, params); const url = `${this.platform.edithHost}${fullUri}`; const send = (signFormat: SignFormat) => fetch(url, { method: "GET", headers: { ...this.baseHeaders(), ...signMainApi("GET", uri, this.cookies, params, undefined, undefined, this.platform.signLocation, signFormat), }, }); ``` ```ts // src/lib/client.ts:95-105 private async mainApiPost( uri: string, data: Record ): Promise { const signHeaders = signMainApi("POST", uri, this.cookies, undefined, data, undefined, this.platform.signLocation); const url = `${this.platform.edithHost}${uri}`; const res = await fetch(url, { method: "POST", headers: { ...this.baseHeaders(), ...signHeaders }, body: JSON.stringify(data), }); ``` ### Technical Analysis The client legitimately nee ...[truncated 2380 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/postinstall.js:27
Finding

Postinstall Script Recursively Deletes an Existing Skill Path

Content
View full analysis
${PACKAGE_ROOT}`); return true; ``` ### Technical Analysis The npm `postinstall` lifecycle runs automatically during package installation. The script attempts to register the package as a Claude Code Skill at `~/.claude/skills/redbook`. If that path already exists and is not a symbolic link, the installer invokes: ```js rmSync(SKILL_LINK, { recursive: true }); ``` There is no ownership marker, content validation, backup, confirmation, or requirement that the existing directory was created by this package. Therefore, an unrelated user-managed Skill or other data at the same path is recursively destroyed. Creating a Skill link can support the package's optional integration, but deleting an unknown directory during ordinary npm installation exceeds the privileges necessary to install the CLI. ### Attack Path 1. A user has an existing directory or file at: ```text ~/.claude/skills/redbook ``` 2. The directory contains a custom Skill, local configuration, or other user-controlled data. 3. The user installs or upgrades the package with npm. 4. npm automatically executes `node scripts/postinstall.js`. 5. The script sees tha ...[truncated 800 chars]
Remediation
View remediation

T07 · Tool Hijacking and Spoofing

Warning
Location
scripts/postinstall.js:55
Finding

Postinstall Script Mutates Integrity-Checked Dependency Code

Content
View full analysis
30s).'); } catch (err) { console.log(`[redbook] Warning: could not patch sweet-cookie: ${err.message}`); } } function patchSweetCookieBigInt() { const target = join( PACKAGE_ROOT, 'node_modules', '@steipete', 'sweet-cookie', 'dist', 'providers', 'chromeSqlite', 'shared.js' ); if (!existsSync(target)) return; try { const content = readFileSync(target, 'utf-8'); const needle = 'SELECT name, value, host_key, path, expires_utc, samesite, encrypted_value,'; if (!content.includes(needle)) { // Already patched or upstream fixed return; } const patched = content.replace( needle, 'SELECT name, value, host_key, path, CAST(expires_utc AS TEXT) AS expires_utc, samesite, encrypted_value,' ); writeFileSync(target, patched, 'utf-8'); console.log('[redbook] Patched sweet-cookie BigInt overflow (CAST expires_utc).'); } catch (err) { console.log(`[redbook] Warning: could not patch sweet-cookie BigInt: ${err.message}`); } } ``` ### Technical Analysis npm verifies downloaded package artifacts against the integrity values in `package-lock.json`. ...[truncated 2038 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
src/lib/render.ts:526
Finding

Untrusted Markdown Is Processed by Unsandboxed Chrome Without HTML Sanitization

Content
View full analysis
{ try { const { marked } = await import("marked"); return await marked.parse(md); } catch { console.error(kleur.red("Card rendering requires marked.")); console.error(kleur.dim("Install it with:")); console.error(kleur.dim(" npm install -g marked")); process.exit(1); } } ``` ```ts const browser = await launch.call(puppeteer.default ?? puppeteer, { executablePath: chromePath, headless: true, args: ["--no-sandbox", "--disable-setuid-sandbox", "--disable-gpu"], }); try { const page = await browser.newPage(); await page.setViewport({ width: opts.width, height: opts.height, deviceScaleFactor: opts.dpr, }); // Render cover const coverHtml = buildCoverHtml(frontmatter, style, opts.width, opts.height); await page.setContent(coverHtml, { waitUntil: "domcontentloaded" }); const coverPath = join(opts.outputDir, "cover.png"); await page.screenshot({ path: coverPath, type: "png", clip: { x: 0, y: 0, width: opts.width, height: opts.height }, }); // Render content cards const cardPaths: string[] = []; for (let i = 0; i < pages.length; i++) { const html = await markdownToHtml(pages[i]); const cardHtml = buildCardHtml( html, i + 1, pages.length, style, opts.width, opts.height ); await page.setContent(cardHtml, { waitUntil: "domcontentloaded" }); ``` ### Technical Analysis The renderer passes Markdown to `marked.parse()` and embeds the resulting HTML into a browser page. No sanitizer, content-security policy, JavaScript disablement, URL-scheme validation, or request interception is shown. Markdown parsers commonly preserve embedded HTML unless configured or followed ...[truncated 1935 chars]
Remediation
View remediation
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Rogue AgentSelf-Modification, Session Persistence
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (70)

YARA rule 'info_stealer': Information stealer patterns (credential harvesting, browser data theft) [malware]

High
Category
YARA Match
Confidence
75% confidence
Finding

YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Content

Scanner excerpt · CLAUDE.md (reported line 22)May include surrounding context.

md
Manual trigger via `workflow_dispatch` is also available.

## Build & Test

- `npm run build` — TypeScript compile + chmod
- No test suite yet — verify manually with `redbook whoami`

## Project Structure

- `src/cli.ts` — CLI entry point, 21 commands, `getClient()` is the single cookie→client funnel
- `src/lib/client.ts` — XHS API client (`postComment`, `replyComment`, etc.)
- `src/lib/cookies.ts` — Cookie extraction with Chrome profile auto-discovery
- `src/lib/signing.ts` — Request signing
- `src/lib/analyze.ts` — Viral note analysis and question detection
- `src/lib/reply-strategy.ts` — Batch reply filtering, templating, rate-limited execution
- `src/lib/template.ts` — Viral content template extraction
- `src/lib/health.ts` — Note health check: level detection, sensitive words, tag count
- `src/lib/render.ts` — Card rendering (markdown → PNG via puppeteer-core, optional dep)
- `SKILL.md` — Skill documentation (serves both Claude Code and OpenClaw/ClawHub

YARA rule 'info_stealer': Information stealer patterns (credential harvesting, browser data theft) [malware]

High
Category
YARA Match
Confidence
95% confidence
Finding

The skill explicitly instructs users and AI agents to extract browser cookies, pass them on the command line, save them to files, and reuse them for authentication. Browser session cookies are plaintext bearer credentials; exposing them through CLI args, environment variables, cloud uploads, or automation can leak account access via shell history, process listings, logs, CI output, or compromised agent environments. In context, this is more dangerous because the tool is designed for agent-driven automation and cloud/OpenClaw use, which increases the chance that secrets are copied, persisted, or exfiltrated outside the user’s browser trust boundary.

Content

Scanner excerpt · README.md (reported line 153)May include surrounding context.

md
��) |
| `auth` | 保存、导出、检查 Cookie 文件,适合云端/OpenClaw 使用 |

### 通用选项

| 选项 | 说明 | 默认值 |
|------|------|--------|
| `--cookie-source <浏览器>` | Cookie 来源浏览器(chrome, safari, firefox) | `chrome` |
| `--chrome-profile <名称>` | Chrome 配置文件目录名(如 "Profile 1"),默认自动检测 | 自动 |
| `--cookie-string <cookies>` | 手动传入 Cookie 字符串:`"a1=值; web_session=值"`(从 Chrome DevTools 复制) | 无 |
| `--platform <name>` | 强制后端:`xhs`(大陆)或 `rednote`(全球版),不传则自动检测 | 自动 |
| `--global` | 强制使用全球版 RedNote 后端(等同 `--platform rednote`) | 无 |
| `--json` | JSON 格式输出 | `false` |

### 保存 Cookie / 云端使用

如果在 OpenClaw、云服务器或 CI 里运行,不想每条命令都加 `--cookie-string`,可以把 Cookie 保存成文件。普通命令会按这个顺序读取 Cookie:`--cookie-string` �

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The documentation discusses generating anti-bot API signatures, browser/device fingerprint material, and alternate signing formats to access protected APIs. That is not inherently malware, but it is a sensitive capability that exceeds a simple content-analysis description and can facilitate stealthier authenticated automation against protected services.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The documentation discusses generating anti-bot API signatures, browser/device fingerprint material, and alternate signing formats to access protected APIs. That is not inherently malware, but it is a sensitive capability that exceeds a simple content-analysis description and can facilitate stealthier authenticated automation against protected services.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The documentation discusses generating anti-bot API signatures, browser/device fingerprint material, and alternate signing formats to access protected APIs. That is not inherently malware, but it is a sensitive capability that exceeds a simple content-analysis description and can facilitate stealthier authenticated automation against protected services.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The documentation discusses generating anti-bot API signatures, browser/device fingerprint material, and alternate signing formats to access protected APIs. That is not inherently malware, but it is a sensitive capability that exceeds a simple content-analysis description and can facilitate stealthier authenticated automation against protected services.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The documentation discusses generating anti-bot API signatures, browser/device fingerprint material, and alternate signing formats to access protected APIs. That is not inherently malware, but it is a sensitive capability that exceeds a simple content-analysis description and can facilitate stealthier authenticated automation against protected services.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The documentation discusses generating anti-bot API signatures, browser/device fingerprint material, and alternate signing formats to access protected APIs. That is not inherently malware, but it is a sensitive capability that exceeds a simple content-analysis description and can facilitate stealthier authenticated automation against protected services.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The documentation discusses generating anti-bot API signatures, browser/device fingerprint material, and alternate signing formats to access protected APIs. That is not inherently malware, but it is a sensitive capability that exceeds a simple content-analysis description and can facilitate stealthier authenticated automation against protected services.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The documentation discusses generating anti-bot API signatures, browser/device fingerprint material, and alternate signing formats to access protected APIs. That is not inherently malware, but it is a sensitive capability that exceeds a simple content-analysis description and can facilitate stealthier authenticated automation against protected services.

Content

No source excerpt is available for this finding.

YARA rule 'info_stealer': Information stealer patterns (credential harvesting, browser data theft) [malware]

High
Category
YARA Match
Confidence
93% confidence
Finding

The text normalizes use of 'real logged-in cookies + residential IP + real Chrome fingerprint' to minimize detection. In context this is not proof of malware, but it does confirm the tool is designed to leverage live user session credentials and browser identity for stealthier automated access, which is sensitive and increases misuse potential.

Content

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

md
safe band, not guesswork. Community crawlers ([MediaCrawler](https://github.com/NanmiCoder/MediaCrawler)) default to **~2 s/request, single-threaded** (`CRAWLER_MAX_SLEEP_SEC = 2`, `MAX_CONCURRENCY_NUM = 1`); reverse-engineering write-ups put the "looks-human" frequency at **3–8 s/request** and the per-IP ceiling at **≤5 requests/min** (~12 s average). This skill runs on your **real logged-in cookies + residential IP + real Chrome fingerprint** — the *lowest*-detection profile (the thing scrapers spend most of their effort faking). So the binding risk isn't request signature, it's **behavioral**: a human doesn't open 100 note-detail pages in two minutes. We therefore pace to a human reading cadence — comfortably inside the safe band — rather than to the absolute minimum. (5-minute gaps, an earlier guess, are ~25× slower than the ceiling and buy nothing.)

### The real rule: behave like a human reading (not "go slow")

Detection here is **distributional, not a rate threshold.

Credential Access

High
Category
Privilege Escalation
Confidence
97% confidence
Finding

The skill explicitly relies on native keychain-backed browser cookie extraction to access Xiaohongshu sessions. Credential access is dangerous because extracted cookies can be reused to impersonate the user, perform account actions, and potentially expose private account data if stored or logged insecurely.

Content

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

md
- Node.js >= 22
- Logged into xiaohongshu.com in Chrome (or Safari/Firefox with `--cookie-source`)
- macOS (cookie extraction uses native keychain access)
- **For card rendering only:** `puppeteer-core` and `marked` (`npm install -g puppeteer-core marked`). Uses your existing Chrome — no additional browser download.

Self-Modification

High
Category
Rogue Agent
Confidence
85% confidence
Finding

Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.

Content

Scanner excerpt · docs/research-task-1789.md (reported line 280)May include surrounding context.

md
2. **Add persona-based reply** — extend `batch-reply` with `--persona <file>` option
3. **Add Gemini cover generation** — new `generate-cover` command with optional `@google/genai` dep
4. **Add Module L** to SKILL.md — AI Cover Generation analysis module
5. **Update SKILL.md metadata** — add `requires.env` for `GEMINI_API_KEY` (optional)
6. **Add `redbook monitor`** — simple comment monitoring loop with configurable interval

---

Known Vulnerable Dependency: basic-ftp==5.2.0 — 4 advisory(ies): GHSA-6v7q-wjvx-w8wg (basic-ftp: Incomplete CRLF Injection Protection Allows Arbitrary FTP Command Exe); CVE-2026-39983 (basic-ftp has FTP Command Injection via CRLF); CVE-2026-41324 (basic-ftp vulnerable to denial of service via unbounded memory consumption in Cl) +1 more

High
Category
Supply Chain
Confidence
80% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: extract-zip==2.0.1 — 2 advisory(ies): CVE-2026-19693 (extract-zip allows arbitrary file writes through symlink archive entries); CVE-2026-56876 (extract-zip unvalidated symlink path traversal)

High
Category
Supply Chain
Confidence
80% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: ip-address==10.1.0 — 2 advisory(ies): CVE-2026-69192 (ip-address: Address4 decodes leading-zero octets as decimal while resolvers deco); CVE-2026-42338 (ip-address has XSS in Address6 HTML-emitting methods)

High
Category
Supply Chain
Confidence
80% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: ws==8.19.0 — 2 advisory(ies): CVE-2026-45736 (ws: Uninitialized memory disclosure); CVE-2026-48779 (ws: Memory exhaustion DoS from tiny fragments and data chunks)

High
Category
Supply Chain
Confidence
80% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/postinstall.js (reported line 60)May include surrounding context.

js
}

/**
 * Patch @steipete/sweet-cookie keychain timeout bug.
 *
 * Published v0.1.0 hardcodes `timeoutMs: 3_000` in chromeSqliteMac.js,
 * ignoring the caller's value. The macOS `security` CLI often needs >3s

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/postinstall.js (reported line 64)May include surrounding context.

js
}

/**
 * Patch @steipete/sweet-cookie keychain timeout bug.
 *
 * Published v0.1.0 hardcodes `timeoutMs: 3_000` in chromeSqliteMac.js,
 * ignoring the caller's value. The macOS `security` CLI often needs >3s

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/postinstall.js (reported line 89)May include surrounding context.

js
}

/**
 * Patch @steipete/sweet-cookie keychain timeout bug.
 *
 * Published v0.1.0 hardcodes `timeoutMs: 3_000` in chromeSqliteMac.js,
 * ignoring the caller's value. The macOS `security` CLI often needs >3s

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · src/lib/cookies.ts (reported line 382)May include surrounding context.

ts
}

/**
 * Patch @steipete/sweet-cookie keychain timeout bug.
 *
 * Published v0.1.0 hardcodes `timeoutMs: 3_000` in chromeSqliteMac.js,
 * ignoring the caller's value. The macOS `security` CLI often needs >3s

Lp1

High
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The CLI reads environment variables such as REDBOOK_COOKIE_FILE, REDBOOK_PLATFORM, and REDBOOK_COOKIE_STRING, which expands its authority beyond what the manifest reportedly declares. In an agent-skill setting, understated environment access is dangerous because it allows the skill to consume secrets or alter behavior from ambient process state without explicit user awareness.

Content

No source excerpt is available for this finding.

YARA rule 'info_stealer': Information stealer patterns (credential harvesting, browser data theft) [malware]

High
Category
YARA Match
Confidence
89% confidence
Finding

The info-stealer signature is triggered by code that reads cookies directly from installed browsers, which is a real credential-harvesting capability even if presented as a convenience feature. In this skill's context, that capability is especially risky because the same tool can immediately use those cookies to perform authenticated reads and account mutations on behalf of the user.

Content

Scanner excerpt · src/cli.ts (reported line 81)May include surrounding context.

ts
oin(homedir(), ".redbook");
const DEFAULT_COOKIE_FILE = join(REDBOOK_DIR, "cookies.json");

const program = new Command();

program
  .name("redbook")
  .description("CLI tool for Xiaohongshu (Red Note)")
  .version(pkg.version);

// Global option for cookie source
function addCookieOption(cmd: Command): Command {
  return cmd
    .option(
      "--cookie-source <browser>",
      "Browser to read cookies from (chrome, safari, firefox)",
      "chrome"
    )
    .option(
      "--chrome-profile <name>",
      'Chrome profile directory name (e.g., "Profile 1")'
    )
    .option(
      "--cookie-string <cookies>",
      'Manual cookie string: "a1=VALUE; web_session=VALUE" (from Chrome DevTools)'
    )
    .option(
      "--platform <name>",
      "Force backend: 'xhs' (mainland xiaohongshu.com) or 'rednote' (global rednote.com). Default: auto-detect from your login."
    )
    .option(
      "--global",
      "Force the global RedNote backend (shorthand for --platform rednote)"
    );
}

Lp1

High
Category
MCP Least Privilege
Confidence
97% confidence
Finding

This module performs undisclosed network-capable behavior by probing a local HTTP DevTools endpoint and opening a WebSocket connection to Chrome. Even though the traffic is loopback-only, attaching to a browser debugging session exposes highly sensitive browser state and should be explicitly declared because it materially expands the skill's privilege surface.

Content

No source excerpt is available for this finding.

YARA rule 'info_stealer': Information stealer patterns (credential harvesting, browser data theft) [malware]

High
Category
YARA Match
Confidence
92% confidence
Finding

The YARA hit is supported by the module's actual behavior: it deliberately obtains decrypted Chrome cookies, including by launching/attaching to CDP and copying profile data to bypass profile-lock issues. While the apparent goal is service automation rather than credential theft, these are the same primitives used by information stealers and they create a real risk of browser-session compromise if misused.

Content

Scanner excerpt · src/lib/cdp-cookies.ts (reported line 6)May include surrounding context.

ts
/**
 * CDP (Chrome DevTools Protocol) cookie extraction fallback.
 *
 * When sweet-cookie can't fully decrypt Chrome cookies on Windows
 * (Chrome 127+ uses App-Bound Encryption), this module connects to
 * Chrome via its DevTools Protocol to read cookies directly — Chrome
 * itself handles decryption, so all cookies are readable.
 *
 * Flow:
 *  1. Check for an existing Chrome debugging session on port 9222
 *  2. If unavailable, launch Chrome headless with --remote-debugging-port
 *  3. Use Network.getAllCookies via WebSocket to read decrypted cookies
 *  4. Shut down headless Chrome if we launched it
 */

import { spawn, execFileSync, type ChildProcess } from "node:child_process";
import { existsSync, mkdtempSync, mkdirSync, copyFileSync, rmSync } from "node:fs";
import { homedir, tmpdir } from "node:os";
import { join } from "node

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
src/lib/cdp-cookies.ts:173