Skip to content

fix(browser): make ref uploads request-owned#105151

Merged
steipete merged 2 commits into
mainfrom
codex/browser-atomic-upload
Jul 12, 2026
Merged

fix(browser): make ref uploads request-owned#105151
steipete merged 2 commits into
mainfrom
codex/browser-atomic-upload

Conversation

@steipete

Copy link
Copy Markdown
Contributor

Closes #38844

What Problem This Solves

Managed Browser upload requests that supplied both paths and a trigger ref returned before Playwright captured the chooser and assigned the files. Failures were detached and suppressed, and a stale waiter could consume a later unrelated chooser.

Why This Change Was Made

The ref form now has one request-owned Playwright lifecycle: resolve one page, attach one chooser listener, guarded click, strict use-time path revalidation, guarded file assignment, and deterministic cleanup under one deadline and request signal. Ownership is connection-scoped because abort cleanup disconnects the shared Playwright connection.

The paths-only delayed-arm API remains detached. Direct inputRef and element uploads, Chrome MCP routing, and managed upload-root validation remain supported.

User Impact

  • paths + ref waits until exactly one chooser receives the validated files or returns the specific failure.
  • Timeout, abort, stale-click, validation, and assignment failures remove their listener.
  • Superseding uploads wait for connection cleanup before a successor reconnects.
  • Direct input assignment now uses the same navigation policy guard as other interactions.

Evidence

Exact-head CI is pending. The final live proof needs a fresh credential because the prior OpenAI service-account key was exposed in an internal process-inspection transcript and will not be reused.

@openclaw-barnacle openclaw-barnacle Bot added size: L maintainer Maintainer-authored PR labels Jul 12, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fb03f04d39

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

inputRef,
element,
paths: resolvedPaths,
ssrfPolicy: ctx.state().resolved.ssrfPolicy,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Forward the full navigation policy to upload hooks

When an OpenClaw-managed profile is launched with --proxy-server while strict SSRF is in effect, browserNavigationPolicyForProfile adds browserProxyMode: "explicit-browser-proxy" so assertBrowserNavigationAllowed fails closed; this hook now wraps setInputFiles/ref uploads in navigation guards but passes only ssrfPolicy. An upload from an otherwise allowed page that auto-submits or navigates, for example to a public IP-literal URL, is therefore checked as direct browser traffic and can bypass the explicit-proxy block. Please pass the full browserNavigationPolicyForProfile(ctx, profileCtx) into both guarded upload calls.

Useful? React with 👍 / 👎.

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. P1 High-priority user-facing bug, regression, or broken workflow. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. labels Jul 12, 2026
@clawsweeper

clawsweeper Bot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Codex review: found issues before merge. Reviewed July 12, 2026, 4:41 AM ET / 08:41 UTC.

Summary
Makes paths + ref browser uploads a single awaited Playwright operation with request-scoped chooser ownership, cancellation, cleanup, path revalidation, assignment, and navigation guarding.

PR surface: Source +261, Tests +439. Total +700 across 9 files.

Reproducibility: yes. from source with high confidence: use a managed profile with an explicit browser proxy under strict SSRF policy and trigger navigation during direct-input or ref-based file assignment; the route drops browserProxyMode before invoking the guard.

Review metrics: none identified.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #38844
Summary: This PR is the candidate implementation for the linked issue's split upload-and-click lifecycle, stale chooser ownership, and masked assignment failures.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🦐 gold shrimp
Proof: 🐚 platinum hermit
Patch quality: 🦐 gold shrimp
Result: needs maintainer review before merge.

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

Rank-up moves:

  • [P2] Forward the complete profile navigation policy and add explicit-proxy coverage for both guarded upload branches.

Risk before merge

  • [P1] Merging this head could evaluate assignment-triggered navigation as direct browser traffic instead of fail-closed explicit-proxy traffic for managed profiles configured with --proxy-server.

Maintainer options:

  1. Forward the complete profile policy (recommended)
    Compute the existing profile navigation policy once, spread it into both guarded upload calls, and add explicit-proxy route coverage before merge.
  2. Pause the guarded-upload change
    Keep the PR open but unmerged until every newly guarded assignment path preserves the profile proxy policy.

Next step before merge

  • [P2] The protected maintainer label and existing author-facing security blocker make this a normal contributor follow-up and maintainer review path, not an automated repair candidate.

Security
Needs attention: The exact head drops an existing explicit-proxy navigation-policy input on the newly guarded upload paths.

Review findings

  • [P1] Forward the full navigation policy to upload guards — extensions/browser/src/browser/routes/agent.act.hooks.ts:105
Review details

Best possible solution:

Preserve the request-owned upload lifecycle, but pass browserNavigationPolicyForProfile(ctx, profileCtx) into both guarded upload calls and add route coverage proving explicit-proxy mode reaches direct-input and ref-triggered assignment guards.

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

Yes, from source with high confidence: use a managed profile with an explicit browser proxy under strict SSRF policy and trigger navigation during direct-input or ref-based file assignment; the route drops browserProxyMode before invoking the guard.

Is this the best way to solve the issue?

No on the exact head. Request-owned chooser handling is the appropriate boundary, but the route must preserve the complete existing profile navigation policy rather than constructing a partial option bag.

Full review comments:

  • [P1] Forward the full navigation policy to upload guards — extensions/browser/src/browser/routes/agent.act.hooks.ts:105
    Use browserNavigationPolicyForProfile(ctx, profileCtx) for both guarded upload calls. Passing only ssrfPolicy drops browserProxyMode: "explicit-browser-proxy", so a file assignment that navigates can be checked as direct traffic and bypass the profile's fail-closed proxy rule.
    Confidence: 0.99

Overall correctness: patch is incorrect
Overall confidence: 0.99

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 68553bed8437.

Label changes

Label changes:

  • add P1: The PR addresses a real browser workflow regression but currently introduces a merge-blocking navigation security defect.
  • add merge-risk: 🚨 security-boundary: The newly guarded upload calls omit browserProxyMode, allowing assignment-triggered navigation to miss the explicit-proxy fail-closed rule.
  • add proof: sufficient: Contributor real behavior proof is sufficient. The PR reports an after-fix real Gateway, managed Chrome, and OpenAI agent run where the page observed the selected file and the Gateway remained alive; this supports the central lifecycle fix, though it does not cover the explicit-proxy security edge.
  • add rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🐚 platinum hermit and patch quality is 🦐 gold shrimp.
  • add status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action. Sufficient (live_output): The PR reports an after-fix real Gateway, managed Chrome, and OpenAI agent run where the page observed the selected file and the Gateway remained alive; this supports the central lifecycle fix, though it does not cover the explicit-proxy security edge.

Label justifications:

  • P1: The PR addresses a real browser workflow regression but currently introduces a merge-blocking navigation security defect.
  • merge-risk: 🚨 security-boundary: The newly guarded upload calls omit browserProxyMode, allowing assignment-triggered navigation to miss the explicit-proxy fail-closed rule.
  • rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🐚 platinum hermit and patch quality is 🦐 gold shrimp.
  • status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action. Sufficient (live_output): The PR reports an after-fix real Gateway, managed Chrome, and OpenAI agent run where the page observed the selected file and the Gateway remained alive; this supports the central lifecycle fix, though it does not cover the explicit-proxy security edge.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR reports an after-fix real Gateway, managed Chrome, and OpenAI agent run where the page observed the selected file and the Gateway remained alive; this supports the central lifecycle fix, though it does not cover the explicit-proxy security edge.
Evidence reviewed

PR surface:

Source +261, Tests +439. Total +700 across 9 files.

View PR surface stats
Area Files Added Removed Net
Source 5 312 51 +261
Tests 4 449 10 +439
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 9 761 61 +700

Security concerns:

  • [high] Preserve explicit-proxy fail-closed policy — extensions/browser/src/browser/routes/agent.act.hooks.ts:105
    Both upload branches pass only the SSRF policy, omitting the profile-derived proxy mode used to reject navigation that would bypass an explicit browser proxy.
    Confidence: 0.99

What I checked:

Likely related people:

  • vincentkoc: Current-main blame and symbol history connect this contributor to the profile navigation-policy helper, proxy-mode contract, and adjacent browser upload implementation; the available checkout history is compressed into commit efdce6754d. (role: recent area contributor; confidence: medium; commits: efdce6754d00; files: extensions/browser/src/browser/navigation-guard.ts, extensions/browser/src/browser/routes/agent.shared.ts, extensions/browser/src/browser/pw-tools-core.downloads.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.

@steipete

Copy link
Copy Markdown
Contributor Author

Maintainer verification on exact head 53818d05e0da528eafa0c1317ef7411f1957ab6a:

  • Refactored ref-based uploads into one request-owned operation: one resolved page, chooser listener before click, strict use-time path validation, guarded file assignment, one deadline/abort owner, and cleanup that prevents a successor from overlapping stale work.
  • Preserved paths-only delayed arming, direct inputRef/element uploads, Chrome MCP uploads, and normal browser functionality.
  • Focused tests passed 65/65 on Blacksmith Testbox-through-Crabbox: https://github.com/openclaw/openclaw/actions/runs/29185303822
  • Exact-head required CI is green; exact-head pnpm build passed; fresh autoreview found no actionable issues.
  • Live proof used a real Gateway, managed headless browser, local upload fixture, and a real openai/gpt-5.6 agent turn. The agent made one upload call containing both paths and the current button ref; canonical SQLite transcript and browser evidence showed selected:report.json before the required final token.
  • Live gates: gateway_ready:yes, fixture_ready:yes, agent_upload_with_ref:yes, browser_selected_observed:yes, agent_final_pass:yes, gateway_alive_after_agent:yes, atomic_upload_live_proof:pass.

This closes the chooser race without removing any upload mode or forcing users onto a less capable path.

@steipete
steipete merged commit de4d407 into main Jul 12, 2026
133 of 137 checks passed
@steipete
steipete deleted the codex/browser-atomic-upload branch July 12, 2026 09:19
@steipete

Copy link
Copy Markdown
Contributor Author

Merged via squash.

github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 13, 2026
* fix(browser): make ref uploads request-owned

* style(browser): satisfy upload owner const lint
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

maintainer Maintainer-authored PR merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. P1 High-priority user-facing bug, regression, or broken workflow. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. size: L status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: browser upload/file chooser flow is flaky and can misreport stale-click failures as browser control timeouts

1 participant