Close the renderer privilege boundary: navigation, IPC, permissions, shell #22

Closed
Tyler wants to merge 0 commits from pr/02-security-boundary into main
Owner

Phase 1 of the improvement plan (ai_prompts/prompt4.md), PR 2 of the sequence. Mirrors GitHub PR Twest2/StepForge#6.

  • New app/security.js centralizes navigation/popup denial, deny-by-default permissions (display capture only for the capture worker), IPC sender guard, payload budgets, field validators, produced-files registry.
  • All three windows sandboxed with navigation/popup/webview denial.
  • Every IPC channel validates sender + arguments; shell access is intent-specific (openProduced/revealLinkedArchive/openExternal); archive:peek removed; export:run output dirs constrained to dialog/settings-sourced paths.
  • Renderer links never navigate the privileged window.

Verified: 215 unit tests incl. 12 new security regression tests; startup smoke/unit-workflows/sample-artifacts/build-release E2E pass; click selftest unchanged (stream source, 3/3 markers, 8/8 burst; arm/debounce failures are the pre-existing defect scheduled for PR 5).

Phase 1 of the improvement plan (ai_prompts/prompt4.md), PR 2 of the sequence. Mirrors GitHub PR Twest2/StepForge#6. - New app/security.js centralizes navigation/popup denial, deny-by-default permissions (display capture only for the capture worker), IPC sender guard, payload budgets, field validators, produced-files registry. - All three windows sandboxed with navigation/popup/webview denial. - Every IPC channel validates sender + arguments; shell access is intent-specific (openProduced/revealLinkedArchive/openExternal); archive:peek removed; export:run output dirs constrained to dialog/settings-sourced paths. - Renderer links never navigate the privileged window. Verified: 215 unit tests incl. 12 new security regression tests; startup smoke/unit-workflows/sample-artifacts/build-release E2E pass; click selftest unchanged (stream source, 3/3 markers, 8/8 burst; arm/debounce failures are the pre-existing defect scheduled for PR 5).
Tyler added 1 commit 2026-07-03 18:26:06 +00:00
Close the renderer privilege boundary: navigation, IPC, permissions, shell
Template tests / tests (pull_request) Failing after 33s
50e445e7c3
Phase 1 of the improvement plan (PR 2 of the sequence). A remote page could
previously inherit the privileged preload bridge: the main window had no
navigation guard or popup handler, IPC handlers accepted any sender, every
Electron permission was granted to everyone, and shell:openPath accepted an
arbitrary renderer-supplied target.

- New app/security.js (plain-Node testable) centralizes the policy:
  app-page identity, navigation/popup denial, deny-by-default permissions,
  external-URL validation, IPC sender guard, payload budgets, field
  validators, and a produced-files registry.
- Every window (main, region overlay, capture worker) is sandboxed, denies
  all navigation away from its own page, denies every popup, and refuses
  webview attachment.
- Every IPC channel now rejects events that are not from the main window's
  top frame on index.html, rejects non-plain/oversized argument bags, and
  channels with risky inputs validate ids, enums, names, and sizes
  (path-traversal and prototype-pollution guards included).
- Permissions are deny-by-default; the only grant in the app is display
  capture (+media) for the dedicated capture-worker page. The display-media
  handler also verifies the requesting frame.
- shell:openPath/showItemInFolder are gone. Replacements are intent-specific:
  openProduced (only files the main process produced this session),
  revealLinkedArchive (path read from the store, not the renderer), and
  openExternal (parsed, scheme-checked http(s)/mailto only).
- archive:peek removed: unused, and it let the renderer read arbitrary
  archives by path.
- export:run only accepts output directories that came from a dialog pick or
  remembered settings; anything else re-prompts.
- Renderer: description links never navigate; http(s)/mailto open externally
  via the validated handler.
- 12 new security regression tests: hostile navigation targets, permission
  matrix, sender spoofing (wrong window/subframe/navigated/disposed frames),
  oversized payloads, traversal/pollution attempts, produced-file registry,
  and source-level guards (no blanket grants, no generic shell channels,
  sandbox on every window).

Verified: 215 unit tests pass; startup smoke, unit-workflows, sample
artifacts, and build-release E2E pass; click self-test still reaches
source: stream with markers 3/3 and burst 8/8 under the deny-by-default
policy (arm/debounce remain the known pre-existing failures, untouched
here); UI screenshot confirms the sandboxed renderer boots.

Co-Authored-By: Claude Fable 5 <[email protected]>
Author
Owner

Merged into main as 6ffef69 (same-SHA merge to both forges; GitHub mirror PR Twest2/StepForge#6 MERGED, CI green on ubuntu+windows). Closing.

Merged into main as 6ffef69 (same-SHA merge to both forges; GitHub mirror PR Twest2/StepForge#6 MERGED, CI green on ubuntu+windows). Closing.
Tyler closed this pull request 2026-07-03 18:27:40 +00:00

Pull request closed

Please reopen this pull request to perform a merge.
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Tyler/StepForge#22