Back to skill

Security audit

CC Design

Security checks for vulnerabilities and agentic risk

Overview

This design skill is mostly coherent, but one export helper can unintentionally bundle sensitive local files if an HTML file contains unsafe asset paths.

Review before installing. Use the export tools only on HTML you created or trust, inspect asset paths before creating self-contained HTML, and avoid packaging projects that contain secrets nearby. Prefer pinned dependencies, a lockfile, and a sandboxed workspace for exports involving third-party HTML or sensitive project files.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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 (3)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/super_inline_html.js:15
Finding
Arbitrary Local File Inclusion in Self-Contained HTML Output<![CDATA[ ## Vulnerability Details **File Location**: `scripts/super_inline_html.js:15-18, 34-40, 45-51, 57-63, 70-76, 82-90` **Vulnerability Type**: Unrestricted local-file read through path traversal and absolute asset paths **Risk Level**: High ### Vulnerable Code ```js function fileToDataUrl(filePath, mimeType) { const data = fs.readFileSync(filePath); return `data:${mimeType};base64,${data.toString('base64')}`; } // Inline <link rel="stylesheet" href="..."> result = result.replace(/<link\s+[^>]*rel=["']stylesheet["'][^>]*href=["']([^"']+)["'][^>]*\/?>/gi, (match, href) => { if (href.startsWith('http') || href.startsWith('data:')) return match; const filePath = path.resolve(baseDir, href); if (!fs.existsSync(filePath)) return match; const css = fs.readFileSync(filePath, 'utf-8'); return `<style>\n${css}\n</style>`; }); // Inline <script src="..."> result = result.replace(/<script\s+[^>]*src=["']([^"']+)["'][^>]*><\/script>/gi, (match, href) => { if (href.startsWith('http') || href.startsWith('data:')) return match; if (href.includes('unpkg.com') || href.includes('cdn.')) return match; const filePath = path.resolve(baseDir, href); if (!fs.existsSync(filePath)) return match; const js = fs.readFileSync(filePath, 'utf-8'); return `<script>\n${js}\n</script>`; }); // Inline <img src="..."> result = result.replace(/<img\s+[^>]*src=["']([^"']+)["']/gi, (match, src) => { if (src.startsWith('http') || src.startsWith('data:')) return match; const filePath = path.resolve(baseDir, src); if (!fs.existsSync(filePath)) return match; const ext = path.extname(filePath); const dataUrl = fileToDataUrl(filePath, getMimeType(ext)); return match.replace(src, dataUrl); }); // Process <style> blocks result = result.replace(/<style[^>]*>([\s\S]*?)<\/style>/gi, (match, cssContent) => { const inlined = cssContent.replace(/url\(["']?([^"')]+)["']?\)/gi, (urlMatch, urlPath) => { if (urlPath.startsWith('http') || urlPath.startsWith('dat ...[truncated 2619 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Define an explicit asset root, normally the canonical directory containing the input HTML. 2. Reject absolute paths before resolution: ```js if (path.isAbsolute(assetPath)) { throw new Error('Absolute asset paths are not allowed'); } ``` 3. Canonicalize both the asset root and target with `fs.realpathSync()` to account for symbolic links. 4. Verify that every canonical target remains beneath the authorized root: ```js function resolveAsset(assetRoot, assetPath) { if (path.isAbsolute(assetPath)) { throw new Error('Absolute paths are not allowed'); } const root = fs.realpathSync(assetRoot); const candidate = fs.realpathSync(path.resolve(root, assetPath)); const relative = path.relative(root, candidate); if (relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative))) { return candidate; } throw new Error(`Asset escapes authorized root: ${assetPath}`); } ``` 5. Apply the same validation to stylesheet links, script sources, image sources, CSS `url()` values, and inline style attributes. 6. Allowlist supported asset extensions and reject files whose type does not match the relevant HTML context. 7. Consider requiring explicit opt-in for assets outside the document directory instead of permitting implicit traversal. 8. Add regression tests for `../` traversal, absolute paths, encoded traversal, and symlink escapes. ]]>

T03 · Remote Payload Retrieval and Execution

Warning
Location
references/interactive-prototype.md:153
Finding
Floating CDN Scripts Permit Remote Runtime Payload Changes<![CDATA[ ## Vulnerability Details **File Location**: `references/interactive-prototype.md:153-155` **Vulnerability Type**: Unpinned remote JavaScript execution without integrity verification **Risk Level**: Medium ### Vulnerable Code ```html <script src="https://unpkg.com/react@18/umd/react.production.min.js"></script> <script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script> <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> ``` ### Technical Analysis The recommended prototype structure loads executable JavaScript from a third-party CDN. The package references use floating major-version selectors rather than immutable versions, and the tags do not include Subresource Integrity hashes. Consequently, the JavaScript executed by a generated prototype may differ from what was present when the Skill was reviewed. If the CDN, upstream package account, package publication process, or dependency resolution is compromised, modified code can execute in the browser whenever the prototype is opened. This behavior is relevant to interactive prototype functionality, but mutable remote code is not the minimum privilege necessary. Exact, integrity-verified resources or locally vendored copies can provide the same functionality with a smaller supply-chain attack surface. ### Attack Path 1. A generated prototype adopts the documented script tags. 2. The prototype is opened while connected to the network. 3. The browser requests the floating package versions from `unpkg.com`. 4. The CDN resolves those references to whatever release currently satisfies the specified major version. 5. If the resolved artifact or delivery infrastructure has been compromised, the browser downloads attacker-controlled JavaScript. 6. The remote code executes in the prototype's origin and can access its DOM, browser storage available to that origin, and data entered into the prototype. 7. The code can make outbound network requests subject to ...[truncated 589 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace floating package selectors with exact, reviewed versions. 2. Add verified Subresource Integrity hashes and `crossorigin="anonymous"` to every remote script. 3. Prefer locally vendored, reviewed copies when prototypes must work offline or process sensitive sample data. 4. Apply a restrictive Content Security Policy that allowlists only required script and connection origins. 5. Use the pinned-and-SRI-protected pattern already documented in `references/react-babel-setup.md:11-13` consistently across all prototype guidance. 6. Add a release process that verifies hashes before updating any remote dependency. 7. Avoid putting real credentials, production data, or sensitive personal information into browser prototypes. ]]>

T08 · Insecure Dependencies

Warning
Location
scripts/package.json:9
Finding
Export Dependencies Are Not Reproducibly Locked<![CDATA[ ## Vulnerability Details **File Location**: `scripts/package.json:9-12` **Vulnerability Type**: Non-reproducible third-party dependency installation **Risk Level**: Medium ### Vulnerable Code ```json "dependencies": { "playwright": "^1.53.0", "pptxgenjs": "^3.12.0" } ``` The installation instructions also direct users to execute: ```bash cd skills/cc-design/scripts && npm install && cd - npx playwright install chromium ``` No dependency lockfile was present in the audited project structure. ### Technical Analysis Caret version ranges permit future compatible releases to be selected during installation. Without a committed lockfile, dependency and transitive-dependency resolution may change between installations, meaning the executed dependency graph is not the same graph that was audited. The documented `npm install` command executes package lifecycle behavior allowed by npm, while `npx playwright install chromium` retrieves a browser binary. These operations are legitimate for the export functionality, but the absence of an immutable dependency resolution record weakens supply-chain controls and reproducibility. This finding does not assert that `playwright` or `pptxgenjs` is malicious. It concerns the inability to guarantee that later installations use the exact reviewed artifacts. ### Attack Path 1. A user follows `references/platform-tools.md` and runs `npm install` in the scripts directory. 2. npm resolves the caret ranges and their transitive dependencies at installation time. 3. A later release or changed transitive dependency is selected because no committed lockfile constrains resolution. 4. If a newly selected package version or dependency is compromised, its code may run during installation or when the export scripts call `require()`. 5. The dependency code executes with the privileges of the user running the export workflow. 6. The additional Playwright installation step downloads and installs a browser artifact that is lik ...[truncated 519 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin direct dependencies to exact versions rather than caret ranges. 2. Generate, review, and commit `package-lock.json`. 3. Replace installation guidance using `npm install` with: ```bash npm ci ``` 4. Enforce lockfile integrity in automated checks and reject unreviewed dependency updates. 5. Review dependency and transitive-dependency changes before merging lockfile updates. 6. Use npm provenance, registry allowlisting, and integrity verification where supported. 7. Pin the Playwright package and associated browser revision, and document the expected artifact checksums. 8. Run export tooling in a sandbox with minimal filesystem and network access when processing untrusted HTML. ]]>
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (34)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The declared description presents a creative design/prototyping skill focused on producing polished HTML UI artifacts, exploring visual directions, and reviewing design work. The supplied code instead implements a specific conversion/export tool for presentation slides: it reads an HTML file, parses <section> elements, and generates a .pptx deck either as editable text slides or screenshot-based image slides. While presentations are mentioned in the declared purpose, the actual code does not design slides or provide design critique; its primary purpose is format conversion/export. That is a materially different capability from the declared design-oriented function, so this is a mismatch.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared description presents a design-focused skill for producing HTML-based visual designs and design guidance. The supplied code does not implement any design, HTML generation, prototyping, visual review, or style-direction behavior. Instead, it is a generic helper for parsing CLI arguments for scripts. This is not merely a supporting detail of the described skill in isolation; the code chunk's primary purpose is unrelated utility functionality, so the description does not accurately represent the actual behavior shown.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The declared description presents this as a design/prototyping skill focused on creating or advising on visual UI work. The supplied code does not implement design generation, styling, critique, or prototyping behavior. Instead, it is a narrowly scoped export tool: it reads a local HTML file, launches Playwright Chromium, renders the file, optionally expands slide sections for printing, and saves a PDF. While PDF export could support a design workflow, it is not the same as the declared primary purpose, and key capabilities actually present in code—local file reading and browser-based PDF generation—are undeclared. Therefore this is a material description-to-behavior mismatch.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The declared description presents a design-focused skill intended to create or critique polished visual UI prototypes and recommend style directions. The supplied code does not perform design generation, design review, visual exploration, or style advising. Instead, it is a technical packaging tool that processes an existing HTML file, reads linked local assets from the filesystem, and outputs a single bundled HTML artifact with inlined CSS, JS, images, and CSS-referenced assets. This is a materially different primary purpose and includes undeclared file transformation/bundling capabilities unrelated to the stated design/prototyping role.

Ae1

High
Category
analysis-evasion
Content
| Slide deck | `references/starter-components.md` | `assets/templates/deck_stage.js` | 固定画布缩放与翻页 |
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
| Slide deck | `references/starter-components.md` | `assets/templates/deck_stage.js` | 固定画布缩放与翻页 |
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
| Slide deck | `references/starter-components.md` | `assets/templates/deck_stage.js` | 固定画布缩放与翻页 |
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
| 动画 / motion study | `references/starter-components.md` + `references/react-babel-setup.md` | `assets/templates/animations.jsx` | 时间轴和播放状态 |
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
| 动画 / motion study | `references/starter-components.md` + `references/react-babel-setup.md` | `assets/templates/animations.jsx` | 时间轴和播放状态 |
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
| 动画 / motion study | `references/starter-components.md` + `references/react-babel-setup.md` | `assets/templates/animations.jsx` | 时间轴和播放状态 |
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger conditions are very broad ('make it look good', presentations, design systems, wireframes, mockups, style selection), which can cause the skill to activate for many ordinary requests outside its safest intended scope. Over-broad routing increases the chance that auxiliary behaviors like exports, file transforms, or tool invocation are used when a simpler response would suffice, enlarging attack surface and causing unintended file operations.

Natural-Language Policy Violations

Medium
Confidence
98% confidence
Finding
The Default Contract states '输出语言:中文说明', which establishes Chinese as the default language for responses. This is a natural-language locale policy issue because it forces a specific language unless the user says otherwise, rather than offering a language choice or requiring explicit opt-in.

Vague Triggers

Medium
Confidence
88% confidence
Finding
The manifest instructs use of "$cc-design" but does not define when this skill should or should not activate, nor does it provide any negative examples or scope boundaries. In a manifest file, this lack of trigger specificity can cause unintended invocation if the agent treats the phrase as a general design request shortcut.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
The natural-language instructions defining when to load or skip the skill are written only in Chinese, which imposes a specific language/locale on users or downstream agents without any opt-in or stated regional justification. This matches the policy category for language or locale constraints that are not optional or documented as necessary.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The reference instructs the agent to auto-load this workflow whenever a user mentions a specific brand name or asks to match a well-known product. Because many of the listed brands are common terms in normal design discussions, this can trigger external fetching and style-cloning behavior without clear user consent, expanding scope and increasing the chance of unintended network access, brand imitation, or policy violations.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
❌ **Don't blindly copy:** Adapt the design system to the user's product context
❌ **Don't ignore licensing:** Note that design systems may have trademark restrictions
❌ **Don't mix conflicting aesthetics:** Stripe's gradients + Vercel's minimalism = visual chaos
❌ **Don't skip user confirmation:** Always show what you fetched before applying

## Example Usage
Confidence
85% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
The entire skill guidance is written only in Chinese and includes user-facing instructions such as what to ask and what to tell the user, implying operation in a fixed language. There is no indication that the user may choose another language, nor any justification that this skill is limited to a Chinese-language context.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The file uses Chinese-only activation and usage cues ('Load when', 'Skip when', 'Why it matters') without offering a language choice or equivalent multilingual guidance. In an agent skill, this can cause operator confusion, incorrect triggering, or exclusion of users/reviewers who cannot read the instructions, which degrades safe and reliable use even if it is not directly exploitable for code execution or data theft.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The trigger guidance is intentionally broad enough to activate on many generic design-adjacent requests, which can cause inappropriate routing of ordinary tasks into this skill. In an agent system, over-broad invocation conditions are a real security and safety concern because they expand the skill's authority surface and increase the chance that unrelated or sensitive prompts are handled under this skill's instructions.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The guide embeds Chinese-only trigger and operating instructions (for example, 'Load when' and the review workflow) without indicating that language should follow the user's preference. In an agent setting, this can cause the skill to activate or respond in a language the user did not request, degrading usability, causing misunderstandings, and potentially bypassing downstream policy or review expectations tied to language consistency.

Vague Triggers

Medium
Confidence
96% confidence
Finding
The trigger guidance uses broad phrases like "make it look good" and "design a screen," which are common everyday requests and can cause the skill to activate in situations beyond its intended scope. In an agent setting, overly broad activation increases the chance of misrouting tasks, overriding more appropriate skills, or injecting unsolicited design-oriented behavior into unrelated workflows.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
This markdown file contains natural-language operational guidance entirely in Chinese, and it does not indicate that the user may choose another language or that the skill is intentionally limited to a Chinese-language audience. That can violate language/locale policy by implicitly forcing a specific language without user opt-in.

Rp1

Medium
Category
MCP Rug Pull
Confidence
94% confidence
Finding
The documentation instructs users to run `npx playwright install chromium` without pinning a specific Playwright version. `npx` may resolve and execute whatever package version is current or otherwise available in the environment, which weakens reproducibility and can expose users to unintended or malicious package changes in the supply chain. In this skill context, the command is especially relevant because it is a setup step users are likely to copy-paste directly.

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.

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.

Static analysis

Detected: suspicious.dynamic_code_execution

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
scripts/gen_pptx.js:177