Back to skill

Security audit

Design.md Extractor

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent local design extractor, but it needs review because it can open arbitrary URLs or local files and may save page text and metadata into generated outputs.

Install only if you are comfortable with a local browser opening the exact URL or file you provide. Use it on trusted public pages or intentionally selected local files, avoid private dashboards or secret-bearing URLs, and review generated design-snapshot.json before sharing because it may contain page URLs, selectors, and visible text snippets.

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

Warning
Location
scripts/extract-design.mjs:16
Finding

Unrestricted URL Navigation Enables SSRF and Local-File Access

Content
View full analysis

Vulnerability Details

File Location: scripts/extract-design.mjs:16-36
Vulnerability Type: Server-Side Request Forgery and unrestricted local-resource navigation
Risk Level: Medium
Category: T09: Insecure Skill Coding Practices

Vulnerable Code

js
const options = parseArgs(process.argv.slice(2));

if (!options.url) {
  fail('Missing --url. Example: node scripts/extract-design.mjs --url https://example.com --out ./design.md');
}

const outPath = resolve(process.cwd(), options.out ?? 'design.md');
const snapshotPath = options.snapshot ? resolve(process.cwd(), options.snapshot) : undefined;
const viewport = parseViewport(options.viewport ?? '1440x900');
const timeoutMs = Number(options.timeout ?? 30000);

const executablePath =
  options['executable-path'] ?? process.env.PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH ?? findBrowserExecutable();
const browser = await chromium.launch({
  headless: true,
  ...(executablePath ? { executablePath } : {}),
});

try {
  const page = await browser.newPage({ viewport });
  await page.goto(options.url, { waitUntil: 'domcontentloaded', timeout: timeoutMs });

The documented workflow also explicitly permits unrestricted local-file URLs:

bash
node scripts/extract-design.mjs --url file:///absolute/path/to/page.html --out ./design.md --snapshot ./design-snapshot.json

This behavior appears at SKILL.md:31-34.

Technical Analysis

The command-line --url value is supplied directly to Playwright's page.goto() without URL parsing, protocol allowlisting, hostname validation, IP-address filtering, DNS resolution checks, or redirect validation.

Consequently, the browser may navigate to:

  • Loopback services such as http://127.0.0.1 or http://localhost.
  • Private-network systems in RFC 1918 address ranges.
  • Link-local services, including cloud metadata endpoints such as 169.254.169.254.
  • Arbitrary file: URLs accessib ...[truncated 2710 chars]
Remediation
View remediation

Remediation Suggestions

  1. Parse the supplied value with new URL() before launching or navigating the browser.
  2. Allow only https: and, where operationally necessary, http: URLs.
  3. Reject URLs containing embedded usernames or passwords.
  4. Resolve hostnames before navigation and reject loopback, private, link-local, multicast, unspecified, and reserved IPv4 and IPv6 ranges.
  5. Revalidate every redirect destination rather than validating only the initial URL.
  6. Mitigate DNS rebinding by binding validation to the addresses actually used for browser requests.
  7. Disable file: navigation by default.
  8. If local HTML extraction is required, expose it through a separate path argument and:
    • Require explicit user approval.
    • Canonicalize the path with realpath.
    • Restrict it to an approved directory.
    • Reject symbolic-link escapes.
    • Prevent local pages from loading arbitrary network or filesystem resources.
  9. Use Playwright request routing to block unnecessary subresources and requests to prohibited address ranges.
  10. Disable or block service workers for untrusted pages.
  11. Run the browser in an isolated container or network namespace with no access to cloud metadata, internal networks, or sensitive host files.
  12. Document that only trusted URLs may be processed when network-level isolation cannot be enforced.
Vulnerability Patterns
  • 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
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (15)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
3. Run `scripts/extract-design.mjs` from this skill directory.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
3. Run `scripts/extract-design.mjs` from this skill directory.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
3. Run `scripts/extract-design.mjs` from this skill directory.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
3. Run `scripts/extract-design.mjs` from this skill directory.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
79% confidence
Finding

The skill instructs running local code and package installation, but it does not declare an explicit tool scope such as permissions or allowed-tools. That mismatch can cause an agent to invoke broader local capabilities than the skill metadata communicates, reducing reviewability and increasing the chance of unintended environment access during execution.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

This code gathers the current page URL and hostname, and later combines that metadata with extracted visible text from page elements. Across this file there is no confirmation prompt, user-facing log/print, or inline warning/comment disclosing that on-page content and navigation context are being collected, which matters because such data may include sensitive user or system information.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

Repeated embedding of visible text across both color and layout samples multiplies sensitive-content exposure and increases the chance it will be surfaced downstream. Because the skill operates on arbitrary webpages, this can inadvertently ingest confidential text from apps the user is logged into, not just public marketing copy.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The analyzer includes visible text and anchor destinations in collected page samples, which exceeds the stated purpose of design-token extraction. On authenticated or internal pages, this can capture sensitive business data, personal data, or secret-bearing URLs and propagate them into generated artifacts or logs.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The browser-injected analysis path reproduces the same text and link extraction behavior inside page context, increasing the number of code paths that can capture sensitive content. Duplicate collection logic raises the chance that future callers will use the broader capture path unintentionally and makes auditing harder.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The function extracts aria-label, innerText, or textContent from visible elements, which can capture user-visible content from arbitrary pages. In this code file there is no prompt, log statement, or explanatory comment warning that page text is being harvested as part of analysis.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This code propagates visible page text and metadata in plain form into analysis structures, which can persist in memory, files, logs, or downstream outputs. In the context of a tool aimed at arbitrary user-provided URLs, that broadens exposure to sensitive content from private dashboards, internal tools, and authenticated sessions.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The visibleText helper extracts user-visible text from DOM elements and truncates it, but does not prevent capture of secrets, PII, or sensitive application content. Even partial text snippets can expose enough information to leak records, messages, tokens shown in UI, or confidential labels.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The workflow directs the agent to write output files like design.md and design-snapshot.json, but it does not explicitly warn that these actions modify the working directory or may overwrite existing files. In practice, this can lead to accidental data loss, unexpected repository changes, or writing sensitive extracted content into an unintended location.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

Recording element IDs and full class names creates unnecessary page fingerprinting data outside core design-token needs. While lower risk than raw text, IDs/classes often encode internal feature names, user-specific identifiers, or app structure that can leak implementation details.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

This line records href values from anchor elements as part of layout samples, which can expose navigation targets or embedded query parameters from the analyzed page. The file contains no user-facing disclosure or explanatory comment indicating that link destinations are collected.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.