Skip to content

Process Isolation for Security: Multi-Process Architecture #1080

Description

@jaytaph

Process Isolation for Security: Multi-Process Architecture

Problem Statement

Currently, all code runs in a single process. This creates a severe security risk:
a vulnerability in any component (image decoder, CSS parser, renderer, JS engine)
can compromise all open tabs and zones.

Attack Scenario

  1. Attacker crafts a malicious image and uploads it to a website
  2. Gosub renders the image via Cairo/Skia/Vello rasterizer
  3. A buffer overflow or integer overflow in the rasterizer is triggered
  4. Attacker gains code execution in the browser process
  5. Attacker now has access to:
    • DOM of all open tabs
    • All cookies and session tokens across all zones
    • Local storage and session storage of all origins
    • Network requests (can forge requests on behalf of any origin)
    • Window/tab focus and user interaction data

Why This Matters

This violates the fundamental browser security model: data from one origin
should not be accessible to another origin, even if one is compromised.

Solution: Multi-Process Architecture

We will gradually isolate security-critical components into separate processes
with reduced privileges and access control.

Phase 1: Network Isolation

Goal: Prevent SSRF attacks and limit network-related exploits.

Implementation:

  • Spawn gosub-net-daemon (network process) at engine startup
  • Network process owns all network resources (sockets, connection pooling)
  • Renderer/tabs submit fetch requests via IPC (Unix domain socket)
  • Network process returns response (headers + body stream)
  • Prevents renderer from:
    • Initiating requests to internal IPs (SSRF)
    • Spoofing User-Agent or custom headers
    • Accessing raw sockets

IPC Protocol:

  • Format: [u32 length][bincode payload] (length-framed messages)
  • Serialization: bincode (compact, fast)
  • Message types: FetchRequest, FetchResult

Phase 2: Per-Origin Render Isolation

Goal: Isolate renderer from DOM/cookies of other origins. Renderer exploits
cannot leak data across origins.

Implementation:

  • Each origin runs in its own renderer child process
  • Parent process (engine) coordinates between processes:
  • Keeps DOM, styles, cookies, local storage
  • Sends render commands (not DOM) to renderer child
    • Receives rasterized tiles back
  • Renderer child process:
    • Executes painting pipeline (stages 1–5: layout → paint commands)
    • Rasterizes tiles (stage 6) via Cairo/Skia/Vello
    • Never has access to: cookies, DOM of other origins, network

Architecture:

GosubEngine (parent)
├─ Zone A (origin:example.com)
│  ├─ Tab 1, Tab 2
│  └─ Renderer Child Process A (low privileges)
│     ├─ Stage 6: Rasterize tiles
│     └─ (Cannot access DOM, cookies, other zones)
├─ Zone B (origin:attacker.com)
│  └─ Renderer Child Process B (separate, isolated)
└─ Network Process (Phase 1)

IPC Protocol:

  • Parent → Child: RenderRequest (viewport, paint commands, textures)
  • Child → Parent: RenderResult (rasterized tiles)
  • Format: Same as Phase 1 (bincode length-framed)

Data Transferred (per frame):

  • Paint commands: ~10–50 KB
  • Textures (images): ~1–2 MB
  • Total: ~2 MB/frame at 60 FPS (~120 MB/s over Unix socket, acceptable)

Note: Both CPU (Cairo/Skia) and GPU (Vello) backends run in the same renderer
child process with the same isolation level. Backend choice is not a security
discriminator.


Phase 3: GPU Process

Goal: Isolate GPU driver bugs and GPU memory corruption from renderer code.

Implementation:

  • Spawn gosub-gpu-daemon (GPU worker) with exclusive GPU device access
  • Renderer child process submits GPU commands to GPU daemon
  • GPU daemon executes wgpu rendering and returns texture IDs
  • Prevents: GPU driver exploits, GPU memory leaks, GPU command injection

Out of Scope (Future Work)

  • JavaScript Isolation: V8 in separate process per origin (very large change)
  • HTML/CSS Parser Isolation: Separate process for parsing (complex; parsing is sequential)
  • Storage Process: Separate process for cookies/localStorage (lower priority)

Security Model After Implementation

Component Current After Phase 1 After Phase 2 After Phase 3
Network can access other zones' data ✅ Yes ❌ No ❌ No ❌ No
Renderer can access other origins' cookies ✅ Yes ✅ Yes ❌ No ❌ No
Renderer can forge requests ✅ Yes ❌ No ❌ No ❌ No
GPU exploit can crash browser ✅ Yes ✅ Yes ✅ Yes ❌ No

Testing Strategy

  • Add integration tests for IPC message framing (corruption handling)
  • Add tests for process crash recovery (orphan process cleanup)
  • Benchmark: measure frame time delta before/after Phase 2
  • Security test: verify renderer child cannot read parent memory
  • Security test: verify network process cannot access tabs' data

References


Acceptance Criteria

  • Phase 1 complete: Network process isolated, SSRF prevented
  • Phase 2 complete: Renderer per-origin, origin data isolation enforced
  • IPC layer: Robust (handles process crashes, message corruption)
  • Performance: <10ms added latency per frame (Phase 2)
  • Tests: 90%+ coverage for IPC layer and process lifecycle
  • Documentation: Updated with new architecture diagrams

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions