Back to skill

Security audit

Playwright Scraper

Security checks for vulnerabilities and agentic risk

Overview

This skill is an unrestricted anti-bot web scraper, and its URL input can be abused to run local shell commands.

Install only after the publisher replaces execSync string construction with an argument-array API, validates and restricts URLs, ships the missing scraper script, updates or pins dependencies, and documents that scraping must be limited to sites the user is authorized to access.

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
index.js:26
Finding

OS Command Injection Through the URL Argument

Content
View full analysis

Vulnerability Details

File Location: index.js, lines 26–29
Vulnerability Type: OS command injection
Risk Level: Critical

Vulnerable Code

js
const url = request.params.arguments.url;
try {
  // Execute the scraper script and capture its output
  const stdout = execSync(`node scripts/playwright-stealth.js "${url}"`, { encoding: 'utf8' });

Technical Analysis

The stealth_scrape MCP tool accepts an attacker-controlled url value and interpolates it directly into a command string passed to child_process.execSync(). This API executes the string through a system shell.

Wrapping the value in double quotes does not make it safe. An attacker can include a double quote to terminate the intended argument and then append shell operators and arbitrary commands. Neither the MCP input schema nor the request handler validates the value as an HTTP/HTTPS URL or safely escapes it for the host shell.

The referenced scripts/playwright-stealth.js file is absent from the audited package. Although this prevents the advertised scraper from operating normally, it does not reliably mitigate the injection: the shell can still parse and execute appended commands.

Attack Path

  1. An attacker or compromised agent invokes the exposed stealth_scrape MCP tool.
  2. The attacker supplies a crafted url, for example:
    text
    "; id; #
    
  3. The server constructs a command equivalent to:
    sh
    node scripts/playwright-stealth.js ""; id; #"
    
  4. execSync() passes that command to the system shell.
  5. The shell executes the injected id command under the MCP server process's operating-system identity.
  6. An attacker can replace id with other commands available to that account.

Impact Assessment

Successful exploitation provides arbitrary command execution with the privileges of the Node.js MCP server. The attacker could read or alter files accessible to that account, ...[truncated 425 chars]

Remediation
View remediation

Remediation Suggestions

  1. Do not construct a shell command using user-controlled data. Invoke Node.js directly with an argument array and disable shell processing:

    js
    import { execFileSync } from "node:child_process";
    
    const stdout = execFileSync(
      process.execPath,
      ["scripts/playwright-stealth.js", validatedUrl],
      {
        encoding: "utf8",
        shell: false,
        timeout: 30_000,
        maxBuffer: 5 * 1024 * 1024
      }
    );
    
  2. Parse and validate the input before execution:

    js
    function validateUrl(value) {
      if (typeof value !== "string" || value.length > 2048) {
        throw new Error("Invalid URL");
      }
    
      const parsed = new URL(value);
      if (!["http:", "https:"].includes(parsed.protocol)) {
        throw new Error("Only HTTP and HTTPS URLs are allowed");
      }
    
      return parsed.href;
    }
    
  3. Consider blocking loopback, link-local, private-network, and cloud metadata destinations if arbitrary internal-resource access is not an intended feature.

  4. Run the browser and MCP process under a dedicated, unprivileged account with filesystem and network restrictions.

  5. Add regression tests using quote characters, command separators, command substitutions, newlines, and platform-specific shell metacharacters.

  6. Include and review the referenced scraper script before deployment; the audited package does not contain scripts/playwright-stealth.js.

Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (16)

Known Vulnerable Dependency: brace-expansion==1.1.12 — 4 advisory(ies): CVE-2026-13149 (brace-expansion: DoS via exponential-time expansion of consecutive non-expanding); CVE-2026-33750 (brace-expansion: Zero-step sequence causes process hang and memory exhaustion); CVE-2026-14257 (brace-expansion: DoS via unbounded expansion length causing an out-of-memory pro) +1 more

High
Category
Supply Chain
Confidence
94% confidence
Finding

brace-expansion 1.1.12 is a known vulnerable version with multiple denial-of-service advisories involving pathological expansion inputs. Because it is present in the lockfile, any runtime path that accepts attacker-controlled glob or brace patterns could trigger excessive CPU or memory consumption.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: express-rate-limit==8.2.1 — 1 advisory(ies): CVE-2026-30827 (express-rate-limit: IPv4-mapped IPv6 addresses bypass per-client rate limiting o)

High
Category
Supply Chain
Confidence
95% confidence
Finding

express-rate-limit 8.2.1 is affected by an advisory allowing rate-limit bypass using IPv4-mapped IPv6 address forms. In a scraper skill that may expose an MCP/HTTP interface through the SDK stack, bypassable rate limiting can materially weaken abuse protection and permit brute force or request flooding from a single client.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: fast-uri==3.1.0 — 7 advisory(ies): CVE-2026-13676 (fast-uri vulnerable to host confusion via failed IDN canonicalization); CVE-2026-18446 (fast-uri vulnerable to host confusion via backslash authority introducer); CVE-2026-75975 (fast-uri vulnerable to server-side request forgery via malformed IPv6 normalizat) +4 more

High
Category
Supply Chain
Confidence
88% confidence
Finding

fast-uri 3.1.0 is a known-affected version with multiple host confusion and SSRF-related advisories. In the context of a browser automation/scraper skill, URI parsing errors are more dangerous because the skill is likely to process remote URLs, and malformed input could influence outbound requests, target validation, or allowlist checks.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: hono==4.12.5 — 16 advisory(ies): CVE-2026-56762 (Hono missing validation of cookie name on write path in setCookie()); CVE-2026-47676 (Hono: app.mount() strips mount prefix using undecoded path, causing incorrect ro); CVE-2026-47675 (Hono: Cookie helper does not sanitize sameSite and priority, allowing Set-Cookie) +13 more

High
Category
Supply Chain
Confidence
96% confidence
Finding

hono 4.12.5 has numerous listed advisories affecting cookies, routing, and request handling behavior. Because @modelcontextprotocol/sdk depends on Hono and may expose server functionality, flaws in request parsing or route handling could become reachable from remote clients and have meaningful security consequences.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: ip-address==10.0.1 — 2 advisory(ies): CVE-2026-69192 (ip-address: Address4 decodes leading-zero octets as decimal while resolvers deco); CVE-2026-42338 (ip-address has XSS in Address6 HTML-emitting methods)

High
Category
Supply Chain
Confidence
90% confidence
Finding

ip-address 10.0.1 is flagged for address parsing inconsistencies and XSS in HTML-emitting methods. In this dependency tree it is used by express-rate-limit, and parsing inconsistencies can directly affect IP-based security decisions, making bypass of per-client controls plausible in server-exposed skill deployments.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: path-to-regexp==8.3.0 — 2 advisory(ies): CVE-2026-4923 (path-to-regexp vulnerable to Regular Expression Denial of Service via multiple w); CVE-2026-4926 (path-to-regexp vulnerable to Denial of Service via sequential optional groups)

High
Category
Supply Chain
Confidence
89% confidence
Finding

path-to-regexp 8.3.0 has reported ReDoS/DoS issues involving complex route patterns. Since it underpins router behavior in the server stack, attacker-crafted paths may trigger excessive processing and degrade availability if the skill exposes HTTP endpoints.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill explicitly advertises anti-bot evasion, stealth behavior, user-agent spoofing, and scraping arbitrary URLs, but provides no warning about legal, ethical, or security risks. This makes misuse more likely by normalizing bypass of website protections and enabling users to target any site without guardrails or disclosure of the consequences.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The manifest description is written only in Chinese, which imposes a specific language choice in the skill's natural-language metadata. There is no indication of user opt-in, multilingual support, or a documented region-specific justification for this locale constraint.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The natural-language strings describing the tool and its input are written only in Chinese, which effectively imposes a locale/language choice without offering alternatives or opt-in. The file does not document a region-specific purpose that would justify this restriction under the stated policy.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The tool passes a user-controlled URL directly into a shell command via execSync string interpolation. Even though the URL is wrapped in double quotes, shell metacharacter expansion and quoting edge cases can still enable command injection or unintended command execution, especially in a stdio-exposed MCP tool where input may be attacker-controlled.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: @hono/node-server==1.19.11 — 2 advisory(ies): CVE-2026-39406 (@hono/node-server: Middleware bypass via repeated slashes in serveStatic); GHSA-frvp-7c67-39w9 (Node.js Adapter for Hono: Path traversal in `serve-static` on Windows via encode)

Low
Category
Supply Chain
Confidence
91% confidence
Finding

The lockfile includes @hono/node-server 1.19.11, and the cited advisories affect static file serving behavior such as repeated-slash middleware bypass and Windows path traversal in serve-static handling. Even though this file alone does not prove the vulnerable code path is used, a dependency lockfile pinning a known-affected version is a real supply-chain risk because the package may be invoked by the skill at runtime.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: body-parser==2.2.2 — 1 advisory(ies): CVE-2026-12590 (body-parser vulnerable to denial of service when invalid limit value silently di)

Low
Category
Supply Chain
Confidence
82% confidence
Finding

body-parser 2.2.2 is listed in the dependency tree and has a reported denial-of-service issue around invalid limit handling. This is a true vulnerable dependency finding, although its practical impact depends on whether untrusted request bodies are parsed by an exposed HTTP endpoint in the skill.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: qs==6.15.0 — 3 advisory(ies): CVE-2026-82417 (qs: Denial of Service via Attacker Controlled isBuffer); CVE-2026-8723 (qs has a remotely triggerable DoS: qs.stringify crashes with TypeError on null/u); CVE-2026-82562 (qs array-limit bypass via bracket-key comma parsing)

Low
Category
Supply Chain
Confidence
84% confidence
Finding

qs 6.15.0 is present and has advisories related to denial of service and parser edge cases. This is a true vulnerable dependency, but impact is lower unless the skill accepts attacker-controlled query strings or nested parameter structures through an exposed web interface.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
93% confidence
Finding

The dependency uses a caret range, which permits automatic installation of newer compatible releases rather than a single exact version. This increases supply-chain risk because a compromised or breaking upstream release could be pulled into builds without explicit review, though the package.json alone does not show active exploitation.

Content

Scanner excerpt · package.json (reported line 5)May include surrounding context.

json
"name": "playwright-scraper",
  "type": "module",
  "dependencies": {
    "@modelcontextprotocol/sdk": "^1.27.1",
    "playwright-extra": "^4.3.6",
    "puppeteer-extra-plugin-stealth": "^2.11.2"
  }

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The dependency is not pinned to an exact version, so future installs may resolve to different upstream releases. In this skill context, that is somewhat more dangerous because browser automation and scraping tooling are high-value targets for supply-chain compromise and often execute powerful local code during runtime.

Content

Scanner excerpt · package.json (reported line 6)May include surrounding context.

json
"type": "module",
  "dependencies": {
    "@modelcontextprotocol/sdk": "^1.27.1",
    "playwright-extra": "^4.3.6",
    "puppeteer-extra-plugin-stealth": "^2.11.2"
  }
}

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The stealth plugin is specified with a caret range, allowing newer upstream versions to be installed automatically. This is more sensitive in context because a stealth/evasion-focused browser plugin has elevated abuse potential and, if compromised, could alter scraping behavior, exfiltrate data, or execute malicious code in environments running the skill.

Content

Scanner excerpt · package.json (reported line 7)May include surrounding context.

json
"dependencies": {
    "@modelcontextprotocol/sdk": "^1.27.1",
    "playwright-extra": "^4.3.6",
    "puppeteer-extra-plugin-stealth": "^2.11.2"
  }
}

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
index.js:29