Skip to content

Latest commit

 

History

History
46 lines (40 loc) · 8.81 KB

SECURITY-CHECKLIST.md

File metadata and controls

46 lines (40 loc) · 8.81 KB

Electron security checklist

Electron security

How CFEngine Policy Builder follows Electron's security recommendations, item by item, with the code that shows it. The Electron security workflow checks every item marked ✅ on each push and pull request, and weekly:

# Recommendation Status Evidence
1 Only load secure content ✅ The packaged app loads its own files only, from app://bundle/ (item 18). Everything the main process fetches itself is https: the Enterprise hub (checkedUrl in src/main/hub.ts refuses anything else), the masterfiles versions index (VERSIONS_URL in src/main/project.ts), the CFEngine Build module index and module details (INDEX_URL, DETAILS_URL in src/main/modules.ts; a README from them becomes plain data (readmeTree: allowlisted tags, http(s) links, no attributes) rendered as React elements, never as HTML). http:// appears only for the development server on localhost. The exception is a project's git remote: the user's choice of URL (REMOTE_URL in src/main/deploy.ts also takes http://, git://, file:// and local paths), fetched and pushed by the system's git.
2 Do not enable Node.js integration for remote content ✅ nodeIntegration is never enabled (createWindow in src/main/index.ts); the running page has no require or process.
3 Enable context isolation ✅ contextIsolation: true in createWindow (src/main/index.ts).
4 Enable process sandboxing ✅ sandbox: true in createWindow (src/main/index.ts); no --no-sandbox.
5 Handle session permission requests from remote content ✅ setPermissionRequestHandler and setPermissionCheckHandler in src/main/index.ts grant only clipboard-sanitized-write (Copy in Generated Policy) and deny the rest, whether requested or only checked.
6 Do not disable webSecurity ✅ Never set; the running window reports webSecurity: true.
7 Define a Content Security Policy ✅ The <meta http-equiv="Content-Security-Policy"> in src/renderer/index.html: default-src 'self', script-src 'self' (no inline scripts, no eval). style-src allows 'unsafe-inline', which Emotion/MUI need for their injected styles. img-src adds GitHub's hosts (github.com, raw.github.com, *.githubusercontent.com) for module READMEs' images and maintainers' avatars; images elsewhere are shown as links (githubImage in src/renderer/src/modules/moduleDetails.ts).
8 Do not enable allowRunningInsecureContent ✅ Never set; the running window reports false.
9 Do not enable experimental features ✅ Never set; the running window reports false.
10 Do not use enableBlinkFeatures ✅ Never set.
11 Do not use allowpopups for WebViews ✅ The app has no <webview>.
12 Verify WebView options before creation ✅ webviewTag stays off (the running window reports false), so no webview can be attached.
13 Disable or limit navigation ✅ The will-navigate handler in src/main/index.ts prevents any navigation away from the loaded page; http(s) links go to the system browser instead.
14 Disable or limit creation of new windows ✅ setWindowOpenHandler in src/main/index.ts always returns { action: 'deny' }; http(s) links open in the system browser.
15 Do not use shell.openExternal with untrusted content ✅ The only shell.openExternal call is in openExternalIfSafe (src/main/index.ts), which passes only http: and https: URLs.
16 Use a current version of Electron ✅ Electron 44 (package.json), checked weekly against Electron's supported majors and npm audit.
17 Validate the sender of all IPC messages ✅ Every ipcMain.handle checks isTrustedFrame (src/main/index.ts): the top frame of our own page only. Feature modules wrap their handlers in trusted(…) (project.ts, deploy.ts, hub.ts, testenv.ts). Unit tests check untrusted senders are refused (project.test.ts, deploy.test.ts).
18 Avoid usage of the file protocol and prefer usage of custom protocols ✅ The packaged app's page is served from app://bundle/ (serveRenderer in src/main/index.ts), which maps to the built renderer folder and returns 404 for anything outside it, encoded .. included. Nothing calls loadFile, and the GrantFileProtocolExtraPrivileges fuse is off (electron-builder.yml).
19 Check which fuses you can change ✅ electronFuses in electron-builder.yml: RunAsNode, EnableNodeOptionsEnvironmentVariable, EnableNodeCliInspectArguments and GrantFileProtocolExtraPrivileges off; EnableCookieEncryption, OnlyLoadAppFromAsar and EnableEmbeddedAsarIntegrityValidation on. Read back from the packaged binary.
20 Do not expose Electron APIs to untrusted web content ✅ The preload (src/preload/index.ts) exposes one object, window.api, of functions over fixed channels; never ipcRenderer itself, and event listeners get only the payload, not the IpcRendererEvent.

Running the checks locally

node scripts/security-checks.mjs          # source checks
node scripts/electron-support-check.mjs   # supported Electron, npm audit
npx electron-vite build && npx playwright test -c e2e/playwright.config.ts e2e/security.spec.ts
npx electron-builder --dir && node scripts/fuses-check.mjs "release/mac/CFEngine Policy Builder.app"