fix(browser): block unsafe code patterns in browser evaluate#8818
fix(browser): block unsafe code patterns in browser evaluate#8818yubrew wants to merge 1 commit intoopenclaw:mainfrom
Conversation
| { pattern: /\bsendBeacon\s*\(/i, name: "sendBeacon" }, | ||
| { pattern: /\bnavigator\s*\.\s*sendBeacon/i, name: "navigator.sendBeacon" }, | ||
|
|
There was a problem hiding this comment.
[P1] sendBeacon detection can miss common invocations due to missing \(
In BLOCKED_PATTERNS, the navigator.sendBeacon entry is /\bnavigator\s*\.\s*sendBeacon/i (no \s*\(), so code like navigator.sendBeacon('https://…') won’t match this specific rule. You currently rely on the separate /\bsendBeacon\s*\(/i rule to catch it, but that allows trivial bypasses like navigator['sendBeacon']('…') (won’t hit either rule), and it also means the reported pattern name may be misleading ("sendBeacon" vs "navigator.sendBeacon"). Consider aligning the navigator.sendBeacon rule with the comment’s intent (function call detection) or removing it if redundant.
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/browser/pw-evaluate-validation.ts
Line: 35:37
Comment:
[P1] `sendBeacon` detection can miss common invocations due to missing `\(`
In `BLOCKED_PATTERNS`, the `navigator.sendBeacon` entry is `/\bnavigator\s*\.\s*sendBeacon/i` (no `\s*\(`), so code like `navigator.sendBeacon('https://…')` won’t match this specific rule. You currently rely on the separate `/\bsendBeacon\s*\(/i` rule to catch it, but that allows trivial bypasses like `navigator['sendBeacon']('…')` (won’t hit either rule), and it also means the reported pattern name may be misleading ("sendBeacon" vs "navigator.sendBeacon"). Consider aligning the `navigator.sendBeacon` rule with the comment’s intent (function call detection) or removing it if redundant.
How can I resolve this? If you propose a fix, please make it concise.
Additional Comments (1)
Prompt To Fix With AIThis is a comment left during a code review.
Path: src/browser/pw-tools-core.interactions.ts
Line: 226:232
Comment:
[P2] New validation rejects any `fetch(`/`eval(`/etc. substring, even inside string literals/comments
`assertSafeEvaluateCode(fnText)` runs on the raw text and the validators intentionally can’t distinguish code vs. strings/comments. This means previously-valid snippets like `() => "call fetch('…')"` or docs/examples embedded in strings will now hard-fail, which could be a breaking behavior change for callers of `act:evaluate` (see `src/browser/routes/agent.act.ts:293`). If that’s intended, it may be worth documenting at the API boundary or adjusting tests to explicitly cover/acknowledge the breaking case.
How can I resolve this? If you propose a fix, please make it concise. |
| constructor(pattern: string, code: string) { | ||
| const truncated = code.length > 50 ? code.slice(0, 50) + "..." : code; | ||
| super( | ||
| `Unsafe browser code blocked: Contains "${pattern}" which is not allowed for security reasons. ` + | ||
| `Code preview: ${truncated}`, | ||
| ); |
There was a problem hiding this comment.
[P1] Error message includes unescaped user code preview, which can leak secrets and/or enable log injection.
UnsafeEvaluateCodeError includes a Code preview: ${truncated} string built directly from the user-supplied code (pw-evaluate-validation.ts:14-19). If callers log this error (or bubble it to users), the preview can contain credentials/cookies/PII and can include newlines/control characters that make logs misleading. Consider redacting obvious sensitive fields and/or sanitizing control characters before embedding the preview.
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/browser/pw-evaluate-validation.ts
Line: 14:19
Comment:
[P1] Error message includes unescaped user code preview, which can leak secrets and/or enable log injection.
`UnsafeEvaluateCodeError` includes a `Code preview: ${truncated}` string built directly from the user-supplied `code` (`pw-evaluate-validation.ts:14-19`). If callers log this error (or bubble it to users), the preview can contain credentials/cookies/PII and can include newlines/control characters that make logs misleading. Consider redacting obvious sensitive fields and/or sanitizing control characters before embedding the preview.
How can I resolve this? If you propose a fix, please make it concise.
Additional Comments (1)
If the goal is to prevent the dangerous runtime APIs ( Prompt To Fix With AIThis is a comment left during a code review.
Path: src/browser/pw-tools-core.interactions.ts
Line: 226:231
Comment:
[P0] `evaluateViaPlaywright` now rejects *all* uses of `eval(`, which breaks the intended “function string” input format.
`fnText` is expected to look like `(el) => ...` or `() => ...`, and the implementation always runs `eval("(" + fnBody + ")")` in the browser context (see `pw-tools-core.interactions.ts:246` and `:263`). With the new validator, any user-provided function body containing the substring `eval(` (even as a method name, variable, comment, or string literal) will be blocked, which is a behavioral breaking change for legitimate evaluate code (e.g. `(el) => el.dataset.eval(...)`, `obj.eval(...)`, or even string content).
If the goal is to prevent the *dangerous runtime APIs* (`fetch`, `WebSocket`, etc.), consider narrowing the `eval` pattern to the “direct eval call” in user code only, or explicitly document that any appearance of these tokens anywhere (including strings/comments) is disallowed.
How can I resolve this? If you propose a fix, please make it concise. |
Add code validation to `evaluateViaPlaywright` to block dangerous patterns that could be used for data exfiltration or code injection. An attacker controlling the code (via prompt injection) could use APIs like `fetch()`, `WebSocket`, or `navigator.sendBeacon()` to exfiltrate cookies, credentials, and sensitive data from the browser context. Blocked patterns include: - Data exfiltration: fetch, XMLHttpRequest, WebSocket, sendBeacon - Code execution: eval, new Function, setTimeout/setInterval with strings - Module loading: dynamic import, importScripts Reference: CWE-95 (Improper Neutralization of Directives in Dynamically Evaluated Code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
42532ec to
b6c9024
Compare
bfc1ccb to
f92900f
Compare
|
This pull request has been automatically marked as stale due to inactivity. |
This comment was marked as spam.
This comment was marked as spam.
|
Closing this PR because the author has more than 10 active PRs in this repo. Please reduce the active PR queue and reopen or resubmit once it is back under the limit. You can close your own PRs to get back under the limit. |
Summary
Adds code validation to
evaluateViaPlaywrightto block dangerous patterns that could be used for data exfiltration or code injection.The Problem
The browser automation
evaluatefunction executes user-provided JavaScript code without any validation. An attacker controlling the code (via prompt injection) could use APIs likefetch(),WebSocket, ornavigator.sendBeacon()to exfiltrate cookies, credentials, and sensitive data from the browser context.Reference: CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code
Changes
src/browser/pw-evaluate-validation.ts: New validation module with blocklist of dangerous patternssrc/browser/pw-tools-core.interactions.ts: Add validation call before code executionsrc/browser/pw-evaluate-validation.test.ts: Unit tests for validation logic (29 tests)src/browser/pw-tools-core.evaluate-blocks-unsafe.test.ts: Integration tests (13 tests)Blocked patterns:
fetch,XMLHttpRequest,WebSocket,sendBeaconeval,new Function,setTimeout/setIntervalwith stringsimport,importScriptsTest Plan
pnpm build && pnpm check && pnpm testpassesevaluateViaPlaywrightrejects unsafe codeRelated
Built with bitsec-ai. AI-assisted: Yes. Testing: fully tested (test written before fix). Code reviewed and understood.
Greptile Overview
Greptile Summary
Adds a pre-execution validation step for
evaluateViaPlaywrightto reject browser-evaluated code containing a set of blocked “dangerous” patterns (exfiltration APIs, dynamic code execution, and module loading). This is implemented via a newpw-evaluate-validation.tsmodule and covered by unit tests for the validator plus integration tests that ensure unsafefnstrings are rejected before interacting with a Playwright page.Confidence Score: 3/5
eval(token is likely to break legitimate evaluate snippets given this function always usesevalinternally, and (2) the error message currently echoes user code which can leak sensitive data into logs. No other obvious correctness issues were found in the touched paths.