security(H1): add Content Security Policy

Add CSP in two layers:
1. Meta tag in index.html (works for all builds)
2. HTTP header via Electron session API (defense-in-depth)

Policy: script-src 'self' blocks XSS from loading external scripts
or executing inline scripts. style-src allows 'unsafe-inline' for
Vue's style injection. connect-src allows ws/wss/http/https for
configurable relay and API endpoints.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Patrick Mulligan 2026-03-07 09:36:59 -05:00
commit 1ac50b6add
2 changed files with 27 additions and 1 deletions

View file

@ -6,7 +6,7 @@
* HAL hardware drivers run here (Node.js environment).
*/
import { app, BrowserWindow, ipcMain } from 'electron'
import { app, BrowserWindow, ipcMain, session } from 'electron'
import path from 'node:path'
import fs from 'node:fs'
import { fileURLToPath } from 'node:url'
@ -280,6 +280,18 @@ ipcMain.handle('hal:cleanup', async () => {
// App lifecycle
app.whenReady().then(() => {
// Enforce Content Security Policy via HTTP headers (defense-in-depth alongside meta tag)
session.defaultSession.webRequest.onHeadersReceived((details, callback) => {
callback({
responseHeaders: {
...details.responseHeaders,
'Content-Security-Policy': [
"default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; connect-src 'self' ws: wss: http: https:; img-src 'self' data: blob:; font-src 'self'; frame-src 'none'; object-src 'none'",
],
},
})
})
initDatabase()
// Seed cassettes from env/preset if DB table is empty.