# Security

> Use when hardening an Electron app or reviewing renderer/IPC security — contextIsolation, nodeIntegration, sandbox, webSecurity, Content-Security-Policy (CSP), onHeadersReceived, setWindowOpenHandler, will-navigate, validate IPC sender (senderFrame), shell.openExternal, setPermissionRequestHandler, @electron/fuses (RunAsNode, OnlyLoadAppFromAsar), asar integrity, XSS jumping out of the renderer,…

- **Type:** Skill
- **Install:** `agentstack add skill-ohvignas-claude-electron-skills-security`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [ohvignas](https://agentstack.voostack.com/s/ohvignas)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [ohvignas](https://github.com/ohvignas)
- **Source:** https://github.com/ohvignas/claude-electron-skills/tree/main/skills/security

## Install

```sh
agentstack add skill-ohvignas-claude-electron-skills-security
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Electron Security

## Overview
Electron apps run web content with OS-level reach, so an XSS bug can become remote code execution. Security is defense-in-depth: keep the renderer untrusted (isolated + sandboxed), expose only narrow APIs over IPC, lock down navigation/new-windows/permissions, and flip build-time fuses.

## When to use
- Configuring `webPreferences` for any `BrowserWindow`/``.
- Loading any remote or partially-trusted content (XSS could "jump out of the renderer").
- Adding a Content-Security-Policy, IPC handlers, `shell.openExternal`, or window/navigation handling.
- Pre-release hardening: `@electron/fuses`, asar integrity, permission handlers, packaging review.

**When NOT to use:** for the IPC mechanics themselves (`invoke`/`handle`/`contextBridge`) see `process-model-ipc`; for navigation/`` deep-dives see `webcontents-navigation`.

## Quick reference
| API / option | Purpose |
|---|---|
| `contextIsolation: true` | Preload + Electron run in a separate context (default ≥12). |
| `nodeIntegration: false` | No Node globals in the renderer (default). |
| `sandbox: true` | Chromium OS sandbox for the renderer (default ≥20). |
| `webSecurity: true` | Keep same-origin policy on (never disable). |
| `session.defaultSession.webRequest.onHeadersReceived` | Inject a `Content-Security-Policy` header. |
| `contents.setWindowOpenHandler(handler)` | Deny-by-default `window.open`/target=`_blank`. |
| `contents.on('will-navigate', …)` | Block navigation off your origin. |
| `e.senderFrame` / `validateSender` | Verify the origin of every IPC message. |
| `ses.setPermissionRequestHandler(handler)` | Approve/deny camera, geolocation, etc. (default: approve all). |
| `flipFuses(electron, {…})` | Build-time fuses: `RunAsNode`, `OnlyLoadAppFromAsar`, … |

## Example
```js
// main.js — a hardened window, app-wide CSP, validated IPC, deny-by-default popups.
const { app, BrowserWindow, ipcMain, session, shell } = require('electron')
const path = require('node:path')

function createWindow () {
  const win = new BrowserWindow({
    webPreferences: {
      contextIsolation: true,   // isolate preload from page (default, but be explicit)
      nodeIntegration: false,   // no Node in the renderer
      sandbox: true,            // OS sandbox: an XSS can't reach the FS/Node
      webSecurity: true,        // keep same-origin policy
      preload: path.join(app.getAppPath(), 'preload.js')
    }
  })
  win.loadURL('https://example.com')
}

app.whenReady().then(() => {
  // CSP as a response header is enforced even if the page omits its own meta tag.
  session.defaultSession.webRequest.onHeadersReceived((details, callback) => {
    callback({
      responseHeaders: {
        ...details.responseHeaders,
        'Content-Security-Policy': ["default-src 'self'; script-src 'self'"]
      }
    })
  })

  // Only this trusted frame may invoke privileged IPC.
  ipcMain.handle('get-secrets', (event) => {
    if (new URL(event.senderFrame.url).host !== 'example.com') return null
    return getSecrets()
  })

  createWindow()
})

// Apply to EVERY webContents (windows AND ), not just the first window.
app.on('web-contents-created', (_event, contents) => {
  // Deny all new-window requests; route safe links to the OS browser instead.
  contents.setWindowOpenHandler(({ url }) => {
    if (url.startsWith('https://example.com/')) setImmediate(() => shell.openExternal(url))
    return { action: 'deny' }
  })
  // Block navigation away from our origin.
  contents.on('will-navigate', (event, navigationUrl) => {
    if (new URL(navigationUrl).origin !== 'https://example.com') event.preventDefault()
  })
})
```

## Common mistakes
- **Disabling `webSecurity` (or setting `allowRunningInsecureContent`)** to "fix" CORS/mixed content — this turns off the same-origin policy. Fix the server/CSP instead.
- **Exposing raw `ipcRenderer.on`/`send`** via `contextBridge` — wrap each channel in a typed function so the page can't drive arbitrary IPC.
- **Returning `{ action: 'allow' }` by default** in `setWindowOpenHandler`, or handling only `BrowserWindow` and forgetting `` — use `web-contents-created` to cover all frames.
- **Trusting IPC senders** — any web frame can message the main process; check `event.senderFrame.url` before privileged work.
- **`shell.openExternal(userControlledUrl)`** — can run arbitrary commands; only pass validated/hardcoded URLs.

## Reference
Full API tables: [reference.md](reference.md)

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [ohvignas](https://github.com/ohvignas)
- **Source:** [ohvignas/claude-electron-skills](https://github.com/ohvignas/claude-electron-skills)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-ohvignas-claude-electron-skills-security
- Seller: https://agentstack.voostack.com/s/ohvignas
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
