The core exploit pipeline: XSS to Remote Code Execution

In a normal web browser, an XSS vulnerability allows an attacker to steal session cookies or run script operations inside the sandbox. In an Electron app, the frontend has access to native operating system APIs via the Node.js runtime if configured incorrectly.

If your application has nodeIntegration set to true and contextIsolation set to false, any injected script can import Node's child process module and run system commands. This is why we prioritize testing the context boundary.

Pentest finding

Node integration in Electron client allows full system access

During a security audit of a desktop stock trading client, we found a stored XSS in the user dashboard. Because the app ran with nodeIntegration: true, we executed: require('child_process').exec('calc.exe'). On macOS, this allowed us to run terminal scripts to copy local documents and export them to our logging servers.

Auditing preload scripts and context bridge configurations

To build a secure Electron app, you must set nodeIntegration: false and contextIsolation: true. Communication between the frontend and Node must occur through a secure preload.js script using the contextBridge API.

However, developers often make mistakes when configuring the bridge. If you expose raw Node modules directly through the bridge, the security boundary is bypassed:

// VULNERABLE: Exposing raw ipcRenderer methods
contextBridge.exposeInMainWorld('api', {
  send: (channel, data) => ipcRenderer.send(channel, data) // Allows any channel access
});

// SECURE: Restricting to specific channels and inputs
contextBridge.exposeInMainWorld('api', {
  sendTransaction: (amount, recipient) => {
    const safeChannel = "transaction:process";
    ipcRenderer.send(safeChannel, { amount, recipient });
  }
});

Checking webPreferences settings

During our penetration tests, we check the main process files to audit your webPreferences configurations. We verify that:

Electron Security Checklist

If your application uses Electron, verify these settings in your main process:

  1. Verify sandbox: true: Enforce chromium level process sandboxing.
  2. Sanitize inputs in preload.js: Check the parameters passed from JavaScript before sending them over IPC to Node.
  3. Restrict navigate event: Prevent the application from navigating to untrusted remote URLs that could load malicious scripts.

Get your Electron app audited

A misconfigured Electron application exposes your customers to severe operating system security risks. We will check your main configurations, test your context bridges, and verify your preload code.

Book an Electron Pentest