Back to skill

Security audit

Playwright Scraper CN

Security checks for vulnerabilities and agentic risk

Overview

This scraping skill mostly matches its purpose, but it includes undocumented login/SMS automation and unsafe browser settings that need review before use.

Install only if you trust the publisher and will run it in a restricted environment. Use it only on sites you are authorized to access, avoid scraping sensitive pages unless needed, treat screenshots/HTML/cookies as secrets, and do not run the Xianyu login script unless the phone number is yours and you explicitly intend to request an SMS code. Prefer container or network isolation for browser runs, and pin or review any external skill or dependency before installing.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (5)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/xianyu-login.js:3
Finding
Undocumented Hard-Coded Phone Number Submitted Through an SMS Authentication Flow<![CDATA[ ## Vulnerability Details **File Location**: `scripts/xianyu-login.js:3-64` **Vulnerability Type**: Hard-coded personal data and unauthorized external action **Risk Level**: High ### Vulnerable Code ```javascript const phone = '15982192571'; // ... await page.goto('https://www.goofish.com', { waitUntil: 'networkidle', timeout: 30000 }); // ... const phoneInput = await page.$( 'input[type="tel"], input[placeholder*="手机"], input[placeholder*="号码"]' ); if (phoneInput) { await phoneInput.fill(phone); console.log('✅ 已输入手机号:', phone); await page.waitForTimeout(1000); await page.screenshot({ path: '/tmp/xianyu_step3.png' }); const codeBtn = await page.$('text=获取验证码, text=发送验证码'); if (codeBtn) { await codeBtn.click(); console.log('✅ 已点击获取验证码'); await page.waitForTimeout(2000); await page.screenshot({ path: '/tmp/xianyu_step4.png' }); } } ``` ### Technical Analysis The script embeds a real-looking phone number directly in source code, enters it into the Goofish login form, and activates the control that requests an SMS verification code. This behavior transmits personal data to an external service and generates an authentication event without obtaining runtime confirmation from the affected number's owner. The script is not disclosed in the documented repository file structure or normal two-mode scraping workflow. Triggering SMS authentication is also not necessary for the Skill's declared generic web-scraping functionality. The number is printed to process output, and screenshots of the authentication flow are saved under predictable names in the shared `/tmp` directory. Depending on the page state, those screenshots may contain the phone number, authentication status, account details, or other sensitive interface content. ### Attack Path 1. An operator or Agent invokes `node scripts/xianyu-login.js`. 2. The script opens the Goofish website and selects the login workflow. 3. It automa ...[truncated 845 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the hard-coded phone number from the repository and its history. 2. Remove the undocumented login script unless authenticated scraping is an explicitly declared and reviewed feature. 3. If login automation is required, accept the phone number only through an interactive, consent-based prompt or a protected secret provider. 4. Require explicit confirmation immediately before requesting an SMS code. 5. Never print the complete phone number; mask all but a small number of digits. 6. Disable authentication screenshots by default and redact sensitive form fields before capture. 7. If temporary screenshots are necessary, create a private temporary directory with mode `0700`, generate unpredictable file names, set files to mode `0600`, and securely remove them after use. 8. Add rate limiting and prevent repeated SMS requests. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/xianyu-stealth.js:12
Finding
Chromium Sandbox and Web Security Boundaries Are Disabled for Untrusted Pages<![CDATA[ ## Vulnerability Details **File Location**: `scripts/xianyu-stealth.js:12-21`; additional occurrence in `scripts/playwright-stealth.js:41-47` **Vulnerability Type**: Browser isolation and same-origin protections disabled **Risk Level**: High ### Vulnerable Code ```javascript const browser = await chromium.launch({ headless: true, args: [ '--no-sandbox', '--disable-setuid-sandbox', '--disable-blink-features=AutomationControlled', '--disable-web-security', '--disable-features=IsolateOrigins,site-per-process', '--disable-infobars', '--disable-dev-shm-usage', '--disable-accelerated-2d-canvas', '--no-first-run', '--no-zygote', '--disable-gpu', ], }); ``` The primary stealth scraper also weakens isolation: ```javascript const browser = await chromium.launch({ headless: headless, args: [ '--no-sandbox', '--disable-setuid-sandbox', '--disable-blink-features=AutomationControlled', '--disable-features=IsolateOrigins,site-per-process', ], }); ``` ### Technical Analysis The scripts browse externally supplied pages while disabling several important Chromium security boundaries: - `--no-sandbox` and `--disable-setuid-sandbox` remove renderer process sandboxing. - `--disable-web-security` disables browser enforcement of protections such as the same-origin policy. - `--disable-features=IsolateOrigins,site-per-process` weakens site isolation. Anti-automation evasion does not require disabling the Chromium sandbox or same-origin security. These settings exceed the minimum privileges needed to retrieve and render pages. A web page is attacker-controlled content. If that page exploits Chromium or induces unsafe cross-origin behavior, these flags substantially reduce defense in depth and increase the chance that compromise extends beyond the page being scraped. ### Attack Path 1. An attacker causes the Skill to scrape an ...[truncated 1040 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `--no-sandbox`, `--disable-setuid-sandbox`, and `--disable-web-security`. 2. Retain Chromium site isolation; remove `--disable-features=IsolateOrigins,site-per-process`. 3. Keep anti-automation changes limited to narrowly scoped browser properties that do not disable security boundaries. 4. Run the browser as a dedicated, unprivileged operating-system user. 5. Add container isolation with a read-only root filesystem, restricted mounts, dropped Linux capabilities, resource limits, and a restrictive seccomp profile. 6. Limit outbound browser traffic to approved destinations. 7. Keep Playwright and Chromium patched and use the browser version distributed for the audited Playwright release. 8. Fail safely when the environment cannot support sandboxed Chromium rather than silently reverting to an unsandboxed launch. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/playwright-simple.js:11
Finding
Unrestricted URL Navigation Enables Server-Side Request Forgery and Internal Network Access<![CDATA[ ## Vulnerability Details **File Location**: `scripts/playwright-simple.js:11-32` **Vulnerability Type**: Unvalidated arbitrary URL navigation **Risk Level**: High ### Vulnerable Code ```javascript const url = process.argv[2]; if (!url) { console.error('❌ 請提供 URL'); console.error('用法: node playwright-simple.js <URL>'); process.exit(1); } // ... const browser = await chromium.launch({ headless: process.env.HEADLESS !== 'false' }); const page = await browser.newPage(); console.log(`📱 導航到: ${url}`); await page.goto(url, { waitUntil: 'domcontentloaded' }); ``` Equivalent unrestricted navigation also occurs in: ```javascript // scripts/playwright-stealth.js const url = process.argv[2]; const response = await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 30000, }); ``` ### Technical Analysis The scripts accept an arbitrary URL and navigate to it without validating: - The URL scheme. - The initial hostname and resolved IP addresses. - Loopback, private, link-local, multicast, or reserved address ranges. - Cloud instance metadata endpoints. - Redirect destinations. - DNS rebinding or resolution changes. When this Skill runs inside an Agent, server, CI environment, or workstation, the browser may reach services that are inaccessible to the external requester. The scraper then returns page text to standard output or stores screenshots and HTML, creating an SSRF-style read channel. Browser navigation can also generate secondary requests for scripts, images, frames, and other resources. Consequently, checking only the initial URL string would not fully address the issue. ### Attack Path 1. An attacker supplies a URL targeting a local service, private network host, or cloud metadata endpoint. 2. The Agent invokes the scraper with that URL. 3. Chromium sends the request from the trusted host's network context. 4. The internal service returns information unavailable to the attacker directly. 5. The script extracts bod ...[truncated 819 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Parse targets with the standard `URL` class and permit only `http:` and `https:`. 2. Resolve all hostnames before navigation and reject loopback, private, link-local, multicast, unspecified, carrier-grade NAT, and reserved IP ranges for both IPv4 and IPv6. 3. Explicitly block cloud metadata destinations, including link-local metadata IP addresses and provider-specific metadata hostnames. 4. Revalidate every redirect destination before following it. 5. Protect against DNS rebinding by validating all resolved addresses and controlling DNS resolution at the network layer. 6. Intercept browser requests with Playwright routing and apply the same policy to frames and subresources. 7. Prefer an explicit hostname allowlist for Agent-driven operation. 8. Place the browser in a network namespace or container with firewall rules that deny access to private and metadata networks. 9. Require user confirmation before accessing a destination outside an established allowlist. ]]>

T08 · Insecure Dependencies

Warning
Location
package-lock.json:18
Finding
Dependency Archive Is Retrieved Through a Cleartext HTTP Registry Mirror<![CDATA[ ## Vulnerability Details **File Location**: `package-lock.json:18` **Vulnerability Type**: Unauthenticated dependency transport **Risk Level**: Medium ### Vulnerable Code ```json "node_modules/@playwright/test": { "version": "1.58.2", "resolved": "http://mirrors.tencentyun.com/npm/@playwright/test/-/test-1.58.2.tgz", "integrity": "sha512-akea+6bHYBBfA9uQqSYmlJXn61cTa+jbO87xVLCWbTqbWadRVmhxlXATaOjOgcBaWU4ePo0wB41KMFv3o35IXA==", "license": "Apache-2.0", "dependencies": { "playwright": "1.58.2" } } ``` ### Technical Analysis The lockfile instructs npm to obtain `@playwright/test` from an `http://` mirror. Cleartext HTTP does not authenticate the package server and does not protect requests or responses from network interception. The SHA-512 integrity field provides an important archive-integrity check and should normally reject a modified archive that does not match the lockfile. It does not, however, provide transport confidentiality, authenticate the mirror, or protect a workflow in which both dependency metadata and downloaded content can be modified before review. Reliance on an unnecessary third-party cleartext mirror also increases availability and provenance risk. ### Attack Path 1. A user follows the documented `npm install` procedure. 2. npm reads the cleartext mirror URL from `package-lock.json`. 3. A network intermediary observes or interferes with the HTTP exchange. 4. A modified archive should be rejected if the existing integrity value is enforced and remains trusted. 5. If lockfile integrity metadata is also modified before installation, ignored by tooling, or otherwise bypassed, attacker-controlled package code can be installed. 6. Dependency code then runs with the privileges of the user executing the Skill when it is imported or when applicable package lifecycle behavior is invoked. ### Impact Assessment A successful supply-chain compromise could execute code with the installing user's privileges and affect proje ...[truncated 335 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Configure npm to use `https://registry.npmjs.org/` or another audited HTTPS registry. 2. Regenerate `package-lock.json` so every `resolved` URL uses authenticated HTTPS. 3. Reject cleartext dependency sources in CI with an automated lockfile policy check. 4. Use `npm ci` in deployment and preserve lockfile integrity verification. 5. Pin dependency versions deliberately and review lockfile changes before merging. 6. Consider package provenance verification and a controlled internal registry for production environments. 7. Remove `@playwright/test` if it is not needed at runtime, reducing the dependency and installation surface. ]]>

T08 · Insecure Dependencies

Warning
Location
SKILL.md:87
Finding
Documentation Instructs Users to Install and Execute an Unpinned External Skill<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:87-95` **Vulnerability Type**: Mutable external dependency installation and execution **Risk Level**: Medium ### Vulnerable Code ```bash # Install deep-scraper skill npx clawhub install deep-scraper # Use it cd skills/deep-scraper node assets/youtube_handler.js "https://www.youtube.com/watch?v=VIDEO_ID" ``` ### Technical Analysis The Skill documentation directs users or an Agent to install `deep-scraper` by name and execute one of its JavaScript files. No exact version, artifact digest, signature, immutable source revision, or reviewed provenance is specified. As a result, the effective code executed by this documented workflow can change after the current Skill has been audited. The `npx` command may also retrieve command-line tooling dynamically if it is not already available locally. This expands the trusted computing base to mutable external components that are not contained in the audited project. The instruction is not automatically executed by this package, which limits immediate exposure, but users following the advertised YouTube workflow are directed into the unsafe supply-chain path. ### Attack Path 1. A user asks the Skill to obtain a YouTube transcript and follows the documented specialized workflow. 2. `npx` resolves the `clawhub` tooling available in the environment or downloads it. 3. `clawhub install deep-scraper` resolves the current package associated with that unversioned name. 4. A compromised registry, maintainer account, mutable release, or dependency can supply code different from the version originally reviewed. 5. The user executes `assets/youtube_handler.js` with local Node.js privileges. 6. Malicious upstream code can access files, environment variables, credentials, and network resources available to the invoking account. ### Impact Assessment If the external Skill or installation tooling is compromised, arbitrary JavaScript can run with the user's privileges. ...[truncated 315 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not instruct an Agent to install third-party Skills automatically. 2. Require explicit informed user approval before retrieving or executing external code. 3. Pin the external Skill and installation tooling to exact, immutable versions. 4. Verify release signatures or cryptographic hashes before execution. 5. Document the upstream repository, maintainer, reviewed commit, expected file list, and checksum. 6. Prefer a reviewed, vendored implementation when licensing and maintenance practices permit. 7. Execute optional third-party handlers in a restricted container with minimal filesystem and network access. 8. Re-audit the external component whenever its pinned version changes. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • 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
Findings (54)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The declared description emphasizes anti-bot protection and suitability for complex sites with scraping defenses. The code does not implement any anti-bot evasion measures such as stealth plugins, header/cookie management, proxy rotation, challenge solving, session handling, or browser fingerprint masking. In fact, the code comments explicitly describe it as a 'simple' scraper for general dynamic sites with no anti-scraping protection. It only performs basic navigation, a fixed delay, content extraction, and optional screenshot capture. Therefore the description materially overstates the capability and intended use compared with the actual behavior.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The declared description says this is a Playwright-based web scraping skill with anti-bot protection. While the code does use Playwright and includes anti-detection measures, its primary behavior is not scraping content. Instead, it automates a login process on Xianyu/Goofish: visiting the site, clicking a login button, filling a phone number, attempting to send an SMS verification code, taking screenshots, and displaying page text. These are materially different capabilities from scraping and involve account-authentication actions that were not declared. Therefore the description does not accurately represent the code's actual behavior.

Ae1

High
Category
analysis-evasion
Content
| **Cloudflare Protected** | High | **Playwright Stealth** ⭐ | `scripts/playwright-stealth.js` |
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
| **Cloudflare Protected** | High | **Playwright Stealth** ⭐ | `scripts/playwright-stealth.js` |
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
| **Cloudflare Protected** | High | **Playwright Stealth** ⭐ | `scripts/playwright-stealth.js` |
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
| **Cloudflare Protected** | High | **Playwright Stealth** ⭐ | `scripts/playwright-stealth.js` |
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
| **Cloudflare Protected** | High | **Playwright Stealth** ⭐ | `scripts/playwright-stealth.js` |
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
| **Cloudflare Protected** | High | **Playwright Stealth** ⭐ | `scripts/playwright-stealth.js` |
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
| **Cloudflare Protected** | High | **Playwright Stealth** ⭐ | `scripts/playwright-stealth.js` |
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
| **Cloudflare Protected** | High | **Playwright Stealth** ⭐ | `scripts/playwright-stealth.js` |
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
| **Cloudflare Protected** | High | **Playwright Stealth** ⭐ | `scripts/playwright-stealth.js` |
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Missing User Warnings

High
Confidence
96% confidence
Finding
The README suggests manually logging in and exporting cookies without any safety guidance for handling authentication material. Exported cookies can enable session hijacking or unauthorized account access if copied, logged, shared, or stored insecurely, and this risk is especially relevant in a scraping skill that may target authenticated sessions.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
This script goes beyond ordinary scraping and automates an account login flow, including entering a hardcoded phone number and triggering SMS verification. In a scraping skill, that creates credential-handling and account-access capabilities that can be misused for unauthorized access attempts, account takeover workflows, or deceptive collection of one-time codes.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
echo ""

# 清理
rm -f /tmp/test-*.json screenshot-*.png

echo "✅ 所有測試通過!"
Confidence
95% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

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.

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.

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.

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.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The README explicitly promotes anti-bot evasion techniques and page data capture without any warning about authorization, terms-of-service, privacy, or sensitive-data handling. In a scraping skill, that omission increases the chance of misuse against protected sites and unsafe retention of scraped HTML or screenshots that may contain personal or confidential information.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The README explicitly promotes stealth scraping, hiding automation fingerprints, screenshot capture, and HTML saving, but provides no warning about authorization, privacy, or lawful data handling. In a scraping skill, that omission increases the likelihood of misuse against protected sites or collection of sensitive content, especially because the text frames bypassing anti-bot controls as a recommended workflow.

Lp3

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding
The skill documents executable commands that use network access and environment variables, but it does not declare any explicit tool scope or permissions metadata. In a skill ecosystem, missing scope declarations weakens reviewability and can let users or orchestration systems invoke higher-risk behaviors without clear consent boundaries.

Static analysis

No suspicious patterns detected.