Back to skill

Security audit

Story Short Scan

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly a story-market scraping assistant, but one scraper reuses a logged-in admin browser session, extracts an Admin-Token cookie, and calls management APIs, which needs review before use.

Install only if you are authorized to access and export the management catalog data it collects. Prefer using the public scraping modes; avoid running the Heiyan admin scraper from a personal or high-privilege admin Chrome profile, and treat any generated reports as potentially sensitive internal data.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (3)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/cdp-utils.js:21
Finding

Administrator Bearer Token Exposed Through Process Command-Line Arguments

Content
View full analysis
`"${a.replace(/"/g, '\\"')}"`).join(" "); try { return execSync(`agent-browser --cdp ${port} ${cmd}`, { encoding: "utf-8", timeout: 20000, stdio: ["pipe", "pipe", "pipe"], }).trim(); } catch (e) { return e.stdout?.trim() || ""; } } ``` The credential reaches this function through browser-evaluation JavaScript constructed as follows: ```js function fetchBookList(port, token, pageNum) { const t = safeStr(token); const js = "fetch(" + safeStr(API_BASE + "/manage/book/list") + "," + "{method:'POST'," + "headers:{" + "'Content-Type':'application/x-www-form-urlencoded'," + "'Authorization':'Bearer '+" + t + "}," + "body:new URLSearchParams({pageNum:" + safeStr(pageNum) + ",pageSize:" + safeStr(PAGE_SIZE) + ",language:'zh_TW'})" + "}).then(function(r){return r.json()})"; return evalJSON(port, js); } function fetchBookDetail(port, token, bookId) { const t = safeStr(token); const js = "fetch(" + safeStr(API_BASE + "/manage/book/" + encodeURIComponent(bookId)) + "," + "{headers:{'Authorization':'Bearer '+" + t + "}}" + ").then(function(r){return r.json()})"; return evalJSON(port, js); } ``` ### Technical Analysis The Black Rock scraper reads an `Admin-Token` cookie and embeds its value in JavaScript containing an HTTP `Authorization` header. This entire JavaScript string is then passed to `agent-browser` by constructing a shell command. Consequently, the raw bearer token can appear in the command-line arguments of the shell and the `agent-browser` process while the request is running. Depending on operating-system process visibil ...[truncated 1523 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/cdp-utils.js:21
Finding

Shell Command Injection in the Shared CDP Command Wrapper

Content
View full analysis
`"${a.replace(/"/g, '\\"')}"`).join(" "); try { return execSync(`agent-browser --cdp ${port} ${cmd}`, { encoding: "utf-8", timeout: 20000, stdio: ["pipe", "pipe", "pipe"], }).trim(); } catch (e) { return e.stdout?.trim() || ""; } } ``` The token value that can reach the wrapper is obtained from the active page: ```js function getToken(port) { const js = "JSON.stringify((()=>{" + "var m=document.cookie.match(/Admin-Token=([^;]+)/);" + "return m?m[1]:''" + "})())"; return evalJSON(port, js) || ""; } ``` ### Technical Analysis The wrapper attempts to quote each argument by enclosing it in double quotes and escaping embedded double-quote characters. This is not sufficient shell escaping. Inside shell double quotes, command substitutions such as `$(command)` and backtick substitutions remain active. Therefore, an argument containing shell substitution syntax can cause the shell invoked by `execSync()` to execute additional commands. In the Black Rock flow, the value of `Admin-Token` is embedded into a JavaScript argument passed through this wrapper. `safeStr()` protects the syntax of the generated JavaScript using `JSON.stringify`, but it does not sanitize values for shell interpretation. The script also does not validate that the final browser host is `manage.zhangwenpindu.cn` before extracting the cookie. Exploitation requires an attacker to influence an argument reaching `ab()`. In the audited code, the most relevant path is a maliciously crafted readable token supplied through a compromised or attacker-controlled browser context. The vulnerability is therefore conditional but technically exploitable. ### Attack Path 1. The management origin or active browser cont ...[truncated 1241 chars]
Remediation
View remediation
65535) { throw new Error("Invalid CDP port"); } ``` 3. Treat all browser-derived values, including cookies and page content, as untrusted data. 4. Validate the active host before reading credentials: ```js const probe = probePage(PORT); if (!probe || probe.host !== "manage.zhangwenpindu.cn") { throw new Error("Unexpected browser origin"); } ``` 5. Keep JavaScript code static where possible. Pass ordinary data through structured CDP parameters rather than concatenating it into executable source text. 6. Add tests covering shell metacharacters, including `$()`, backticks, backslashes, quotes, semicolons, and newlines, to ensure they are transmitted only as literal argument data. ]]>

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/heiyan-booklist-scraper.js:37
Finding

Privileged Management API Access Exceeds the Minimum Scope Required for Public Market Scanning

Content
View full analysis
{" + "var m=document.cookie.match(/Admin-Token=([^;]+)/);" + "return m?m[1]:''" + "})())"; return evalJSON(port, js) || ""; } ``` It then uses that token against management API endpoints: ```js function fetchBookList(port, token, pageNum) { const t = safeStr(token); const js = "fetch(" + safeStr(API_BASE + "/manage/book/list") + "," + "{method:'POST'," + "headers:{" + "'Content-Type':'application/x-www-form-urlencoded'," + "'Authorization':'Bearer '+" + t + "}," + "body:new URLSearchParams({pageNum:" + safeStr(pageNum) + ",pageSize:" + safeStr(PAGE_SIZE) + ",language:'zh_TW'})" + "}).then(function(r){return r.json()})"; return evalJSON(port, js); } function fetchBookDetail(port, token, bookId) { const t = safeStr(token); const js = "fetch(" + safeStr(API_BASE + "/manage/book/" + encodeURIComponent(bookId)) + "," + "{headers:{'Authorization':'Bearer '+" + t + "}}" + ").then(function(r){return r.json()})"; return evalJSON(port, js); } ``` Optional detail collection retrieves additional fields for every filtered book: ```js if (DETAIL && filtered.length) { console.log(` 获取 ${filtered.length} 本详情...`); for (let i = 0; i < filtered.length; i++) { try { sleep(500); const detail = fetchBookDetail(PORT, token, filtered[i].id); if (detail?.data) { filtered[i].tags = detail.data.tags || []; filtered[i].description = detail.data.description || ""; filtered[i].chapterCount = detail.data.chapterCount || 0; } if ((i + 1) % 10 === ...[truncated 2400 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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 (10)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill instructs operators to reuse a logged-in Chrome session, extract a Bearer token from cookies, and call management-side APIs on admin domains. This goes well beyond public 'hot short-story ranking' analysis and crosses into authenticated backend data access and export, which could expose nonpublic data or facilitate unauthorized scraping under a user's credentials.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill instructs operators to reuse a logged-in Chrome session, extract a Bearer token from cookies, and call management-side APIs on admin domains. This goes well beyond public 'hot short-story ranking' analysis and crosses into authenticated backend data access and export, which could expose nonpublic data or facilitate unauthorized scraping under a user's credentials.

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 215)May include surrounding context.

md
| [scripts/dz-browse-scraper.js](scripts/dz-browse-scraper.js) | 点众短篇采集(男频/女频),按 bookId 聚合 anchor 解出书名/评分/简介/作品页(避免把 UI 文字或简介误当书名),带连通性自检+书名解析率质量门,配合 browser-cd

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script explicitly requires a manual login to a management backend and then uses that authenticated context to access non-public backend APIs. That materially exceeds the declared skill purpose of scanning public short-story trends and creates unauthorized access/data-collection risk through privileged admin surfaces.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The code extracts an Admin-Token from browser cookies and reuses it as a Bearer token for API calls, effectively turning the user's logged-in admin session into a credential source. This is dangerous because it enables privileged backend access and data extraction without a dedicated authorization flow, and such token harvesting is unnecessary for a public trend-scanning skill.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill directs use of browser automation, WebFetch, and external platform access, but does not declare any explicit tool scope or permission boundary. That makes the skill's effective capabilities broader and less auditable than its manifest suggests, increasing the chance of unintended network access or misuse in environments that rely on declared scopes for policy enforcement.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

Reusing a logged-in browser session and extracting a Bearer token from cookies can silently leverage the user's authenticated state to access protected resources. Without a clear warning and explicit consent flow, this creates a significant risk of credential misuse, privacy violations, and access to data the user did not intend to expose through the skill.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script silently reads an authentication token from cookies and sends it in backend API requests, but the user is not given a clear warning that their authenticated admin session is being repurposed as an API credential. This reduces informed consent, obscures credential handling, and increases the risk of accidental misuse of privileged sessions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

The skill tells the agent to fetch live data via browser automation and WebFetch but does not clearly warn users that external requests will be made and platform content may be transmitted or processed. While ordinary for a scanning skill, the lack of transparency weakens informed consent and can surprise users in restricted or privacy-sensitive environments.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

The request body hardcodes language:'zh_TW', which imposes a specific locale behavior regardless of user preference. There is no visible opt-in, configurability, or explanation that this is required for a region-specific or compliance-driven purpose.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/cdp-utils.js:26