Back to skill

Security audit

Web Access Skill

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed browser-automation tool, but it exposes broad unauthenticated control over the user's logged-in Chrome session and local file interactions, so it should receive careful review before installation.

Install only if you are comfortable giving an agent broad control over a logged-in Chrome session. Prefer a separate Chrome profile or test account, stop the proxy when not needed, avoid using it on banking/email/admin sites, and require explicit confirmation before uploads, form submissions, posts, purchases, screenshots, or actions on existing tabs.

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

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/cdp-proxy.mjs:275
Finding
Unauthenticated Local API Provides Full Control of the User's Authenticated Browser<![CDATA[ ## Vulnerability Details **File Location**: `scripts/cdp-proxy.mjs:275-562`; persistent startup behavior in `scripts/check-deps.mjs:97-107` **Vulnerability Type**: Missing authentication and insufficient authorization on a privileged browser-control API **Risk Level**: High ### Code Snippet ```javascript if (pathname === '/targets') { const resp = await sendCDP('Target.getTargets'); const pages = resp.result.targetInfos.filter(t => t.type === 'page'); res.end(JSON.stringify(pages, null, 2)); } ``` ```javascript else if (pathname === '/eval') { const sid = await ensureSession(q.target); const body = await readBody(req); const expr = body || q.expr || 'document.title'; const resp = await sendCDP('Runtime.evaluate', { expression: expr, returnByValue: true, awaitPromise: true, }, sid); if (resp.result?.result?.value !== undefined) { res.end(JSON.stringify({ value: resp.result.result.value })); } else if (resp.result?.exceptionDetails) { res.statusCode = 400; res.end(JSON.stringify({ error: resp.result.exceptionDetails.text })); } else { res.end(JSON.stringify(resp.result)); } } ``` ```javascript server.listen(PORT, '127.0.0.1', () => { console.log(`[CDP Proxy] Running at http://localhost:${PORT}`); connect().catch(e => console.error( '[CDP Proxy] Initial connection failed:', e.message )); }); ``` The proxy is also launched as a detached process: ```javascript const child = spawn(process.execPath, [PROXY_SCRIPT], { detached: true, stdio: ['ignore', logFd, logFd], ...(os.platform() === 'win32' ? { windowsHide: true } : {}), }); child.unref(); ``` ### Technical Analysis The proxy binds only to `127.0.0.1`, which reduces remote network exposure, but it does not authenticate callers or authorize individual operations. Any local process able to connect to the configured port can invoke all API endpoints. The exposed operations include: - Enumerating all existing browser tabs throug ...[truncated 2316 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Generate a cryptographically random bearer token each time the proxy starts and require it on every endpoint, including `/health`. 2. Store the token in a user-only file with restrictive permissions or pass it directly to the authorized client. 3. Prefer a private Unix-domain socket with user-only permissions on supported systems. 4. Track tabs created by the proxy and deny access to pre-existing tabs by default. 5. Require explicit, operation-specific user approval before accessing existing tabs, uploading files, submitting forms, or invoking other state-changing actions. 6. Add method allowlists and capability separation instead of exposing unrestricted `Runtime.evaluate`. 7. Reject requests carrying browser `Origin` headers unless an explicitly trusted origin is configured. 8. Use an unpredictable port in addition to authentication; port randomization must not replace authentication. 9. Terminate the proxy when the task ends, or implement a short inactivity timeout and automatic shutdown. 10. Log privileged operations without recording page content, credentials, session tokens, or submitted JavaScript containing secrets. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/cdp-proxy.mjs:482
Finding
Caller-Controlled Screenshot Path Allows Arbitrary User-Writable File Overwrite<![CDATA[ ## Vulnerability Details **File Location**: `scripts/cdp-proxy.mjs:482-491` **Vulnerability Type**: Unrestricted filesystem path used for synchronous file creation or overwrite **Risk Level**: High ### Code Snippet ```javascript else if (pathname === '/screenshot') { const sid = await ensureSession(q.target); const format = q.format || 'png'; const resp = await sendCDP('Page.captureScreenshot', { format, quality: format === 'jpeg' ? 80 : undefined, }, sid); if (q.file) { fs.writeFileSync(q.file, Buffer.from(resp.result.data, 'base64')); res.end(JSON.stringify({ saved: q.file })); } else { res.setHeader('Content-Type', 'image/' + format); res.end(Buffer.from(resp.result.data, 'base64')); } } ``` ### Technical Analysis The `/screenshot` endpoint accepts a complete filesystem path from the `file` query parameter and passes it directly to `fs.writeFileSync`. No validation or confinement is applied. The implementation does not: - Restrict output to a dedicated screenshot directory - Canonicalize and validate the destination path - Reject absolute paths or traversal sequences - Prevent following symbolic links - Prevent overwriting existing files - Use exclusive file creation - Restrict the destination extension - Require authentication before performing the write `fs.writeFileSync` overwrites an existing file by default where the proxy process has permission. Although the bytes originate from a screenshot rather than arbitrary caller-supplied binary content, an attacker can substantially influence the image by navigating a controlled tab to attacker-selected visual content. Saving screenshots to arbitrary locations is not required for the core browsing functionality. Returning image bytes or using server-generated temporary filenames would provide the needed capability with substantially less privilege. ### Attack Path 1. The CDP proxy is running with the user's filesystem permissions. 2. A malicious local pro ...[truncated 1197 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the caller-controlled `file` parameter and return screenshot bytes directly where possible. 2. If local persistence is necessary, create a dedicated screenshot directory with permissions limited to the current user. 3. Generate filenames on the server rather than accepting full paths from callers. 4. Resolve the canonical destination and verify that it remains inside the dedicated directory. 5. Reject absolute paths, traversal components, symbolic links, and unsupported extensions. 6. Open files with exclusive creation semantics to avoid silently overwriting existing files. 7. Apply restrictive permissions to newly created files. 8. Authenticate and authorize the screenshot endpoint. 9. Delete temporary screenshots automatically after a short retention period. ]]>

other

Warning
Location
SKILL.md:56
Finding
Third-Party Jina Routing Can Disclose Sensitive or Session-Bearing URLs<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:56`; related URL-preservation guidance at `SKILL.md:119-120` **Vulnerability Type**: Potential disclosure of sensitive URLs to a third-party network service **Risk Level**: Medium ### Relevant Instruction Snippet The Skill recommends Jina as an optional third-party preprocessing layer and instructs the Agent to prefix a destination with: ```text r.jina.ai/example.com ``` It also separately instructs the Agent to preserve complete site-generated URLs, including session-related parameters such as tokens, when those parameters may be required for navigation. ### Technical Analysis Jina is explicitly identified as a third-party network service. Routing a URL through it discloses the complete destination to that service and may cause Jina to retrieve the referenced resource from its own infrastructure. The instructions encourage active use of Jina to reduce token consumption but do not establish a prohibition against forwarding: - Signed download links - URLs containing access tokens or session identifiers - Private document links - Password-reset or invitation links - Internal or intranet hostnames - Authenticated resource identifiers - URLs containing personal or confidential query data This is particularly risky because another section tells the Agent to preserve complete URLs, including token-bearing parameters. Without an explicit data-classification rule, these two instructions can combine into accidental third-party disclosure. The service is optional and is not necessary for the Skill's fundamental web-access functionality. Direct first-party fetching can process public resources without introducing this additional recipient. ### Attack Path 1. The Agent extracts a complete URL from a page or user request. 2. The URL contains a signed query parameter, access token, private identifier, or other sensitive data. 3. Following the Skill's efficiency guidance, the Agent selects Jina as a pr ...[truncated 795 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Prohibit third-party preprocessing for authenticated, private, signed, intranet, local, or token-bearing URLs. 2. Detect and reject sensitive query parameters such as tokens, signatures, keys, session identifiers, invitation codes, and password-reset values. 3. Strip nonessential query parameters before submitting public URLs to a third party. 4. Require explicit user consent before sending a user-provided URL to Jina or another external preprocessing service. 5. Clearly disclose the third-party recipient and the data that will be sent. 6. Prefer direct first-party retrieval through WebFetch or `curl` for potentially sensitive destinations. 7. Maintain an allowlist of public schemes and domains eligible for third-party preprocessing. 8. Never send localhost, private-address, link-local, or intranet destinations to external fetch services. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (28)

Vague Triggers

High
Confidence
95% confidence
Finding
The trigger scope is extremely broad, effectively routing nearly any web-related request through a high-privilege browsing skill. Because this skill can access logged-in browser context and perform interactive actions, overbroad invocation materially increases the chance that routine tasks are executed with unnecessary privileges and privacy exposure.

Missing User Warnings

High
Confidence
97% confidence
Finding
The skill directs use of the user's normal Chrome session, inheriting existing authentication cookies and account state, but does not require a clear warning or consent flow about privacy and account-impact risks. In this context, the skill can access personal data, paid services, or perform actions as the user, making the omission especially dangerous.

Context-Inappropriate Capability

High
Confidence
99% confidence
Finding
The /eval endpoint exposes arbitrary JavaScript execution inside the user's real, logged-in Chrome session via CDP Runtime.evaluate. That allows reading page content, DOM data, tokens accessible to the page, and performing arbitrary in-page actions on any open target, which substantially exceeds a narrowly scoped web-access proxy and turns the service into a general browser-compromise interface.

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
The /clickAt endpoint uses browser-level input dispatch to simulate trusted mouse gestures, explicitly noting it can trigger file dialogs and bypass anti-automation detection. In the context of a real user Chrome session, this can be used to activate privileged UI flows and perform sensitive actions that sites gate behind genuine user interaction.

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
The /setFiles endpoint can programmatically inject arbitrary local filesystem paths into file inputs in websites loaded in the user's real browser session. This creates a bridge from local files to remote websites without meaningful user mediation, enabling unintended exfiltration of sensitive local documents through ordinary upload forms.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The README explicitly promotes connecting to the user's everyday Chrome and reusing its logged-in session for automation, but does not warn that the agent may gain access to authenticated sites, personal data, cookies, or perform account actions as the user. In the context of an automation skill, this omission materially increases the chance of unsafe deployment because users may not understand the privacy and account-integrity implications before enabling it.

External Transmission

Medium
Category
Data Exfiltration
Content
node "$CLAUDE_SKILL_DIR/scripts/cdp-proxy.mjs" &

# 页面操作
curl -s "http://localhost:3456/new?url=https://example.com"     # 新建 tab
curl -s -X POST "http://localhost:3456/eval?target=ID" -d 'document.title'  # 执行 JS
curl -s -X POST "http://localhost:3456/click?target=ID" -d 'button.submit'  # JS 点击
curl -s -X POST "http://localhost:3456/clickAt?target=ID" -d '.upload-btn'  # 真实鼠标点击
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The README provides examples of posting content, uploading files, and operating creator platforms through browser automation without any safety guidance about irreversible or externally visible actions. In a skill designed to automate real websites with live credentials, this can lead to unintended publication, data leakage, or account misuse if the agent acts incorrectly or the task is ambiguous.

External Transmission

Medium
Category
Data Exfiltration
Content
## Star History

[![Star History Chart](https://api.star-history.com/svg?repos=eze-is/web-access&type=Date)](https://star-history.com/#eze-is/web-access&Date)

<img width="1280" height="306" alt="image" src="https://github.com/user-attachments/assets/2afa25c2-3730-413e-b40f-94e52567249d" />
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Lp3

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding
The skill exposes capabilities that can access environment variables and perform network operations, but it does not declare any explicit tool scope or permission boundary. In a skill designed for broad web interaction, this omission makes it harder to constrain what the agent may access or transmit and increases the blast radius of prompt misuse or implementation mistakes.

Natural-Language Policy Violations

Medium
Confidence
83% confidence
Finding
Core activation and operational instructions are presented in Chinese, and the skill does not indicate that users may choose another language or that the locale is intentionally restricted to a Chinese-speaking environment. This can amount to an implicit language policy constraint without opt-in.

External Transmission

Medium
Category
Data Exfiltration
Content
| 非公开内容,或已知静态层无效的平台(小红书、微信公众号等公开内容也被反爬限制) | **浏览器 CDP**(直接,跳过静态层) |
| 需要登录态、交互操作,或需要像人一样在浏览器内自由导航探索 | **浏览器 CDP** |

浏览器 CDP 不要求 URL 已知——可从任意入口出发,通过页面内搜索、点击、跳转等方式找到目标内容。WebSearch、WebFetch、curl 均不处理登录态。

**Jina**(可选预处理层,可与 WebFetch/curl 组合使用,由于其特性可节省 tokens 消耗,请积极在任务合适时组合使用):第三方网络服务,可将网页转为 Markdown,大幅节省 token 但可能有信息损耗。调用方式为 `r.jina.ai/example.com`(URL 前加前缀,不保留原网址 http 前缀),限 20 RPM。适合文章、博客、文档、PDF 等以正文为核心的页面;对数据面板、商品页等非文章结构页面可能提取到错误区块。
Confidence
84% confidence
Finding
The skill encourages use of Jina, a third-party network service that receives target URLs and page content for transformation. Sending browsing targets or retrieved content to an external processor can disclose sensitive URLs, tokens embedded in links, proprietary documents, or user-intended research activity, and the guidance does not require sanitization or user consent.

Intent-Code Divergence

Medium
Confidence
82% confidence
Finding
Although the guidance says not to affect user tabs, the documented API explicitly allows enumerating existing tabs and operating against arbitrary target IDs. That discrepancy weakens isolation guarantees and could lead to reading from or interacting with the user's already-open sessions, exposing sensitive content or causing unintended account actions.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The skill documents file upload via browser automation without an accompanying safety warning or consent requirement. This can lead to accidental transmission of local files to external sites, which is a direct data-exfiltration risk, especially when the same skill already has broad browser and network privileges.

Context-Inappropriate Capability

Medium
Confidence
92% confidence
Finding
The skill instructs the agent to persist and update per-site knowledge files locally, which introduces stateful file modification beyond the core purpose of fetching web content. This creates an unnecessary write capability that could be abused to store sensitive browsing-derived data, poison future agent behavior, or make stealthy persistent changes to the local workspace.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The skill instructs the agent to automatically write or update local reference files without informing the user that local files will be modified. Silent local persistence increases the risk of unauthorized workspace changes, retention of potentially sensitive site-derived information, and durable prompt-influence over future runs.

External Transmission

Medium
Category
Data Exfiltration
Content
### GET /health
健康检查,返回连接状态。
```bash
curl -s http://localhost:3456/health
```

### GET /targets
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The documented /setFiles endpoint explicitly supports setting arbitrary local file paths into a browser file input and states it can bypass the file chooser entirely. In a web-access skill, this materially increases the risk of unintended local file disclosure because the normal user-mediated consent boundary of the OS file picker is removed and the documentation provides no warning, restriction, or confirmation requirement.

Intent-Code Divergence

Medium
Confidence
86% confidence
Finding
The comment indicates the design deliberately avoids Chrome security prompts while still seeking remote-debugging access to the user's normal browser. That combination is risky because it minimizes visible signals to the user while preserving full CDP control, reducing opportunities for the user to notice or stop sensitive browser automation.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
This endpoint enables sensitive browser-level clicks that may trigger uploads, purchases, consent dialogs, or other high-risk actions, yet there is no user-facing disclosure or confirmation. In a skill intended for web access, silent execution of such actions makes misuse and accidental harm significantly more likely.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
Programmatically setting local files for upload is a sensitive cross-boundary action from the local filesystem to a remote web page, but the proxy provides no disclosure or consent mechanism. Without a prominent warning, users may not realize which local files are being attached to a website or that uploads are being automated at all.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
The file contains user-facing comments and console output in Chinese, including warnings and setup instructions, without any indication that the skill is intentionally China-specific or that users can choose another language. This can violate language/locale policy when a skill imposes a specific language without opt-in.

Natural-Language Policy Violations

Low
Confidence
77% confidence
Finding
All headings and operational guidance are presented only in Chinese, and the file does not offer an alternative language or state that the skill is intentionally limited to a Chinese-speaking audience. Under the policy, forcing a specific language without user opt-in can be a natural-language policy issue.

Missing User Warnings

Low
Confidence
88% confidence
Finding
The screenshot API allows saving page content directly to a local file, which can persist sensitive on-screen data to disk without any warning about retention, access control, or cleanup. In a browsing automation skill that may access logged-in sessions and private pages, this creates a real confidentiality risk if screenshots capture secrets, personal data, or account information.

Natural-Language Policy Violations

Low
Confidence
84% confidence
Finding
The file's descriptive comments and user-facing operational guidance are written exclusively in Chinese, with no indication of language choice or opt-in. Under the stated policy, forcing a specific language without user choice can constitute a locale/language policy violation unless clearly justified.

Static analysis

Detected: suspicious.dangerous_exec, suspicious.env_credential_access

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/check-deps.mjs:98

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/check-deps.mjs:13