Back to skill

Security audit

Book-PDF: 书籍级PDF手册全流程

Security checks for vulnerabilities and agentic risk

Overview

The skill largely matches a PDF-book workflow, but it forces third-party branding into user documents and includes unsafe build/update scripts that should be reviewed before use.

Review or remove the default branding before generating documents, and treat the scripts as local code execution tools. Use this only in a project directory you control, avoid untrusted titles, changelog messages, or HTML fragments, and prefer pinned dependencies plus network/JavaScript restrictions during PDF rendering.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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 (6)

T01 · Skill Instruction Hijacking

Error
Location
SKILL.md:103
Finding

Mandatory third-party branding hijacks generated documents

Content
View full analysis
蒲公英
公众号「AI编程蒲公英」· B站「AI编程程序猿-蒲公英」` **尾页**(class必须是 `back-page`,带连字符): - 社交链接:B站 `https://space.bilibili.com/3493114559858979/` · 公众号「AI编程蒲公英」 ``` The default cover includes: ```html
蒲公英
公众号「AI编程蒲公英」· B站「AI编程程序猿-蒲公英」
知识星球「AI编程:从入门到精通」专属内容
``` The default back page includes: ```html
AI编程:从入门到精通
AI编程蒲公英 微信公众号
扫码关注 AI编程蒲公英
B站:AI编程程序员-蒲公英 · 公众号:AI编程蒲公英
``` ### Technical Analysis The Skill does not merely provide optional placeholders. It explicitly instructs writing agents that every generated PDF must contain a named creator identity, social-media promotion, and related promotional material. The initializer copies the branded cover and back-page templates into each new project, while the build order includes both fragments by default. This changes the output objective from generating a user-controlled publication to distributing unrelated third-party branding. It can also create misleading authorship attribution because the generated document identifies a specific creator regardless of the actual user or author. ### Attack Path 1. The agent loads the Skill to fulfill a request for a book ...[truncated 819 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
templates/update.sh:49
Finding

Changelog message injection permits arbitrary Node.js code execution

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
templates/build.js:15
Finding

Unvalidated metadata enables path traversal and HTML injection

Content
View full analysis
"$PROJECT_DIR/version.json" << EOF { "version": "1.0.0", "build": 0, "lastUpdate": "$TODAY", "title": "$TITLE" } EOF ``` The builder trusts the metadata as a filename component: ```javascript const VERSION_FILE = path.join(__dirname, 'version.json'); const versionData = JSON.parse(fs.readFileSync(VERSION_FILE, 'utf-8')); const OUTPUT_FILE = path.join(OUTPUT_DIR, `${versionData.title}-v${versionData.version}.html`); ``` It also inserts the title directly into HTML: ```javascript const html = ` ${versionData.title} ${css} ``` The PDF builder repeats the unsafe path construction: ```javascript const versionData = JSON.parse(fs.readFileSync(path.join(__dirname, 'version.json'), 'utf-8')); const HTML_FILE = path.join(__dirname, 'output', `${versionData.title}-v${versionData.version}.html`); const PDF_FILE = path.join(__dirname, 'output', `${versionData.title}-v${versionData.version}.pdf`); ``` ### Technical Analysis The title crosses three security boundaries without validation: 1. It is serialized into JSON by string interpolation rather than `JSON.stringify`. 2. It is used as part of a filesystem path without excluding separators or traversal components. 3. It is inserted into an HTML document without entity encoding. A title containing quotes or control characters can corrupt `version.json`. A metadata value containing path separators and `..` components can cause `path.join` to normalize the output path outside th ...[truncated 1165 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
templates/build-pdf.js:18
Finding

Agent-generated HTML executes in a network-enabled browser without sanitization

Content
View full analysis
v[\d.]+/g, `文档版本:v${versionData.version}`); content = content.replace(/发布时间:<\/strong>[^<]+/g, `发布时间:${versionData.lastUpdate} (build #${versionData.build})`); } fragments.push(`\n${content}`); console.log(` ✅ ${name}`); } else { missing.push(name); console.log(` ⬜ ${name} (missing, skipped)`); } } ``` The merged document is then loaded in Chromium with default JavaScript and networking behavior: ```javascript (async () => { console.log('🚀 Starting PDF generation...'); const browser = await chromium.launch(); const page = await browser.newPage(); await page.goto(`file://${HTML_FILE}`, { waitUntil: 'networkidle', timeout: 60000 }); // 等待字体和图片加载 await page.waitForTimeout(4000); ``` ### Technical Analysis The workflow expects agents to produce raw HTML fragments, but no parser or allowlist removes dangerous elements and attributes. A fragment can therefore contain scripts, event handlers, iframes, external images, stylesheets, or other active content. Playwright creates a normal browser page with JavaScript enabled and no request interception. When the local HTML file is loaded, attacker-controlled browser code can execute and make outbound requests. A malicious script can serialize the generated document and transmit it, load tracking resources, modify the final publi ...[truncated 1404 chars]
Remediation
View remediation

other

Note
Location
templates/styles.css:11
Finding

PDF rendering contacts Google Fonts by default

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
SKILL.md:17
Finding

Playwright and Chromium installation instructions are not version-pinned

Content
View full analysis
= 16 - Playwright:`npm install playwright && npx playwright install chromium` ``` The initialization script repeats the same instructions: ```bash # 前置依赖: # - Node.js >= 16 # - Playwright: npm install playwright && npx playwright install chromium ``` ```bash if ! node -e "require('playwright')" 2>/dev/null; then HAS_PLAYWRIGHT=false echo " ⚠️ 未找到 Playwright — 请运行:" echo " npm install playwright" echo " npx playwright install chromium" fi ``` ### Technical Analysis The documented installation command resolves whichever Playwright release is current at installation time. The project does not provide an exact dependency version, lockfile, package integrity policy, or verified browser artifact version. The source URL itself is the standard package-manager route, and the audit found no evidence of typosquatting or an intentionally malicious package. The risk arises from non-reproducible dependency resolution and implicit trust in the user's active npm registry and configuration. ### Attack Path 1. A user follows the dependency instructions. 2. npm resolves `playwright` through the currently configured registry without an exact version constraint. 3. The selected package and its lifecycle behavior are installed. 4. `npx playwright install chromium` downloads the browser build associated with that resolved package. 5. A compromised registry, configuration, account, or future package release could introduce unreviewed code into the build environment. ### Impact Assessment Installed npm packages execute with the privileges of the installing user, and the downloaded Chromium binary later processes project content. A supply-chain compromise could therefore affect files and data accessible ...[truncated 168 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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
Findings (19)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

声明描述的是一个端到端的“制作完整电子书/PDF 手册”系统,包含研究、内容生成、版本管理和构建等多个阶段。实际代码片段只覆盖最后一步中的一小部分:将已经存在的 HTML 文件渲染成 PDF。虽然代码中读取 version.json 可视为与版本命名有关,但并不能支撑声明中的完整语义化版本管理、调研、多 agent 写作等核心能力。因此,这段代码的实际行为明显比声明狭窄,且其主要目的更接近“将已生成 HTML 导出为 PDF”的构建脚本,而不是“从零开始生成书籍级 PDF 手册”的完整技能。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

声明描述的是一个端到端的“从研究到写作到 PDF 产出”的完整书籍生成系统;但实际代码片段只实现了其中很小的一部分,而且还是 HTML 合并步骤。代码没有任何网络调研、内容生成、任务编排、多 agent 协作、Markdown/文稿处理、Playwright 调用、浏览器渲染或 PDF 输出逻辑。它确实涉及版本信息注入和片段化架构,这与声明中的“模块化HTML片段架构 + 语义化版本管理”部分相符,但整体主功能与声明相比明显更窄,且核心承诺的 PDF 生成与内容生产能力均未在代码中体现。因此该描述不能准确代表这段代码的实际行为。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

声明描述的是一个端到端的书籍级PDF手册生成技能,重点在调研、规划、多Agent写作、合并构建与完整手册产出。当前提供的代码片段实际是一个辅助性的发布脚本,主要负责版本号管理、变更日志更新、触发HTML/PDF构建以及备份生成物。虽然其中涉及语义化版本管理,并且会生成HTML/PDF,这与声明中的一小部分流程相关,但它并不实现声明中的核心能力,尤其缺少调研、内容生成、多Agent协作和完整手册编写逻辑。因此代码实际行为与技能宣称的主要用途存在明显偏差,应判定为不匹配。

Content

No source excerpt is available for this finding.

Vague Triggers

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The trigger phrases include broad everyday expressions like '做一本书' and similar generic requests, which can cause the skill to activate in contexts the user did not intend. Over-broad activation increases the chance an agent enters a shell-enabled workflow, creates files, or runs build steps unnecessarily or without clear consent.

Content

No source excerpt is available for this finding.

Hidden Instructions

High
Category
Prompt Injection
Confidence
70% confidence
Finding

Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Content

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

§0N 标题

English Title

概述

```

Hidden Instructions

High
Category
Prompt Injection
Confidence
70% confidence
Finding

Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Content

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

§0N 标题

English Title

概述

```

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill instructs the agent to run shell commands such as bash scripts, node, npm, npx, and update scripts, but it does not declare any explicit tool scope or allowed-tools boundary. This weakens least-privilege controls and can let a broadly empowered agent execute filesystem or process actions beyond what users expect.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
91% confidence
Finding

Using 'npx playwright' without pinning a specific version makes the build depend on whatever package version is resolved at runtime. This introduces supply-chain and reproducibility risk, especially because the command installs and executes code from the package ecosystem.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The file is written as mandatory guidance for a writing agent and begins with Chinese-only instructions, including '写作agent在编写HTML片段时必读此文件'. There is no indication that the agent may adapt to the user's preferred language or locale, which creates a language policy issue under the natural-language policy category.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

L120-L122 的封面模板明确加入“蒲公英”“AI编程蒲公英”等署名/品牌信息,而 L222 写明“封面不加个人署名/水印”。这不是单纯遗漏,而是文档内的明确规范与示例模板直接矛盾,可能误导写作 agent 生成与规范不一致的封面。

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The template hardcodes Chinese headings and body text such as the title, metadata labels, author block, and disclaimer, which implies the generated cover will be produced in Chinese by default. This is a natural-language locale constraint, and the file does not offer a language choice or document that the template is intended only for a Chinese-language or region-specific use case.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

The build script explicitly formats time using the zh-CN locale, which enforces a specific language/locale behavior in the generated output. The file also contains Chinese-only natural-language strings, and there is no indication that users can opt into another locale or that the constraint is documented as region-specific.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

This HTML fragment presents all user-visible text in Chinese, including titles, labels, and footer text, with no indication that the language is configurable or optional. The policy explicitly calls for flagging language or locale constraints when a skill forces a specific language without user opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

This stylesheet includes multiple Chinese natural-language strings in comments and generated content, such as labels for tips and warnings, which indicates the rendered output is fixed to Chinese. The file does not offer any language selection or document that the template is intentionally restricted to a Chinese-language context, which may violate language/locale policy requirements.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The stylesheet imports Google Fonts from an external URL, which causes network access during rendering. In a PDF-generation workflow, this can leak metadata such as IP address, timing, and document-generation activity to a third party, and it can also reduce build determinism or fail in offline/restricted environments.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

This shell script's natural-language content, including usage instructions and status/error messages, is entirely in Chinese. Under the policy, a forced language without user opt-in is a natural-language policy violation unless the locale restriction is explicitly documented and justified, which is not present here.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.