Back to skill

Security audit

chrome-cdp

Security checks for vulnerabilities and agentic risk

Overview

This skill can control already logged-in Chrome tabs, but it lacks clear safety boundaries and uses unsafe installation and command execution patterns.

Install only after reviewing and pinning the external chrome-cdp code, fixing the shell command construction, and deciding whether you are comfortable granting an agent access to your live Chrome profile. Use a separate Chrome profile with no sensitive accounts where possible, and require explicit approval before clicks, typing, navigation, screenshots, or JavaScript evaluation.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
index.js:31
Finding
Shell Command Injection Through Unquoted CDP Arguments## Vulnerability Details **File Location**: `index.js`, lines 31-36 **Vulnerability Type**: OS command injection caused by unsafe shell command construction **Risk Level**: High ### Vulnerable Code ```javascript const cmd = ['node', CDP_SCRIPT, command, ...args]; const output = execSync(cmd.join(' '), { cwd: CDP_DIR, encoding: 'utf8', timeout: 30000 }); ``` ### Technical Analysis The `cdp()` function combines an executable, script path, command, and caller-supplied arguments into a single string using `cmd.join(' ')`. It then passes that string to `execSync()`, which evaluates the string through a system shell. Arguments reaching this sink include `targetId`, `selector`, `text`, `url`, and JavaScript `expression` values accepted by exported functions such as `click()`, `type()`, `navigate()`, and `evaluate()`. These values are neither validated nor safely separated from the command line. Consequently, shell metacharacters such as semicolons, command substitutions, redirections, and pipelines can terminate or alter the intended Node.js command. The construction also handles legitimate arguments containing spaces or quotation marks incorrectly. ### Attack Path 1. An attacker influences an argument passed to an exported skill operation, such as the URL supplied to `navigate()` or the expression supplied to `evaluate()`. 2. The exported operation forwards that value to `cdp()` as an element of `args`. 3. `cdp()` concatenates the argument into a shell command without quoting or escaping. 4. `execSync()` invokes the system shell to interpret the resulting command string. 5. Shell syntax embedded in the attacker-controlled argument executes an additional operating-system command. For example, an input structurally equivalent to: ```javascript navigate('abc123', 'https://example.invalid; id > /tmp/cdp-command-output') ``` causes the semicolon and following command to be interpreted by the shell rath ...[truncated 846 chars]
Remediation
## Remediation Suggestions Avoid invoking a shell for argument-based process execution. Replace `execSync()` with `execFileSync()` or `spawnSync()` and pass each argument separately: ```javascript const { execFileSync } = require('child_process'); const output = execFileSync( process.execPath, [CDP_SCRIPT, command, ...args], { cwd: CDP_DIR, encoding: 'utf8', timeout: 30000, shell: false } ); ``` Additional hardening should include: 1. Restrict `command` to an explicit allowlist such as `list`, `shot`, `snap`, `html`, `click`, `type`, `nav`, `eval`, and `net`. 2. Validate target identifiers against the exact format emitted by Chrome CDP. 3. Apply reasonable length limits to selectors, text, URLs, and expressions to reduce denial-of-service exposure. 4. Validate navigation URLs against the intended schemes and destination policy. 5. Preserve arguments as discrete values; do not attempt to repair the issue solely through manual shell escaping. 6. Return sanitized error details so command failures do not unnecessarily expose sensitive paths or process output. 7. Add regression tests using spaces, quotation marks, semicolons, command substitutions, redirections, and newline characters.

T03 · Remote Payload Retrieval and Execution

Warning
Location
README.md:8
Finding
Unpinned Remote Code Retrieval Followed by Local Execution## Vulnerability Details **File Location**: `README.md`, lines 8-13 **Vulnerability Type**: Mutable remote payload retrieval without version or integrity verification **Risk Level**: Medium ### Vulnerable Code The documented installation process retrieves and copies executable content from the repository's mutable default branch: ```bash # Run in the skills/chrome-cdp directory git clone https://github.com/pasky/chrome-cdp-skill.git temp-cdp # Move files mv temp-cdp/skills/chrome-cdp/* ./ rm -rf temp-cdp ``` The copied CDP script is later selected and executed by `index.js`: ```javascript const CDP_SCRIPT = path.join(__dirname, 'scripts', 'cdp.mjs'); function checkCDP() { if (!fs.existsSync(CDP_SCRIPT)) { return { installed: false, message: 'Please clone https://github.com/pasky/chrome-cdp-skill first' }; } return { installed: true }; } ``` ```javascript const cmd = ['node', CDP_SCRIPT, command, ...args]; const output = execSync(cmd.join(' '), { cwd: CDP_DIR, encoding: 'utf8', timeout: 30000 }); ``` ### Technical Analysis The audited artifact does not include the referenced `scripts/cdp.mjs` implementation. Instead, the installation documentation instructs users to clone a remote Git repository without specifying a release tag or immutable commit hash and then copy files into the active skill directory. No cryptographic checksum, signature, lock file, or other integrity control is provided. Therefore, the effective executable payload can change after this artifact has been reviewed. If the upstream repository, maintainer account, release workflow, or network trust chain is compromised, modified JavaScript can be delivered to future installations. This is classified as remote payload retrieval and execution because the installation procedure retrieves mutable remote code and the local wrapper subsequently executes the copied script with Node.js. The wrapper itself doe ...[truncated 1596 chars]
Remediation
## Remediation Suggestions 1. Include the required `scripts/cdp.mjs` implementation directly in the reviewed and distributed artifact. 2. If external retrieval remains necessary, pin the repository to a specific immutable commit hash rather than cloning the mutable default branch. 3. Publish and verify a cryptographic checksum for every retrieved executable file before copying or running it. 4. Prefer signed release artifacts and verify the maintainer signature through a separately established trust mechanism. 5. Update `README.md`, `SKILL.md`, and `_meta.json` so all installation instructions reference the same verified version. 6. Make installation fail closed if the downloaded files do not match the expected digest. 7. Review the pinned `scripts/cdp.mjs` implementation as part of the same security audit. 8. Record the verified dependency version and integrity digest in package metadata to make future audits reproducible.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (13)

Missing User Warnings

High
Confidence
94% confidence
Finding
The skill explicitly states that an AI agent can read and interact with already logged-in Chrome tabs, including sensitive services like Gmail and GitHub, but it does not present a prominent security warning, consent model, or usage restriction. This is dangerous because it normalizes access to authenticated browser sessions, enabling data exfiltration or unintended actions as the user if an agent invokes the skill without fully informed user approval.

Missing User Warnings

High
Confidence
97% confidence
Finding
The documented commands include click, type, nav, and eval, which can alter page state, submit data, navigate away, or execute arbitrary JavaScript in the user's browser context, yet the documentation does not warn about these risks. In the context of a skill connected to live logged-in tabs, these capabilities can directly perform sensitive actions such as sending messages, changing settings, or extracting secrets from active sessions.

Context-Inappropriate Capability

High
Confidence
96% confidence
Finding
The skill exposes an evaluate() function that passes arbitrary JavaScript expressions into a Chrome DevTools Protocol helper, enabling execution in any open tab context. Because open tabs may contain authenticated sessions, sensitive DOM data, or privileged app state, this capability can be used to steal data or perform actions far beyond the stated purpose of merely accessing tabs.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The README instructs users to enable Chrome remote debugging and then demonstrates listing tabs, screenshots, clicking, typing, navigation, and JavaScript execution against an already running browser. In this context, that can expose existing logged-in sessions, page contents, cookies, and the ability to drive authenticated actions, yet the documentation provides no warning about the sensitivity of attaching to a live personal browser.

Natural-Language Policy Violations

Medium
Confidence
89% confidence
Finding
The natural-language instructions throughout the skill file are in Chinese, and the document does not provide an English alternative, a language-selection option, or any justification that the skill is intended only for a Chinese-language environment. Under the stated policy, forcing a specific language without user opt-in is a policy concern.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The manifest advertises capabilities to inspect tabs, capture screenshots, read HTML/accessibility trees, click/type, navigate, execute JavaScript, and access network information, but it provides no user-facing warning about the privacy and security risks of granting this level of browser control. In the context of a Chrome remote-debugging skill, these features can expose sensitive page contents, authenticated sessions, and permit arbitrary actions in the user’s browser, so omission of risk disclosure meaningfully increases the chance of unsafe use.

Missing User Warnings

Medium
Confidence
86% confidence
Finding
The cdp() helper executes a subprocess to control Chrome without any user-facing disclosure that external commands are being run. This matters because the subprocess is not a harmless implementation detail here: it is the mechanism that grants broad access to browser state and can amplify the consequences of unsafe inputs or misuse.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The screenshot function captures page contents and writes them to /tmp/screenshot.png without any user-facing disclosure or controls. Screenshots may contain credentials, personal data, tokens, or business information, and storing them on disk increases exposure beyond transient in-memory access.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The functions exposing HTML, accessibility trees, and network information can reveal page content, hidden text, tokens, request metadata, and other sensitive information from live authenticated sessions. Because the skill targets already-open tabs, the context makes this more dangerous: it inherits the user's existing trust and session state across potentially sensitive sites.

Context-Inappropriate Capability

Medium
Confidence
90% confidence
Finding
The click(), type(), and navigate() functions give the skill active control over browser tabs rather than simple access/inspection. In an authenticated browser session, these actions can submit forms, trigger purchases, change settings, or navigate to phishing pages, creating a meaningful risk of unauthorized actions.

Natural-Language Policy Violations

Low
Confidence
88% confidence
Finding
The instructional content is presented in Chinese only, with no indication that the skill is intended solely for a Chinese-speaking audience and no option for users to choose another language. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy issue.

Natural-Language Policy Violations

Low
Confidence
87% confidence
Finding
The manifest's user-facing description, feature names, and installation text are written in Chinese, which imposes a locale choice without any opt-in or indication that the skill is intended only for a Chinese-speaking audience. Under the policy, language constraints should either offer user choice or be clearly documented as justified.

Natural-Language Policy Violations

Low
Confidence
88% confidence
Finding
The file-level description and returned user messages are written in Chinese, with no indication that language is configurable or intentionally restricted to a specific audience. This may violate language/locale policy where user-facing skills should not force a single language without opt-in.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
index.js:33