Announcing Beacon: Self-improving memory for coding agents
← All skills
Skill

browser-use

skill:steipete/agent-scripts#browser-use

Control the user's existing signed-in Chrome: callable Codex Chrome plugin first, then OpenClaw extension-backed mcporter, with direct DevTools attachment only as a last fallback.

Verdict
Suspicious

Risky behavior the analysis could not rule out.

Analyzed Oct 27, 2026, 22:27 UTC at 1159adf

Dispute security verdict

If you believe this verdict is incorrect, submit a dispute and we'll review it.

4
findings
medium
highest severity
2
threat classes
228
files scanned
56/63
checks satisfied
0
package advisories

Why this verdict

  • suspicious: finding skill:skills/browser-use:skills/browser-use/SKILL.md:283:PRIVESC
  • suspicious: finding skill:skills/browser-use:skills/browser-use/auto-allow.py:2:PRIVESC
  • suspicious: finding skill:skills/browser-use:skills/browser-use/mcporter-config.md:45:SUPPLY
  • suspicious: finding skill:skills/browser-use:skills/browser-use/mcporter-config.md:46:SUPPLY

Security findings 4

Privilege escalation

mediumContextual riskmedium confidence

The bundled script auto-allow.py watches for Chrome's 'Allow remote debugging?' consent sheet and automatically presses its Allow button, defeating Chrome's user-consent gate for full-profile remote debugging attachment.

Watch Chrome for the 'Allow remote debugging?' sheet and press its Allow button (rightmost enabled button inside the sheet).
trigger:conditionalvector:code
Counter-argument considered

The served SKILL.md range answers my earlier request: it never references auto-allow.py and contains no warning or mitigation about auto-approving the consent sheet, while the script's own code confirms it scans Chrome's accessibility tree for the 'Allow remote debugging' sheet and silently clicks its Allow button via clicick-style automation, defeating the user-consent gate for full-profile remote debugging. That consent-gate defeat is not any carve-out and is not declared in the target description (which only declares plugin/mcporter first and direct DevTools attachment as a last fallback), so no gate fails and the finding stands.

Supply chain

mediumContextual risklow confidence

The skill's mcporter server definitions launch chrome-devtools-mcp via unpinned npx -y with no version, so the MCP server code executed against the user's signed-in Chrome profile is fetched mutably at runtime, an undeclared supply-chain surface for a skill reviewed at a pinned commit.

--command npx --arg -y --arg chrome-devtools-mcp
vector:instruction
Counter-argument considered

Line 45 registers the chrome-isolated variant, so the claim's 'signed-in Chrome profile' wording overstates for this exact line, but the core supply-chain point holds: the instructed command launches chrome-devtools-mcp via unpinned `npx -y` with no version, a mutable fetch-and-execute surface outside the pinned-install carve-out and undeclared anywhere.

Supply chain

mediumContextual riskmedium confidence

mcporter-config.md instructs registering the chrome-devtools MCP server via 'npx -y chrome-devtools-mcp' with no version pin, causing an unpinned remote npm package to be fetched and executed as a persistent MCP server attached to the user's real Chrome profile.

mcporter config add chrome-devtools --scope home --command npx --arg -y --arg chrome-devtools-mcp
vector:instruction
Counter-argument considered

The instructed home-scope registration launches chrome-devtools-mcp via unpinned `npx -y` at daemon start against the real-profile userDataDir, is outside the pinned-install carve-out, has no pinning declaration or mitigation, and is a concrete command the agent is told to run, so all gates hold.

Privilege escalation

mediumContextual riskmedium confidence

SKILL.md instructs the agent to approve Chrome's 'Allow remote debugging?' security consent prompt itself to enable full-profile direct attachment rather than leaving that consent decision to the user.

When a visible, unambiguous Chrome prompt asks to allow the attachment, approve
trigger:conditionalvector:instruction
Counter-argument considered

Having the agent click through Chrome's own 'Allow remote debugging?' consent sheet is an override of a user-consent control not covered by any declared claim or by the declared description (which declares only the attachment fallback); the once/unambiguous bounds and stop-and-ask only for absent/ambiguous prompts bound but do not neutralize the self-approval, so the finding stands.

Open questions 7

What the analysis could not settle from the code alone.

Do the documented 'MCPORTER_CHROME_DEVTOOLS_RELAY_POLICY=require' shell-environment-prefix calls actually enforce relay-only policy, given the same document states the daemon strips inherited MCPORTER_CHROME_DEVTOOLS_RELAY_* controls from the canonical Chrome environment? The detector-claimed contradictions (file_write 'document.title}', '--schema', file_read of the Chrome profile dir) were checked and not confirmed against the cited units.
No unit shown references auto-allow.py; nothing in SKILL.md or mcporter-config.md invokes it, so what mechanism (hook, installer, other file, or manual run) triggers this auto-approval loop is not established from the shown evidence.
Privilege escalation
No unit shown references or invokes auto-allow.py; it is unclear whether this consent-sheet auto-clicker is wired into the skill's instructions or is dead code. The unshown span of SKILL.md (lines 42-96) may invoke it.
Code execution
Detector leads DET:0382c6234175a37e, DET:81c3e5ca00fc8fd6, and DET:d76c6aa4e2d9bee0 allege claim contradictions (file_write 'document.title', file_write '--schema', file_read of the Chrome directory), but the quoted excerpts are example mcporter tool-call arguments in documentation, not actual writes or reads; no contradiction could be confirmed in the cited unit text.
[file request skills/browser-use/auto-allow.py] What does the full body of auto-allow.py do: does it automatically press Allow on Chrome's 'Allow remote debugging?' sheet without user interaction, does it poll/loop for the sheet, and what mechanism does it use to click the button?
Privilege escalation
[file request skills/browser-use/README.md] Does README.md reference or instruct running auto-allow.py, or register any hook or automation that would execute it?
Privilege escalation
[file request skills/browser-use] Does any other file shipped with this skill (README, hooks, install scripts, or other docs) reference or invoke auto-allow.py, and does any hook or settings configuration trigger it automatically?
Privilege escalation
Refuted findings 4

Candidates the review stage examined and rejected, kept for transparency.

Persistence

criticalRefutedmedium confidence

SKILL.md instructs the agent to merge chromeDevtoolsRelay policy and env settings into the user's canonical global mcporter MCP configuration (~/.mcporter/mcporter.json), a persistent write to tool control-plane configuration that outlives the session (the shown values are hardening: relay-required policy and a timeout).

Merge these fields into its existing Chrome definition, preserving its command,
Why it was refuted

The instructed write openly merges hardening values (relay-require policy plus a discovery timeout) into the canonical mcporter definition while preserving existing command and args; it is the declared enforcement mechanism of the declared extension-backed mcporter route, so the harm and undeclared gates fail.

Persistence

criticalRefutedlow confidence

SKILL.md instructs the agent to merge chromeDevtoolsRelay and env settings into the user's canonical global ~/.mcporter/mcporter.json and to stop and respawn the mcporter daemon so the new settings persist, rewriting agent tooling's MCP control-plane configuration outside the workspace (a capability the declared description does not mention).

Merge these fields into its existing Chrome definition, preserving its command,
Why it was refuted

This is the same openly instructed write as line 109 plus a daemon stop/respawn cycle the body itself declares; the merged values are hardening and the persistence behavior is declared in the body, so the harm and undeclared gates fail.

Tool poisoning

criticalRefutedlow confidence

SKILL.md and mcporter-config.md forbid the agent from using isolated browsers, Playwright, Puppeteer, AppleScript, or chrome-isolated as substitutes and forbid switching to them when automation fails unless the user explicitly asks, steering all browser automation onto the user's credentialed real profile even when isolation would be safer.

Never use isolated Chrome, the Codex in-app browser, Playwright, Puppeteer,
Why it was refuted

Steering browser automation onto the real signed-in profile is the skill's declared core capability, the prohibition carries an explicit user-consent escape ('unless the user explicitly asks'), and the isolated escape hatch remains documented, so the harm and undeclared gates fail.

Persistence

criticalRefutedmedium confidence

SKILL.md instructs running 'openclaw browser extension install', which copies an extension to an OpenClaw-owned path and pre-registers its deterministic Chrome ID as a native messaging host in the user's Chrome profile, a persistent host-config registration performed as skill setup.

Run `openclaw browser extension install` before **Load unpacked**. It copies
Why it was refuted

The host registration is performed by the OpenClaw vendor CLI as the explicitly declared setup step for the declared extension-backed mcporter route, openly described in the body, not an agent-authored persistence mechanism, so the harm and undeclared gates fail.

Coverage gaps 26

Parts of the artifact the static analysis could not fully examine.

context:symlink_escape target '../../agent-skills/skills/autoreview' leaves the repository root
skills/autoreview
context:symlink_escape target '../../agent-skills/skills/behavior-validator' leaves the repository root
skills/behavior-validator
context:symlink_escape target '../../birdclaw/.agents/skills/birdclaw' leaves the repository root
skills/birdclaw
context:symlink_escape target '../../agent-skills/skills/crabbox' leaves the repository root
skills/crabbox
context:symlink_escape target '../../discrawl/.agents/skills/discrawl' leaves the repository root
skills/discrawl
context:symlink_escape target '../../gitcrawl/.agents/skills/gitcrawl' leaves the repository root
skills/gitcrawl
context:symlink_escape target '../../gogcli/.agents/skills/gog' leaves the repository root
skills/gog
context:symlink_escape target '../../graincrawl/.agents/skills/graincrawl' leaves the repository root
skills/graincrawl
context:symlink_escape target '../../agent-skills/skills/handoff' leaves the repository root
skills/handoff
context:symlink_escape target '../../imsg/.agents/skills/imsg' leaves the repository root
skills/imsg
context:symlink_escape target '../../peekaboo/skills/peekaboo' leaves the repository root
skills/peekaboo
context:symlink_escape target '../../agent-skills/skills/session-viewer' leaves the repository root
skills/session-viewer
context:symlink_escape target '../../slacrawl/.agents/skills/slacrawl' leaves the repository root
skills/slacrawl
context:symlink_escape target '../../wacli/.agents/skills/wacli' leaves the repository root
skills/wacli
context:symlink_escape target '../../wacrawl/.agents/skills/wacrawl' leaves the repository root
skills/wacrawl
ledger_finding_without_valid_finding run 1: declared-vs-actual.0 SRC:60b37f1bef9d6af5
ledger_finding_without_valid_finding run 1: declared-vs-actual.0 SRC:bd5581c1348a225a
ledger_finding_without_valid_finding run 1: declared-vs-actual.0 SRC:4c599664be206e35
ledger_finding_without_valid_finding run 1: behavior-chains.0 SRC:60b37f1bef9d6af5
ledger_finding_without_valid_finding run 1: behavior-chains.0 SRC:bd5581c1348a225a
ledger_finding_without_valid_finding run 1: behavior-chains.0 SRC:4c599664be206e35
ledger_finding_without_valid_finding run 1: behavior-chains.0 SRC:11895f068e480c2c
invalid_judge_finding declared-vs-actual.0
invalid_judge_finding behavior-chains.0
request_unanswered request.0: instruction-surface.0/autoallow-body: finding: no valid finding cites the answer's evidence
invalid_judge_finding request.0