Skip to content

fix(security): align browser audit with plugin policy#97732

Merged
steipete merged 4 commits into
openclaw:mainfrom
amtellezfernandez:fix/security-audit-browser-summary-policy
Jul 7, 2026
Merged

fix(security): align browser audit with plugin policy#97732
steipete merged 4 commits into
openclaw:mainfrom
amtellezfernandez:fix/security-audit-browser-summary-policy

Conversation

@amtellezfernandez

@amtellezfernandez amtellezfernandez commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

What Problem This Solves

openclaw security audit could report browser control: enabled and flag Browser exposure for small-model agents even when global plugin policy prevented the bundled Browser plugin from running. The summary treated omitted Browser config as enabled without applying plugins.enabled, plugins.allow, plugins.deny, or plugins.entries.browser.enabled.

Why This Change Was Made

The rewritten change uses the existing canonical manifest-owner base policy instead of duplicating plugin-policy rules in security code. Browser plugin ids are normalized case-insensitively, matching startup behavior, and one shared predicate now drives both:

  • summary.attack_surface Browser-control reporting
  • models.small_params Browser-tool exposure reporting

Global plugin policy remains authoritative. Explicit browser config selects Browser behavior but does not bypass a restrictive plugin allowlist; operators who use plugins.allow must include browser to expose Browser control.

This does not change the per-agent trust boundary. The small-model check still evaluates each agent's sandbox and tool policy independently after global Browser availability is established.

User Impact

  • Restrictive plugin configurations no longer receive a false Browser-enabled summary.
  • Small agents no longer receive a false web=[browser] risk classification when Browser is globally unavailable.
  • Mixed-case Browser/BROWSER policy entries are interpreted the same way as Gateway startup.
  • Explicitly allowed Browser configurations keep full Browser functionality.
  • No config, schema, migration, protocol, or runtime enablement behavior changes.

Evidence

Final PR head: a2ad2c8e12e2e5f95bc1dafaa689f1342c222596

  • Focused remote suite: pnpm test src/security/audit-summary.test.ts src/security/audit-extra.sync.test.ts — 16/16 passed.
  • Sanitized direct-AWS run run_3fb78ed75c91 on fresh public-network lease cbx_58fe8eb9e642 (brisk-krill, c7a.8xlarge) exercised the exact pre-rebase head c98ea86a471667056ad20e8c5e88462243376b59.
  • The live-proven pre-rebase head and final head have the identical src/security/** stable patch id d87df79373b19924dc57e146d0f084e0dbb3a9c9; later changes only rebased onto current main and removed the release-owned root changelog line required by native prepare policy.
  • Restrictive state (plugins.allow=["openai"]): audit reported browser control: disabled, the small agent reported web=[off], Browser inventory was disabled, a real Gateway started, and an openai/gpt-5.4 agent returned SECURITY_POLICY_OK.
  • Explicitly allowed state (plugins.allow=["openai","browser"], browser.enabled=true): audit reported browser control: enabled, the small agent reported web=[browser], a real Gateway and managed Chrome started, and an openai/gpt-5.4 agent used the Browser tool against the live page and returned SECURITY_BROWSER_OK.
  • Fresh final-head autoreview against origin/main: no accepted/actionable findings, confidence 0.86.
  • Exact-head hosted CI: all selected checks passed on a2ad2c8e12e2e5f95bc1dafaa689f1342c222596.

Scope

This is an audit-reporting correction. It does not change plugin activation, Browser startup, Browser authorization, per-agent tool policy, or Gateway behavior.

@amtellezfernandez
amtellezfernandez requested a review from a team as a code owner June 29, 2026 09:09
@clawsweeper

clawsweeper Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed July 6, 2026, 9:11 PM ET / 01:11 UTC.

Summary
The branch changes openclaw security audit Browser exposure reporting to consult plugin policy and adds focused security-audit coverage; most other listed files match current-main drift from the stale base.

PR surface: Source -379, Tests -275, Docs +17, Other +560. Total -77 across 61 files.

Reproducibility: yes. source-level: PR head checks raw plugin policy, while current startup auto-enable appends Browser to restrictive allowlists when a root browser block exists. I did not run the PR, but the conflicting source and docs path is direct.

Review metrics: 1 noteworthy metric.

  • Security audit policy cases: 7 added attack-surface cases. These cases define the Browser audit compatibility contract; one added case currently conflicts with documented startup auto-enable behavior.

Stored data model
Persistent data-model change detected: vector/embedding metadata: qa/scenarios/channels/thread-isolation.yaml. Confirm migration or upgrade compatibility proof before merge.

Merge readiness
Overall: 🧂 unranked krab
Proof: 🦐 gold shrimp
Patch quality: 🧂 unranked krab
Result: blocked until stronger real behavior proof is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P1] Fix the audit to use effective Browser plugin activation, then show final-head output for plugins.allow=["openai"] with and without a root browser block.
  • Update the focused security audit tests so the explicit Browser config case matches startup behavior.

Proof guidance:

  • [P1] Needs stronger real behavior proof before merge: The PR body includes live Gateway/audit proof for restrictive and explicitly allowed states, but it does not prove the documented browser.enabled=true plus restrictive allowlist edge that this patch changes incorrectly. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Risk before merge

  • [P1] Merging as-is would make the security audit report browser control: disabled for existing documented configs where a root browser block causes Browser to load under a restrictive plugin allowlist.
  • [P1] The added tests encode the conflicting disabled expectation, so green focused tests would not protect the current startup/docs compatibility contract.

Maintainer options:

  1. Align audit with startup activation (recommended)
    Update the audit helper to evaluate Browser against the effective auto-enabled plugin config and change the explicit-browser restrictive-allowlist test to expect enabled unless Browser is denied or disabled.
  2. Intentionally change Browser policy
    If maintainers want root browser config to stop bypassing restrictive allowlists, this PR needs matching startup behavior, docs, migration or doctor guidance, and upgrade-risk review before merge.
Copy recommended automerge instruction
@clawsweeper automerge

Special instructions:
Update `src/security/audit-extra.summary.ts` so Browser audit availability is computed from the same auto-enabled/effective plugin config used by startup, preserving documented root `browser` config activation under restrictive allowlists, and adjust security audit tests for absent Browser config, explicit Browser config, denylist, and explicit disabled cases.

Next step before merge

  • [P1] A narrow automated repair can align the audit helper and tests with current Browser auto-enable behavior; no broad refactor is needed.

Security
Needs attention: The diff introduces a security-audit false negative for documented Browser auto-enable configurations.

Review findings

  • [P1] Honor Browser auto-enable before reporting disabled — src/security/audit-extra.summary.ts:123-129
Review details

Best possible solution:

Compute Browser audit availability from the same auto-enabled/effective plugin configuration that Gateway startup uses, then keep separate tests for no Browser config, explicit Browser config, denylist, and explicit disabled cases.

Do we have a high-confidence way to reproduce the issue?

Yes, source-level: PR head checks raw plugin policy, while current startup auto-enable appends Browser to restrictive allowlists when a root browser block exists. I did not run the PR, but the conflicting source and docs path is direct.

Is this the best way to solve the issue?

No. Reusing the base policy is the right direction, but applying it before plugin auto-enable skips the effective startup state; the safer fix is to reuse the effective plugin activation path or a small helper derived from it.

Full review comments:

  • [P1] Honor Browser auto-enable before reporting disabled — src/security/audit-extra.summary.ts:123-129
    This checks the raw plugins.allow list, so browser.enabled=true plus plugins.allow=["openai"] reports Browser disabled. Current startup auto-enable adds Browser to the effective allowlist for a root browser block, and the docs promise that behavior, so the audit would hide an actually enabled Browser control surface.
    Confidence: 0.92

Overall correctness: patch is incorrect
Overall confidence: 0.9

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 97777a70268a.

Label changes

Label changes:

  • add P1: The PR can create a security-audit false negative for Browser exposure in an existing documented configuration path.
  • add merge-risk: 🚨 compatibility: Existing users with a root browser block and restrictive plugin allowlist can keep Browser loaded while the PR reports it disabled.
  • add merge-risk: 🚨 security-boundary: The changed security audit can hide an enabled Browser control surface, weakening operator visibility into a sensitive capability.
  • add rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🦐 gold shrimp and patch quality is 🧂 unranked krab.
  • add status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs stronger real behavior proof before merge: The PR body includes live Gateway/audit proof for restrictive and explicitly allowed states, but it does not prove the documented browser.enabled=true plus restrictive allowlist edge that this patch changes incorrectly. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
  • remove P2: Current review triage priority is P1, so this older priority label is no longer current.

Label justifications:

  • P1: The PR can create a security-audit false negative for Browser exposure in an existing documented configuration path.
  • merge-risk: 🚨 compatibility: Existing users with a root browser block and restrictive plugin allowlist can keep Browser loaded while the PR reports it disabled.
  • merge-risk: 🚨 security-boundary: The changed security audit can hide an enabled Browser control surface, weakening operator visibility into a sensitive capability.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🦐 gold shrimp and patch quality is 🧂 unranked krab.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs stronger real behavior proof before merge: The PR body includes live Gateway/audit proof for restrictive and explicitly allowed states, but it does not prove the documented browser.enabled=true plus restrictive allowlist edge that this patch changes incorrectly. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed

PR surface:

Source -379, Tests -275, Docs +17, Other +560. Total -77 across 61 files.

View PR surface stats
Area Files Added Removed Net
Source 31 278 657 -379
Tests 19 331 606 -275
Docs 3 31 14 +17
Config 0 0 0 0
Generated 0 0 0 0
Other 8 658 98 +560
Total 61 1298 1375 -77

Security concerns:

  • [high] Browser exposure can be under-reported — src/security/audit-extra.summary.ts:123
    Using raw plugin policy before startup auto-enable can report Browser disabled while Browser is still effectively loaded for root browser config under a restrictive allowlist.
    Confidence: 0.9

Acceptance criteria:

  • [P1] pnpm test src/security/audit-summary.test.ts src/security/audit-extra.sync.test.ts.
  • [P1] pnpm check:changed -- src/security/audit-extra.summary.ts src/security/audit-summary.test.ts src/security/audit-extra.sync.test.ts.

What I checked:

  • PR head implementation: PR head computes Browser availability by applying passesManifestOwnerBasePolicy directly to cfg.plugins, so it sees plugins.allow=["openai"] as excluding Browser even when runtime auto-enable would materialize Browser into the effective allowlist. (src/security/audit-extra.summary.ts:123, 421dbe98247e)
  • Documented current behavior: Current docs say an explicit root browser block activates the bundled Browser plugin even under a restrictive plugins.allow, matching bundled channel config behavior. Public docs: docs/tools/browser.md. (docs/tools/browser.md:114, 97777a70268a)
  • Startup auto-enable source: Current startup auto-enable treats a root Browser config as relevant setup state and later appends auto-enabled plugins to an existing restrictive allowlist. (src/config/plugin-auto-enable.shared.ts:433, 97777a70268a)
  • Test locks in conflicting behavior: The PR adds an expected disabled result for browser.enabled=true with plugins.allow=["openai"], which conflicts with current startup auto-enable and public docs. (src/security/audit-summary.test.ts:50, 421dbe98247e)
  • History provenance: The current Browser audit summary, Browser auto-enable behavior, and Browser docs in this checkout trace to commit d931839; the PR head then changes only the audit calculation on top of that behavior. (src/security/audit-extra.summary.ts:116, d931839e0c12)
  • Current-main drift check: Selected non-security files shown in the PR diff already match current main object IDs; the review blocker is the remaining security-audit semantic change, not the stale-base file list by itself. (apps/android/CHANGELOG.md:1, 97777a70268a)

Likely related people:

  • steipete: Blame and PR timeline show Peter Steinberger on the current Browser audit, auto-enable, and docs behavior, and he also force-pushed the maintainer rewrite on this PR. (role: recent area contributor; confidence: high; commits: d931839e0c12, ad919c3cfe50, b26445c23e25; files: src/security/audit-extra.summary.ts, src/config/plugin-auto-enable.shared.ts, docs/tools/browser.md)
  • Vincent Koc: Git history shows a recent release-stabilization commit touching the security audit summary path before the current main rewrite, so this is a secondary routing signal only. (role: adjacent audit-history contributor; confidence: low; commits: e085fa1a3ffd; files: src/security/audit-extra.summary.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.
Review history (2 earlier review cycles)
  • reviewed 2026-06-29T09:31:50.305Z sha 4f1151c :: needs maintainer review before merge. :: none
  • reviewed 2026-07-07T00:38:12.989Z sha c46b9c7 :: needs maintainer review before merge. :: none

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. P2 Normal backlog priority with limited blast radius. labels Jun 29, 2026
@amtellezfernandez

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

CI/check state has finished since the last review note. gh pr checks 97732 now shows the selected quality/security/check shards passing, with unrelated optional shards skipped by selector. The PR remains a narrow audit-output fix with no runtime plugin loading or browser startup behavior changes.

Author-side state:

  • Branch head: 4f1151c1
  • Merge state: clean
  • Focused local validation remains as listed in the PR body
  • No code or proof changes after the previous review; this is only to refresh the stale "CI jobs still in progress" risk note.

@clawsweeper

clawsweeper Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@steipete steipete self-assigned this Jul 6, 2026
@steipete
steipete force-pushed the fix/security-audit-browser-summary-policy branch 2 times, most recently from c98ea86 to b26445c Compare July 7, 2026 00:49
@clawsweeper clawsweeper Bot removed proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Jul 7, 2026
@steipete steipete changed the title fix(security): report browser audit summary from plugin policy fix(security): align browser audit with plugin policy Jul 7, 2026
@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation channel: discord Channel integration: discord app: android App: android app: web-ui App: web-ui cli CLI command changes agents Agent runtime and tooling extensions: qa-lab extensions: copilot size: XL and removed size: S labels Jul 7, 2026
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P1 High-priority user-facing bug, regression, or broken workflow. and removed P2 Normal backlog priority with limited blast radius. labels Jul 7, 2026
@clawsweeper clawsweeper Bot added merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. labels Jul 7, 2026
@steipete
steipete force-pushed the fix/security-audit-browser-summary-policy branch from 421dbe9 to a2ad2c8 Compare July 7, 2026 01:15
@openclaw-barnacle openclaw-barnacle Bot added size: S and removed docs Improvements or additions to documentation channel: discord Channel integration: discord app: android App: android app: web-ui App: web-ui cli CLI command changes agents Agent runtime and tooling extensions: qa-lab extensions: copilot size: XL labels Jul 7, 2026
@steipete

steipete commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Land-ready proof for a2ad2c8e12e2e5f95bc1dafaa689f1342c222596:

  • Reworked the contributor patch to use the canonical manifest-owner base policy. The audit no longer duplicates plugin enable/allow/deny/entry rules, and explicit Browser config cannot bypass a restrictive global allowlist.
  • The same canonical predicate drives both summary.attack_surface and per-agent models.small_params. Global plugin availability is the outer boundary; each agent's sandbox/tool policy remains independently enforced.
  • Focused remote tests: pnpm test src/security/audit-summary.test.ts src/security/audit-extra.sync.test.ts — 16/16 passed.
  • Real Gateway proof: sanitized direct-AWS run run_3fb78ed75c91 on cbx_58fe8eb9e642 (brisk-krill, c7a.8xlarge, public network, no Tailscale) exercised the live-proven runtime patch.
    • Restrictive plugins.allow=["openai"]: audit reported Browser disabled, small-model exposure web=[off], Gateway denied Browser control, and an openai/gpt-5.4 agent returned SECURITY_POLICY_OK.
    • Explicit plugins.allow=["openai","browser"] plus browser.enabled=true: audit reported Browser enabled, small-model exposure web=[browser], managed Chrome started, and an openai/gpt-5.4 Browser agent read the live page and returned SECURITY_BROWSER_OK.
  • The live-proven head and final head have identical src/security/** stable patch id d87df79373b19924dc57e146d0f084e0dbb3a9c9; later changes only rebased onto current main and removed the release-owned root changelog line required by native prepare policy.
  • Final structured autoreview: no accepted/actionable findings, confidence 0.86.
  • Exact-head hosted CI: run 28834540783, all selected checks passed.

No runtime activation, Browser authorization, config, schema, protocol, or migration behavior changes.

@steipete
steipete merged commit 349d354 into openclaw:main Jul 7, 2026
120 of 123 checks passed
@steipete

steipete commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Merged via squash.

github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 7, 2026
* fix(security): respect plugin policy in browser audit summary

* fix(security): reuse browser plugin activation policy

Co-authored-by: Alba María Téllez Fernández <[email protected]>

* fix(security): keep browser config behind plugin policy

Co-authored-by: Alba María Téllez Fernández <[email protected]>

* chore(security): keep release notes in PR body

---------

Co-authored-by: Peter Steinberger <[email protected]>
giodl73-repo pushed a commit to giodl73-repo/openclaw that referenced this pull request Jul 8, 2026
* fix(security): respect plugin policy in browser audit summary

* fix(security): reuse browser plugin activation policy

Co-authored-by: Alba María Téllez Fernández <[email protected]>

* fix(security): keep browser config behind plugin policy

Co-authored-by: Alba María Téllez Fernández <[email protected]>

* chore(security): keep release notes in PR body

---------

Co-authored-by: Peter Steinberger <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. P1 High-priority user-facing bug, regression, or broken workflow. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: S status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants