fix(electron): constrain renderer navigation and child windows#739
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughAdds centralized Electron navigation policies, trusted reload tracking, navigation interception, safe external URL handling through the system browser, and hardening for newly created window web contents. ChangesNavigation hardening
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant ElectronApp
participant WebContents
participant NavigationPolicy
participant SystemBrowser
ElectronApp->>WebContents: web-contents-created
ElectronApp->>NavigationPolicy: check web contents type
ElectronApp->>NavigationPolicy: register navigation handlers
WebContents->>NavigationPolicy: navigation or window-open event
NavigationPolicy->>WebContents: prevent navigation or deny child window
NavigationPolicy->>SystemBrowser: open safe external HTTP(S) URL
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@electron/navigationPolicy.ts`:
- Around line 96-100: Replace the use of getCurrentUrl() in the exact-reload
check with a trusted URL snapshot that is not derived from the mutable renderer
location; maintain or update this snapshot only at approved navigation
boundaries, such as did-navigate-in-page, and use it in isExactRendererLocation.
Add a regression test covering replaceState changing the query followed by a
reload.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 15d12811-f0a1-4e50-85c3-1590ea1bc972
📒 Files selected for processing (3)
electron/main.tselectron/navigationPolicy.test.tselectron/navigationPolicy.ts
Description
Adds one global navigation policy for Recordly BrowserWindow contents before any app window is created.
window.open/target=_blankalways returnsdeny, so external pages never become Electron childwindows;
externally.
The global
web-contents-createdhook covers the editor, HUD, update toast, source selector, countdown,and transient source-highlight BrowserWindows without duplicating policy in six constructors.
Motivation
Recordly currently has privileged renderer windows and extension-provided homepage links, but no
top-frame navigation or child-window policy. Navigating a privileged WebContents to external content,
or opening that content inside a new Electron window, creates unnecessary ambient authority.
This follows Electron's official guidance to
limit navigation and new windows.
Type of Change
Related Issue(s)
Architecture remediation Electron-hardening finding. PR #737 establishes the standard quality workflow
and contains the unrelated current-
maintypecheck baseline fix.Testing Guide
npx vitest --run electron/navigationPolicy.test.ts electron/mainCjsNormalize.test.mjs npx biome lint electron/navigationPolicy.ts electron/navigationPolicy.test.ts electron/main.ts npm test npx vite build --config vite.config.ts npm run normalize:electron-main-cjs npm run smoke:electron-main-cjsResults:
Standard
tsc --noEmitreaches only the unrelated unused import on currentmain, already fixed by#737. A packaged GUI/device smoke was not run in this source-only environment.
Risk and non-goals
Electron documents that
will-navigatedoes not fire for intentional main-processloadURL/loadFilecalls, so existing startup/fallback loads are unchanged. Exact reload is preserved; renderer query/path
mutation is deliberately fail-closed because those query flags can carry privileged local paths.
This PR does not claim complete Electron or extension isolation. It intentionally defers:
file://;webSecurity: falseand enforcement of CSP;Those require separate runtime characterization and compatibility gates.
Checklist
Summary by CodeRabbit
Security
Tests