Back to skill

Security audit

playwright-controller

Security checks for vulnerabilities and agentic risk

Overview

This browser capture skill is mostly purpose-aligned, but its command-line entry point can execute code from a developer-specific path outside the package and has under-scoped browsing and file-writing behavior.

Review before installing or running. The CLI should be fixed to import the packaged crawler file, and use should be limited to URLs and output directories the user explicitly trusts. Avoid using it on authenticated, private, internal, or sensitive pages until URL restrictions, output path confinement, retention guidance, and headless/resource-loading documentation are corrected.

Vulnerability Patterns
  • Tool Hijacking and SpoofingModifies or replaces tools so legitimate-looking calls execute attacker logic
  • 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 (2)

T07 · Tool Hijacking and Spoofing

Error
Location
playwright-cmd.js:1
Finding

CLI Loads and Executes an Unaudited Module from an External Absolute Path

Content
View full analysis

Vulnerability Details

File Location: playwright-cmd.js:1
Vulnerability Type: External module hijacking through a hardcoded absolute path
Risk Level: High

Vulnerable Code:

javascript
const { fetchWithPlaywright, fetchElementAndScreenshot } = require('/Users/chenkuan/.openclaw/workspace/毕业论文/论文工程/playwright-crawler-v3.js');

Technical Analysis

The command-line entry point does not load the audited playwright-crawler-v3.js bundled in the project. Instead, Node.js is instructed to load and immediately evaluate a JavaScript module from an absolute path outside the package.

The contents and integrity of that external file are not controlled by this project. If the path exists and another local user, compromised process, or writable workspace can modify it, the imported module can be replaced with arbitrary JavaScript. Node.js executes top-level module code as soon as require() is evaluated, before either imported function is invoked.

This behavior also conflicts with the documented relative import in SKILL.md, which presents require('./playwright-crawler-v3.js'). On systems where the hardcoded path does not exist, the CLI fails to start. On systems where it does exist, the actual executed implementation may differ from the audited package.

Attack Path

  1. An attacker obtains write access to /Users/chenkuan/.openclaw/workspace/毕业论文/论文工程/playwright-crawler-v3.js, or causes an attacker-controlled file to be created at that location.
  2. The attacker inserts top-level JavaScript that performs arbitrary actions, then optionally exports functions with the expected names to avoid detection.
  3. A user or AI Agent invokes playwright-cmd.js through the advertised Skill command or an npm script.
  4. Node.js resolves the hardcoded path and evaluates the attacker-controlled module immediately.
  5. The malicious code runs with the same operating-system identity and permissions as the Skill process ...[truncated 642 chars]
Remediation
View remediation

Remediation Suggestions

Load only the implementation shipped with the package:

javascript
const {
  fetchWithPlaywright,
  fetchElementAndScreenshot
} = require('./playwright-crawler-v3.js');

For explicit and location-independent resolution, anchor the path to the current module:

javascript
const path = require('path');

const {
  fetchWithPlaywright,
  fetchElementAndScreenshot
} = require(path.join(__dirname, 'playwright-crawler-v3.js'));

Additional hardening measures:

  • Remove all hardcoded developer-specific paths from executable code.
  • Package and execute only reviewed source files located beneath the Skill root.
  • Add a clean-environment test that starts the CLI without relying on files outside the package.
  • Consider package integrity checks or signed release artifacts where the Skill distribution system supports them.
  • Ensure the package directory and its executable modules are not writable by untrusted users.

T09 · Insecure Skill Coding Practices

Warning
Location
playwright-crawler-v3.js:49
Finding

Unrestricted Browser Navigation Enables Access to Loopback, Private-Network, and Metadata Services

Content
View full analysis

Vulnerability Details

File Location: playwright-crawler-v3.js:49-52 and playwright-crawler-v3.js:168-171
Vulnerability Type: Server-side request forgery through unrestricted browser navigation
Risk Level: Medium

Vulnerable Code:

javascript
// Full-page retrieval
await page.goto(url, {
  waitUntil: 'networkidle',
  timeout: timeout
});
javascript
// Element retrieval
await page.goto(url, {
  waitUntil: 'networkidle',
  timeout: timeout
});

Related extraction behavior:

javascript
const content = await page.evaluate(() => {
  // Remove unwanted elements
  const elementsToRemove = document.querySelectorAll(
    'script, style, noscript, iframe, nav, footer, header, .ad, .advertisement, .banner'
  );
  elementsToRemove.forEach(el => el.remove());

  // Obtain page text
  return document.body.innerText;
});
javascript
const content = await element.evaluate(el => el.innerText);

Technical Analysis

Both exported crawler functions pass a caller-controlled URL directly to page.goto() without validating the URL scheme, resolving and checking the destination address, restricting hosts, or blocking loopback, private, link-local, and cloud metadata ranges.

The browser runs from the Agent host and therefore has the host's network reachability. A target that is inaccessible to an external attacker may still be reachable through localhost, a private network address, an internal DNS name, or a link-local metadata endpoint. The Skill subsequently extracts response text and takes screenshots, making retrieved internal information available in returned results and output files.

Checking only the initial URL would not be sufficient. A public endpoint can redirect the browser to an internal address, and DNS rebinding can cause a previously public hostname to resolve to a private destination. Browser subresources are also loaded without intercep ...[truncated 1586 chars]

Remediation
View remediation

Remediation Suggestions

Introduce centralized URL validation before every navigation:

  1. Permit only explicitly required schemes, normally https: and optionally http:.
  2. Reject URLs containing embedded credentials.
  3. Resolve the hostname and reject every address in loopback, private, link-local, unspecified, multicast, carrier-grade NAT, and reserved ranges for both IPv4 and IPv6.
  4. Explicitly block cloud metadata destinations, including link-local metadata addresses and provider-specific metadata hostnames.
  5. Revalidate every redirect and verify the final response URL.
  6. Defend against DNS rebinding by validating the address actually used for the connection, not only an earlier DNS lookup.
  7. Prefer an explicit hostname allowlist when the Skill is intended to browse a known set of sites.
  8. Run Chromium in an isolated network namespace or egress-restricted sandbox that cannot reach internal infrastructure.

A request policy should also be attached to the browser context so that subresource requests cannot bypass the top-level navigation checks. Log blocked destinations without recording credentials or sensitive query values.

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 (22)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The documentation describes a webpage browsing and extraction skill, but it also indicates local filesystem writes, forced headed browser behavior, and fixed mobile emulation details that are not clearly disclosed in the top-level purpose. This mismatch can mislead users and higher-level agents about side effects, privacy exposure, and operational behavior, increasing the chance of unsafe use in sensitive environments.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `playwright-cmd.js` - 命令行接口

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The changelog explicitly documents capabilities to extract webpage text and save screenshots/files, but provides no warning about capturing sensitive data, copyrighted content, authenticated pages, or personal information. In a browser-automation skill, omission of privacy and data-handling guidance increases the risk that users or downstream agents will collect and persist sensitive content without informed consent or safeguards.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The README explicitly states that full-page screenshots and extracted page text are automatically saved to disk, but it does not warn users that this may persist sensitive content locally. In the context of a browser automation skill, captured pages can contain personal data, internal dashboards, authentication-visible content, or confidential text, so silent local persistence creates a real privacy and data-handling risk.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The file switches into Chinese for the main skill instructions and usage details, which can force a specific language on users who did not opt in. The policy allows fixed locale/language only when the skill offers a choice or clearly justifies a region-specific constraint, neither of which is present here.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The file repeatedly describes the skill as performing complete page loading, including images, CSS, and fonts, and later states that no interception rules are set so all resources load normally. However, the workflow and other sections explicitly say the implementation sets interception rules to skip images, CSS, and fonts. These statements actively contradict each other about a core aspect of behavior.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The API workflow for fetchWithPlaywright says step 2 sets request interception to skip images, CSS, and fonts, but the later '完整资源加载' section says no interception rules are set and all resources load, specifically to preserve full-page appearance. Because both sections describe implementation behavior, this is an active contradiction rather than mere incompleteness.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The manifest description is written entirely in Chinese and presents the skill as a Chinese-language tool without offering any language or locale choice. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale constraint is clearly documented and justified, which is not present here.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The --dir argument allows arbitrary filesystem paths, and the code creates directories and writes files there with no confinement. If this skill is invoked by a higher-trust agent or automation pipeline, an attacker controlling arguments could cause files to be written into sensitive or unexpected locations, enabling overwrite, persistence, or data placement outside the intended workspace.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The script persists full extracted page content and error details to local files without any apparent minimization, consent, or retention controls. In a browsing/screenshot skill, this can expose sensitive data from visited pages or internal URLs to disk, expanding the data surface beyond transient fetch/screenshot behavior and creating local data leakage risk.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The code and documentation conflict: comments say headless defaults to true, but the implementation forces headed mode. In a browsing/screenshot skill, this can expose visited content visibly on the host desktop, leak information to local observers or screen recording software, and violate operator expectations about stealth and isolation.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill writes screenshots to the local filesystem without that behavior being disclosed in the manifest description. In this skill context, screenshots can capture sensitive page content, session state, or user-provided URLs, so undisclosed persistence increases privacy and data-handling risk.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The browser context is hard-coded to use the zh-CN locale, which forces a specific language/locale behavior regardless of user preference. This matches the policy-violation category because the code does not offer any language choice, opt-in, or documented justification for the locale restriction.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The second function repeats the same mismatch by implying configurable browser behavior while always launching headed mode. In this skill's context, that can unintentionally expose sensitive browsing targets and extracted content during automation, especially on shared or monitored systems.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

This function independently creates a browser context with locale: 'zh-CN', again enforcing a specific locale without any user selection mechanism. Repeating the same fixed locale behavior in another entry point broadens the impact of the policy issue.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The changelog states that the skill does not block any resources, meaning third-party images, CSS, fonts, trackers, and other remote assets will load automatically. Without any warning, this can increase metadata leakage, trigger unwanted network requests to untrusted domains, and enlarge the privacy/security exposure of using the skill on arbitrary webpages.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The natural-language instructions throughout the skill documentation are exclusively in Chinese, and the file does not offer an alternative language or note that the skill is region- or locale-specific. Under the stated policy, forcing a specific language without user opt-in can be a natural-language policy violation.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
87% confidence
Finding

Using a caret range for Playwright allows different versions to be installed over time, which weakens build reproducibility and can unintentionally pull in a vulnerable or behavior-changing release. In a browser-automation skill, dependency drift is more sensitive because the package controls browser downloads and execution paths.

Content

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

json
"node": ">=16.0.0"
  },
  "dependencies": {
    "playwright": "^1.58.2"
  }
}

Unverifiable Dependency: playwright has 1 known advisory(ies) (CVE-2025-59288 (Playwright downloads and installs browsers without verifying the authenticity of)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
82% confidence
Finding

The manifest depends on Playwright without an exact pinned version while there is a known advisory affecting some Playwright releases related to browser download authenticity verification. Because the installed version may vary, consumers cannot reliably determine whether they are protected, which increases supply-chain risk for a tool that fetches and runs browser binaries.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

The code explicitly formats timestamps using the 'zh-CN' locale in user-facing output. This imposes a specific locale without offering an opt-in or documenting that the tool is region-specific, which matches the language/locale policy violation criteria.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

The error-content text uses toLocaleString('zh-CN'), which forces a specific locale in generated user-visible artifacts. Because the file does not offer a locale choice or justify a region-specific constraint, this is a natural-language locale policy issue.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The function documentation says headless mode is configurable and defaults to true, but the implementation ignores the option and always launches Chromium with headless set to false while forcing mobile device emulation. This creates a mismatch between the declared behavior and the actual browsing behavior exposed by the skill.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.