Back to skill

Security audit

Story Long Scan

Security checks for vulnerabilities and agentic risk

Overview

This skill’s web-novel ranking workflow is mostly coherent, but its browser automation helper contains an unsafe shell command pattern that could let hostile page content run local commands.

Review before installing or running. The scraping purpose is legitimate and disclosed, but run it only in an isolated workspace with a dedicated browser profile, avoid unrelated logged-in sessions, and fix the CDP helper to use execFileSync/spawnSync with argument arrays plus strict HTTPS host allowlists before trusting scraped pages.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/cdp-utils.js:23
Finding

Shell Command Injection Through Unsafe CDP Command Construction

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() || ""; } } ``` Relevant page-derived input in `scripts/fanqie-rank-scraper.js`: ```js function buildCategoriesJS(prefix) { return `JSON.stringify((function(){ var prefix=${JSON.stringify(prefix)}; var out=[];var seen={}; Array.from(document.querySelectorAll('a')).forEach(function(a){ var href=a.getAttribute('href')||''; if(href.indexOf(prefix)===-1)return; var name=(a.innerText||a.textContent||'').trim(); if(!name)return; if(seen[href])return;seen[href]=1; out.push({name:name,href:href}); }); return out; })())`; } ``` ```js ab(PORT, "open", `https://fanqienovel.com${cat.href}`); ``` Relevant page-derived input in `scripts/qidian-rank-scraper.js`: ```js var href=a.getAttribute('href')||a.href||''; var url=href?(href.indexOf('http')===0?href:'https:'+href):''; ``` ```js ab(port, "open", b.url); ``` ### Technical Analysis The shared `ab()` helper creates one command string and passes it to `execSync()`, causing Node.js to invoke a system shell. Each argument is surrounded by double quotes, but only literal double-quote characters are escaped. Double quoting does not suppress all shell evaluation. In common shells, command substitutions such as `$(command)` and backtick expressions are still evaluated inside double-quoted strings. Consequently, an argument containing shell substitution syntax ca ...[truncated 2587 chars]
Remediation
View remediation
65535) { throw new Error("Invalid CDP port"); } try { return execFileSync( "agent-browser", ["--cdp", String(parsedPort), ...args.map(String)], { encoding: "utf-8", timeout: 20000, stdio: ["pipe", "pipe", "pipe"], } ).trim(); } catch (e) { return typeof e.stdout === "string" ? e.stdout.trim() : ""; } } ``` This passes arguments directly to the executable without asking a shell to parse them. 2. **Validate every navigation URL** Before calling `ab(port, "open", value)`, parse the value with `new URL()` and enforce: - The protocol must be `https:`. - The hostname must exactly match an approved platform host. - Username and password components must be empty. - Unexpected ports must be rejected. - Relative links must be resolved against a fixed trusted origin. Example: ```js function trustedUrl(value, base, allowedHosts) { const url = new URL(value, base); if (url.protocol !== "https:") { throw new Error("Non-HTTPS URL rejected"); } if (!allowedHosts.includes(url.hostname)) { throw new Error(`Untrusted hostname: ${url.hostname}`); } if (url.username || url.password || url.port) { throw new Error("URL credentials or custom ports are not allowed"); } return url.toString(); } ``` 3. **Apply platform-specific hostname allowlists** Use narrow allowlists such as: - Fanqie: `fanqienovel.com` - Qidian PC: `www.qidian.com` - Qidian mobile: `m.qidian.com` - Qimao: `www.qimao.com` - JJWXC: `www.jjwxc.net` - Ciweimao: `www.ciweimao.com` Include additional subdomains only when they are verified as necessary. 4. * ...[truncated 658 chars]
Vulnerability Patterns
  • 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
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (31)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The declared purpose frames the skill as benign market analysis, but the body instructs execution-oriented behaviors including browser/CDP automation, running local scripts, command invocation, and page-level JavaScript evaluation. This mismatch is dangerous because users and policy layers may approve the skill for 'analysis' while it actually has active web-scraping and automation behavior with a larger attack surface.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared purpose frames the skill as benign market analysis, but the body instructs execution-oriented behaviors including browser/CDP automation, running local scripts, command invocation, and page-level JavaScript evaluation. This mismatch is dangerous because users and policy layers may approve the skill for 'analysis' while it actually has active web-scraping and automation behavior with a larger attack surface.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The declared purpose frames the skill as benign market analysis, but the body instructs execution-oriented behaviors including browser/CDP automation, running local scripts, command invocation, and page-level JavaScript evaluation. This mismatch is dangerous because users and policy layers may approve the skill for 'analysis' while it actually has active web-scraping and automation behavior with a larger attack surface.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The declared purpose frames the skill as benign market analysis, but the body instructs execution-oriented behaviors including browser/CDP automation, running local scripts, command invocation, and page-level JavaScript evaluation. This mismatch is dangerous because users and policy layers may approve the skill for 'analysis' while it actually has active web-scraping and automation behavior with a larger attack surface.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared purpose frames the skill as benign market analysis, but the body instructs execution-oriented behaviors including browser/CDP automation, running local scripts, command invocation, and page-level JavaScript evaluation. This mismatch is dangerous because users and policy layers may approve the skill for 'analysis' while it actually has active web-scraping and automation behavior with a larger attack surface.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The declared purpose frames the skill as benign market analysis, but the body instructs execution-oriented behaviors including browser/CDP automation, running local scripts, command invocation, and page-level JavaScript evaluation. This mismatch is dangerous because users and policy layers may approve the skill for 'analysis' while it actually has active web-scraping and automation behavior with a larger attack surface.

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

md
1. 选择平台脚本;起点直接运行 `scripts/qidian-rank-scraper.js`,番茄/七猫/晋江等按需启动 browser-cdp

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
1. 选择平台脚本;起点直接运行 `scripts/qidian-rank-scraper.js`,番茄/七猫/晋江等按需启动 browser-cdp

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
1. 选择平台脚本;起点直接运行 `scripts/qidian-rank-scraper.js`,番茄/七猫/晋江等按需启动 browser-cdp

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
nk/{channel}_{type}_{cat_id}`,channel 0=女频/1=男频,type 1=新书榜/2=阅读榜。番茄列表页有字体反爬,须用 `scripts/fanqie-rank-scraper.js` 从详情页多策略解码书名/作者/题材/评分/标签/简介,配合 browser-cdp 使用:

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
nk/{channel}_{type}_{cat_id}`,channel 0=女频/1=男频,type 1=新书榜/2=阅读榜。番茄列表页有字体反爬,须用 `scripts/fanqie-rank-scraper.js` 从详情页多策略解码书名/作者/题材/评分/标签/简介,配合 browser-cdp 使用:

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
nk/{channel}_{type}_{cat_id}`,channel 0=女频/1=男频,type 1=新书榜/2=阅读榜。番茄列表页有字体反爬,须用 `scripts/fanqie-rank-scraper.js` 从详情页多策略解码书名/作者/题材/评分/标签/简介,配合 browser-cdp 使用:

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
nk/{channel}_{type}_{cat_id}`,channel 0=女频/1=男频,type 1=新书榜/2=阅读榜。番茄列表页有字体反爬,须用 `scripts/fanqie-rank-scraper.js` 从详情页多策略解码书名/作者/题材/评分/标签/简介,配合 browser-cdp 使用:

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
**晋江采集目标**(`scripts/jjwxc-rank-scraper.js`,默认列表 + 详情两步走):

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
**晋江采集目标**(`scripts/jjwxc-rank-scraper.js`,默认列表 + 详情两步走):

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
**晋江采集目标**(`scripts/jjwxc-rank-scraper.js`,默认列表 + 详情两步走):

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
**晋江采集目标**(`scripts/jjwxc-rank-scraper.js`,默认列表 + 详情两步走):

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
**晋江采集目标**(`scripts/jjwxc-rank-scraper.js`,默认列表 + 详情两步走):

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
**晋江采集目标**(`scripts/jjwxc-rank-scraper.js`,默认列表 + 详情两步走):

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| [scripts/qimao-rank-scraper.js](scripts/qimao-rank-scraper.js) | 七猫榜单采集(大热/新书/完结等),tab 切换(失败重试)+滚动加载,按 bookId 取书名回填作品页链接,带连通性自检+链接/热度命中率标注 |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| [scripts/ciweimao-rank-scraper.js](scripts/ciweimao-rank-scraper.js) | 刺猬猫榜单采集(点击/收藏/月票等),单页 9 榜提取,按 bookId 归一书名回填作品页链接,带连通性自检+空结果重试+链接命中率标注 |

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill clearly directs the agent to perform network scraping and optionally control a browser/CDP, but it declares no explicit tool scope or permission boundaries. That creates an authorization gap where a caller or runtime may permit broader-than-expected external access, increasing the chance of unintended web requests, browser automation, or data collection beyond what users anticipated.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger phrases include broad natural-language expressions such as '长篇什么火' and '起点排行', which can cause accidental invocation in normal conversation. In a skill that can initiate network scraping, browser automation, and local file creation, unintended triggering raises the risk of unplanned external access and side effects.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The title and descriptive content are presented entirely in Chinese, and the file does not indicate that language use is optional or limited to a specific regional audience. Under the stated policy, forcing a specific language without user opt-in is a natural-language locale violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

The entire skill content is written as a prescriptive guide for operating on Chinese web-fiction platforms and assumes Chinese-language usage throughout, but it does not state that this is a China-specific or Chinese-language-only reference. Under the policy, forcing a specific language or locale without user opt-in or explicit justification is a natural-language policy concern.

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