agentsclimarketplace

Electron security

Skill ShieldNet-360/secure-vibe/dist/agent-skills/.agents/skills/electron-security

SecureVibe — prevention-first security for AI-written code. Signed SKILL.md knowledge that makes AI coding assistants write secure code at generation time, plus a deterministic CI gate. Offline · keyless · Ed25519-signed. By ShieldNet360.

Install
npx -y skills add ShieldNet-360/secure-vibe --skill electron-security

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Harden Electron apps: renderer trust boundary (nodeIntegration, contextIsolation, sandbox), contextBridge/IPC allowlists, shell.openExternal, navigation guards, deep-link auth, safeStorage — Applies to: when generating Electron main-process code (BrowserWindow, ipcMain, app events); when generating a preload script or contextBridge surface; when wiring custom-protocol / deep-link handlers; when storing tokens or secrets in an Electron app; when reviewing Electron IPC, navigation, or window configuration

SKILL.md

6.4 KB, as published. Nobody here has run it

<!-- Native skill bundle for agent-skills (cross-tool convention). Generated by `secure-vibe dev regenerate`. --> <!-- Do not edit by hand; the source of truth is skills/electron-security/SKILL.md. -->

Electron Desktop Security

Harden Electron apps: renderer trust boundary (nodeIntegration, contextIsolation, sandbox), contextBridge/IPC allowlists, shell.openExternal, navigation guards, deep-link auth, safeStorage

ALWAYS

  • Configure every BrowserWindow with nodeIntegration: false, contextIsolation: true, and sandbox: true. The preload + contextBridge is the supported way to give the renderer capabilities — the page never needs Node.
  • Expose a minimal, typed API from the preload via contextBridge.exposeInMainWorld. Expose named functions only — never hand the renderer ipcRenderer, require, process, or whole modules.
  • Validate every IPC argument in the main-process handler: type-check, bound, and allowlist. The renderer is an attacker-controlled input source.
  • Spawn child processes with execFile / spawn and an argument array — never exec with a shell string built from renderer input. Allowlist each argument (e.g. ^[A-Za-z0-9_-]+$).
  • Confine filesystem paths: path.resolve(base, input) then verify the result startsWith(base + path.sep). Reject absolute paths and .. segments.
  • Allowlist shell.openExternal to https: (and mailto: if needed) after parsing the URL. Reject file:, custom schemes, and anything else.
  • Add navigation guards: app.on('web-contents-created', …) with contents.on('will-navigate', …) and contents.setWindowOpenHandler(…) that deny by default against a strict origin allowlist.
  • Remember the contextBridge surface is exposed to whatever origin the webContents currently holdsexposeInMainWorld does not re-check origin after a navigation. So a single missing will-navigate guard lets a remote / attacker origin inherit your entire IPC surface (this is how a stored hyperlink → navigation becomes 1-click RCE). The nav guard is the primary control; as defense-in-depth, gate the preload on location before exposing.
  • Before attaching session tokens / cookies to an outbound request, verify the target host is on your own-API allowlist. Never attach credentials to a renderer-supplied URL.
  • Bind custom-protocol / deep-link auth to a one-time state / PKCE value the app generated and is waiting for; validate before storing any token.
  • Store tokens with Electron safeStorage (OS keychain / DPAPI / libsecret), not app-level crypto. Enable ASAR integrity + code signing for release.
  • Treat every server the app connects to — backend, simulation / compute node, auto-update channel, a multi-tenant cloud session — as potentially attacker-controlled (compromised, co-tenant, or MITM). Never load a server URL into a BrowserWindow / <webview> that carries your preload, and never feed a server response into an IPC sink (file path, shell arg, openExternal URL) without the same validation you apply to renderer input.
  • Harden parsers that consume untrusted server / stream data (binary frames, SDF / XML, model files): bound every length field before allocating, cap recursion and <include>-style expansion (circular refs → infinite loop / fetch), and wrap the parse in try/catch. Otherwise a malicious server crashes or hangs the renderer (DoS), even when memory-safety prevents RCE.

NEVER

  • Set nodeIntegration: true, disable contextIsolation, disable webSecurity, or set allowRunningInsecureContent: true — especially when the window loads remote or navigable content.
  • Concatenate renderer input into a shell string (child_process.exec(\docker kill ${names}`)`) — command injection.
  • Concatenate a renderer-supplied path for fs read/write (${BASE}${filePath}) — path traversal / arbitrary file write.
  • Call shell.openExternal on an arbitrary or renderer-controlled URL — file: / custom protocol handlers are a local-launch / RCE vector.
  • Attach Authorization / session cookies to a URL the renderer chose without a host allowlist — XSS then exfiltrates the token.
  • Accept a deep-link auth token (myapp://auth?refresh-token=…) without origin / state validation — login CSRF / session fixation.
  • Encrypt tokens at rest with AES-CBC (no integrity) or a key derived solely from a locally recoverable machine ID, and never keep a PLAINTEXT: fallback path.
  • Ship a frameless / chromeless navigable window (frame: false, no address bar): after a redirect the user has no visual cue they left the app, so a phished navigation can silently clone your UI. Frameless is acceptable only behind a hard navigation guard.
  • Assume the renderer (or its rendered content) is the only untrusted input — a backend / sim / update server the app trusts can itself be compromised or, in multi-tenant deployments, driven by another tenant.

KNOWN FALSE POSITIVES

  • Dev builds that load over http://localhost:<port> with relaxed settings — the rules apply to release builds; ensure dev config never ships.
  • A custom protocol (myapp://) for OAuth callbacks is expected — the control is state/PKCE validation, not the scheme's existence.
  • contextBridge-exposed functions are intentional capabilities; review what each one does (and whether it validates input), not the fact that the bridge exists.
  • shell.openExternal on a hard-coded https:// constant (not user input) is fine.
  • A frameless window that loads only local first-party content (file:// / packaged app) behind a deny-by-default nav guard is fine — the risk is frameless plus navigable to remote origins.
  • Connecting to a backend and rendering its data (telemetry JSON, numbers, binary frames) is normal desktop behaviour. The control is bounding / validating that data and never treating it as HTML, a filesystem path, or a shell argument — not avoiding the connection itself.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.