Back to skill

Security audit

Awesome Deck Pdf Check

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it says, but its PDF exporter runs user-selected HTML in Chromium with the browser sandbox disabled and has under-scoped install and temp-file risks users should review.

Install only if you are comfortable reviewing the exporter and running it on trusted HTML. Avoid rendering HTML from untrusted sources, prefer pinned dependencies and a lockfile, avoid sudo unless an administrator approves it, and run the exporter in an isolated workspace or container because it disables Chromium sandboxing and deletes fixed temporary paths named _pdf_pages and _slides.html.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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

Error
Location
scripts/export_pdf.js:109
Finding
Chromium Sandbox Disabled While Rendering User-Selectable HTML## Vulnerability Details **File Location**: `scripts/export_pdf.js`, lines 109–146 **Vulnerability Type**: Unsafe browser security configuration **Risk Level**: High ### Vulnerable Code ```javascript return puppeteer.launch({ headless: true, executablePath, args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage'], }); ``` The resulting browser instance later loads a user-selectable HTML file: ```javascript const page = await browser.newPage(); await page.setViewport({ width: W, height: H, deviceScaleFactor: 2 }); const filePath = path.resolve(process.cwd(), HTML_FILE); await page.goto(`file://${filePath}`, { waitUntil: 'networkidle0' }); ``` ### Technical Analysis The exporter explicitly disables both principal Chromium sandbox mechanisms through `--no-sandbox` and `--disable-setuid-sandbox`. These flags are not required for the declared task of rendering HTML slides under a properly configured, unprivileged environment. The input path comes from `process.argv[2]`, allowing the user or an invoking process to select the HTML document rendered by Chromium. JavaScript remains enabled, and no request interception prevents the document from loading remote scripts, images, frames, or other resources. Although browser JavaScript does not inherently receive unrestricted filesystem access, disabling the Chromium sandbox removes an important containment boundary. If malicious HTML exercises a Chromium vulnerability, exploitation can occur with the operating-system privileges of the Node.js process rather than being constrained by the browser sandbox. ### Attack Path 1. An attacker supplies, modifies, or convinces a user to render a malicious HTML slide deck. 2. The user invokes `node export_pdf.js malicious.html`. 3. The script starts Chromium with its sandbox explicitly disabled. 4. Chromium loads the attacker-controlled document with JavaScript enabled. 5. The document may conta ...[truncated 829 chars]
Remediation
## Remediation Suggestions 1. Remove `--no-sandbox` and `--disable-setuid-sandbox`. 2. Run Chromium as a dedicated, unprivileged user with a writable profile and functioning browser sandbox. 3. If the deployment environment cannot support Chromium sandboxing, run the exporter inside a hardened container or virtual machine with: - No sensitive host-directory mounts. - A read-only root filesystem where practical. - Dropped Linux capabilities. - Resource and process limits. - No host network access unless explicitly required. 4. Disable JavaScript with `page.setJavaScriptEnabled(false)` when generated decks do not require scripts. 5. Add request interception and allow only required `file:` resources. Block `http:`, `https:`, `ws:`, and `wss:` requests by default during PDF export. 6. Resolve and validate the HTML path against an explicitly permitted project directory. 7. Keep Chromium and Puppeteer pinned and promptly updated for browser security fixes.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/export_pdf.js:158
Finding
Predictable Temporary Paths Permit Data Loss and Symlink Attacks## Vulnerability Details **File Location**: `scripts/export_pdf.js`, lines 158–219 **Vulnerability Type**: Unsafe temporary-file and directory handling **Risk Level**: Medium ### Vulnerable Code ```javascript const imgDir = path.resolve(process.cwd(), '_pdf_pages'); if (fs.existsSync(imgDir)) fs.rmSync(imgDir, { recursive: true }); fs.mkdirSync(imgDir); ``` The script also creates, overwrites, and deletes another fixed path: ```javascript const tmpHtml = path.resolve(process.cwd(), '_slides.html'); fs.writeFileSync(tmpHtml, `<!DOCTYPE html><html><head><meta charset="utf-8"><style>` + `*{margin:0;padding:0;box-sizing:border-box}body{background:#000}` + `@media print{@page{size:${W}px ${H}px;margin:0}body{-webkit-print-color-adjust:exact;print-color-adjust:exact}}` + `</style></head><body>${slides}</body></html>` ); await overlayPage.goto(`file://${tmpHtml}`, { waitUntil: 'networkidle0' }); await new Promise(r => setTimeout(r, 800)); await overlayPage.pdf({ path: path.resolve(process.cwd(), OUT_FILE), width: `${W}px`, height: `${H}px`, printBackground: true, margin: { top: 0, right: 0, bottom: 0, left: 0 } }); await browser.close(); fs.rmSync(imgDir, { recursive: true }); fs.unlinkSync(tmpHtml); ``` ### Technical Analysis The exporter uses the fixed names `_pdf_pages` and `_slides.html` in the current working directory. It does not verify that these paths were created by the current process, are ordinary files or directories, or are not symbolic links. Before rendering, `_pdf_pages` is recursively deleted if it already exists. This can destroy legitimate user data occupying that path. In a shared or attacker-writable working directory, predictable names also enable race conditions and symbolic-link manipulation around file creation, overwrite, and cleanup. The fixed `_slides.html` path is overwritten without e ...[truncated 1520 chars]
Remediation
## Remediation Suggestions 1. Create a unique private temporary directory with `fs.mkdtempSync(path.join(os.tmpdir(), 'html-ppt-to-pdf-'))`. 2. Store all intermediate HTML and PNG files inside that unique directory. 3. Create temporary files using exclusive flags such as `flag: 'wx'` where applicable. 4. Before destructive operations, use `fs.lstatSync()` and reject symbolic links or unexpected filesystem object types. 5. Track only paths created by the current execution and never recursively remove a pre-existing project path. 6. Place cleanup in a `try`/`finally` block so failures do not leave sensitive intermediate files behind. 7. Generate the output PDF separately from temporary files and avoid overwriting an existing output unless the user explicitly permits it. 8. Prevent concurrent runs from sharing temporary resources by using per-process random names.

T08 · Insecure Dependencies

Warning
Location
SKILL.md:51
Finding
Unpinned Dependencies and Mutable Installation Commands## Vulnerability Details **File Location**: `SKILL.md`, lines 51–68; also present in `README.md`, lines 49–51, and `references/install.md`, lines 60–97 **Vulnerability Type**: Unpinned third-party executable dependencies **Risk Level**: Medium ### Vulnerable Code ```bash # Option A: skip Chromium download, install separately npm install puppeteer --ignore-scripts npx puppeteer browsers install chrome # Option B: use puppeteer-core (no bundled Chrome download) npm install puppeteer-core # Option C: install system Chrome first, then run script # macOS: brew install --cask google-chrome # Linux: sudo apt install chromium-browser npm install puppeteer-core ``` Other project instructions similarly recommend mutable package installations: ```bash npm install puppeteer pip install python-pptx ``` ### Technical Analysis The installation instructions retrieve unspecified current versions of Puppeteer, Puppeteer Core, Python PPTX, Chromium, and related components. The project provides no lockfile, exact version constraints, cryptographic hashes, or registry restrictions. `npm install puppeteer` may execute package lifecycle scripts and download a browser binary. The `npx puppeteer` command may resolve and execute package code from the configured registry. The Python command also resolves a mutable dependency set without hashes. These actions expand the Skill's effective codebase beyond the audited repository. The identified package names appear legitimate, and the audit found no evidence of intentional typosquatting or a malicious package. The risk arises from non-reproducible installation and reliance on mutable upstream artifacts rather than from a confirmed compromised dependency. ### Attack Path 1. A user follows the documented installation commands. 2. The package manager resolves the latest available package and transitive dependencies from its configured registry. 3. A compromised registry account, ...[truncated 1198 chars]
Remediation
## Remediation Suggestions 1. Pin exact Puppeteer, Puppeteer Core, and Python PPTX versions that have been tested and reviewed. 2. Commit an npm lockfile containing integrity metadata and instruct users to run `npm ci` rather than an unconstrained `npm install`. 3. Use a Python requirements file with exact versions and hashes, installed with `pip install --require-hashes -r requirements.txt`. 4. Avoid unpinned `npx` execution. Invoke a locally installed, lockfile-controlled executable instead. 5. Document approved package registries and recommend disabling unexpected registry overrides. 6. Verify downloaded browser artifacts through the package manager's supported integrity controls. 7. Add automated dependency vulnerability and provenance checks to the release process. 8. Separate privileged operating-system dependency installation from normal Skill execution and require explicit user approval before administrative commands are run.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (21)

Ae1

High
Category
analysis-evasion
Content
**`export_pdf.js` auto-detects Chrome in this order:**
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
**`export_pdf.js` auto-detects Chrome in this order:**
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
**`export_pdf.js` auto-detects Chrome in this order:**
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
**`export_pdf.js` auto-detects Chrome in this order:**
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
**`export_pdf.js` auto-detects Chrome in this order:**
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
**`export_pdf.js` auto-detects Chrome in this order:**
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger phrases are very broad (`make me a nice PPT`, `build a deck`, `generate presentation`) and can cause the skill to activate in contexts the user did not specifically intend. In agent systems, overbroad activation increases the chance of unexpected external fetching, file handling, or command guidance being surfaced without adequate user awareness.

Rp1

Medium
Category
MCP Rug Pull
Confidence
89% confidence
Finding
The skill instructs use of `npx puppeteer`, which resolves and executes a package version that is not pinned. That creates a supply-chain risk: a future compromised or incompatible release could be fetched and run at execution time, especially in automated agent environments where users may follow the instruction verbatim.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
# Option C: install system Chrome first, then run script
# macOS: brew install --cask google-chrome
# Linux: sudo apt install chromium-browser
npm install puppeteer-core
```
**Do NOT fall back to wkhtmltopdf, pdfkit, weasyprint, or any other tool.**
Confidence
87% confidence
Finding
The skill includes guidance to run `sudo apt install chromium-browser`, which normalizes privileged command execution during setup. In an agent or user-followed workflow, encouraging `sudo` increases risk because it can lead to unnecessary elevation and system modification, especially when paired with package-install instructions users may not independently validate.

Natural-Language Policy Violations

Medium
Confidence
89% confidence
Finding
The instructions mandate appending Chinese fallbacks and later troubleshooting specifically directs adding 'PingFang SC', which imposes a locale-specific typography choice without offering user choice or documenting why this locale preference is required. This can violate language/locale policy when applied universally rather than conditionally based on user content needs.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The file title and instructions are written entirely in Chinese and direct users to fill the template in that locale, without offering any language or locale choice. This can violate language/locale policy when the skill is expected to be usable across user preferences unless the restriction is explicitly justified.

Skill Enumeration

Medium
Category
Agent Snooping
Content
```
3. Reference it in your project's `CLAUDE.md` or system prompt:
   ```
   Skills path: ~/.claude/skills/html-ppt-to-pdf/SKILL.md
   ```

---
Confidence
85% confidence
Finding
Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Skill Enumeration

Medium
Category
Agent Snooping
Content
```
3. Reference it in your project's `CLAUDE.md` or system prompt:
   ```
   Skills path: ~/.claude/skills/html-ppt-to-pdf/SKILL.md
   ```

---
Confidence
80% confidence
Finding
Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Skill Enumeration

Medium
Category
Agent Snooping
Content
```
3. Reference it in your project's `CLAUDE.md` or system prompt:
   ```
   Skills path: ~/.claude/skills/html-ppt-to-pdf/SKILL.md
   ```

---
Confidence
80% confidence
Finding
Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
### Linux
```bash
# Puppeteer may need extra Chrome deps
sudo apt-get install -y libx11-xcb1 libxcomposite1 libxcursor1 libxdamage1 \
  libxi6 libxtst6 libnss3 libcups2 libxss1 libxrandr2 libasound2 libatk1.0-0 \
  libgtk-3-0
npm install puppeteer
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

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.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
❌ No Chrome/Chromium found. Please install one of the following:

  macOS:   brew install --cask google-chrome
  Linux:   sudo apt install chromium-browser
  npm:     npm install puppeteer   (downloads bundled Chromium)
`);
    process.exit(1);
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The script opens a user-supplied local HTML file in a real Chrome instance via a file:// URL and waits for network idle, which allows any embedded JavaScript and remote subresources in that HTML to execute during export. In this skill context, that means exporting an untrusted deck can trigger network requests, local file interaction behaviors available to the browser context, and unintended code execution within the browser session without any warning to the operator.

Missing User Warnings

Low
Confidence
82% confidence
Finding
The description advertises website URL style cloning but does not warn that analyzing external URLs may involve fetching remote content or taking browser screenshots. This reduces user transparency and can lead to unexpected network access or privacy issues when the skill is invoked.

Natural-Language Policy Violations

Low
Confidence
84% confidence
Finding
The troubleshooting table instructs users to add 'PingFang SC' when Chinese text renders poorly, but the broader document also frames this fallback as a standard requirement rather than a user-selected locale option. This embeds a locale-specific preference into the workflow without clear opt-in or documented regional justification.

Natural-Language Policy Violations

Low
Confidence
89% confidence
Finding
The document consistently presents all user-facing instructions in Chinese, but it does not indicate that the skill is region-specific or provide any opt-in or alternative language path. Under the policy, forcing a specific language without user choice can be a natural-language policy violation.

Static analysis

Detected: suspicious.prompt_injection_instructions

Prompt-injection style instruction pattern detected.

Warn
Code
suspicious.prompt_injection_instructions
Location
references/install.md:24