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
- Attacker crafts a malicious image and uploads it to a website
- Gosub renders the image via Cairo/Skia/Vello rasterizer
- A buffer overflow or integer overflow in the rasterizer is triggered
- Attacker gains code execution in the browser process
- 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
References
Acceptance Criteria
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
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:
gosub-net-daemon(network process) at engine startupIPC Protocol:
[u32 length][bincode payload](length-framed messages)bincode(compact, fast)FetchRequest,FetchResultPhase 2: Per-Origin Render Isolation
Goal: Isolate renderer from DOM/cookies of other origins. Renderer exploits
cannot leak data across origins.
Implementation:
Architecture:
IPC Protocol:
RenderRequest(viewport, paint commands, textures)RenderResult(rasterized tiles)Data Transferred (per frame):
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:
gosub-gpu-daemon(GPU worker) with exclusive GPU device accessOut of Scope (Future Work)
Security Model After Implementation
Testing Strategy
References
/crates/gosub_engine/src/engine/engine.rs— Engine entry point/crates/gosub_engine/src/engine/tab/worker.rs— Tab worker (currently runs in Tokio task)/crates/gosub_engine/src/net/io_runtime.rs— Network I/O (currently in Tokio task)Acceptance Criteria