Preload Script & Security
Relevant source files
The following files were used as context for generating this wiki page:
The Preload Script & Security system in Open Claude Cowork serves as the vital bridge and security boundary between the Electron Main process and the Renderer process. It implements a secure IPC (Inter-Process Communication) pattern that protects the application from common web-based vulnerabilities while providing necessary system-level capabilities to the user interface.
By leveraging Electron's contextBridge and ipcRenderer, the system exposes a restricted, safe API to the frontend. This ensures that the web-based chat interface can communicate with the local Node.js backend server (http://localhost:3001) and manage long-lived streaming connections without exposing full Node.js access or sensitive Electron internals to the renderer.
Sources: preload.js:1-7, main.js:25-34, README.md:164-177
Architecture and Security Strategy
The application employs a defense-in-depth strategy by isolating the renderer process from the system. The Main process configures the BrowserWindow with strict security settings, including disabling nodeIntegration and enabling contextIsolation.
Security Configuration
| Feature | Setting | Description |
|---|---|---|
nodeIntegration | false | Prevents the renderer from accessing Node.js APIs directly. |
contextIsolation | true | Runs the preload script and the renderer in separate JavaScript contexts. |
webSecurity | true | Enforces same-origin policy and other web security features. |
enableWebSQL | false | Disables legacy WebSQL database access. |
WindowOpenHandler | Restricted | Intercepts window.open to open external URLs in the system browser rather than a new Electron window. |
Sources: main.js:28-34, main.js:46-50
Inter-Process Flow
The following diagram illustrates how the preload script acts as a secure intermediary for chat requests and session management.
This diagram shows the flow of communication from the UI through the preload bridge to the backend server.
Sources: preload.js:43-98, server.js:192-218, renderer/renderer.js:560-575
The electronAPI Bridge
The preload script exposes the electronAPI object to the window global in the renderer process. This API is the sole method for the frontend to interact with the backend services.
Key API Functions
Chat & Session Management
sendMessage(message, chatId, provider, model): Initiates a streaming request to the backend. It manages an internalAbortControllerto ensure only one request is active at a time and handles the conversion of the fetch response into a readable stream for the UI.abortCurrentRequest(): Immediately cancels the client-sidefetchrequest using the storedAbortController.stopQuery(chatId, provider): Sends a signal to the backend/api/abortendpoint to terminate server-side processing for a specific chat.
Configuration Retrieval
getProviders(): Queries the backend/api/providersendpoint to retrieve available AI model providers (e.g., Claude, Opencode).
Sources: preload.js:11-30, preload.js:43-108
Stream Handling and Data Transformation
One of the critical roles of the preload script is managing the complexity of Server-Sent Events (SSE) and stream decoding.
The sendMessage function returns a custom Promise that resolves to a getReader method. This abstraction allows the renderer to consume the stream without needing to know the implementation details of the fetch API or TextDecoder.
// From preload.js:80-94
resolve({
getReader: async function() {
const reader = response.body.getReader();
const decoder = new TextDecoder();
return {
read: async () => {
const { done, value } = await reader.read();
return {
done,
value: done ? undefined : decoder.decode(value, { stream: true })
};
}
};
}
});
Sources: preload.js:80-94, renderer/renderer.js:578-580
External Navigation Security
The security model extends to how the application handles external links. To prevent the Electron window from navigating to untrusted websites or being used for phishing, main.js implements two main security handlers:
setWindowOpenHandler: Intercepts attempts to open new windows (e.g., viatarget="_blank"), denying the creation of a new Electron window and instead launching the URL in the user's default system browser.will-navigate: Intercepts clicks on links that would change the current page location. It verifies if the URL is local (file://); if not, it cancels the navigation and opens the link externally.
Sources: main.js:46-58
Conclusion
The Preload Script & Security module effectively implements the Principle of Least Privilege within Open Claude Cowork. By strictly defining the electronAPI and enforcing process isolation, the system ensures that the application remains responsive and capable of handling complex AI-driven workflows while maintaining a robust defense against potential exploits.
Sources: main.js:25-34, preload.js:9-10