4.0 KiB
Electron Security Contract
This document records the Electron runtime security contract for the desktop app.
BrowserWindow Defaults
The main window is created in apps/electron-backend/src/app/app.ts with an
explicit hardened webPreferences object:
contextIsolation: truenodeIntegration: falsesandbox: truewebSecurity: truepreload: apps/electron-backend/src/app/api/main.preload.ts
Renderer code must use the preload bridge exposed as window.electron.
Do not re-enable direct Node.js access from Angular code. New desktop-only APIs
should be added to the preload bridge and backed by an ipcMain.handle(...)
owner in the Electron backend.
Navigation And External URLs
The main window owns three navigation gates:
setWindowOpenHandlerdenies every new window.http:andhttps:targets are opened in the operating system browser throughshell.openExternal.will-navigateallows only the trusted renderer URL. Development mode allowshttp://localhost:4200,http://127.0.0.1:4200, andhttp://[::1]:4200.will-redirectapplies the same allow/deny rules so server-side redirects cannot move the app window to an untrusted origin.
Packaged mode allows only the app's resolved index.html renderer file, not
arbitrary file: URLs. External web navigations are denied in the app window
and opened in the operating system browser.
Do not add broad protocol allow-lists for renderer navigation. If a new desktop-only flow needs to open a URL outside IPTVnator, route it through the default browser unless the app window is deliberately meant to host that URL.
Content Security Policy
The Angular shell defines a baseline CSP in apps/web/src/index.html.
The policy keeps the application self-hosted for scripts, blocks object and
frame embedding, limits forms to the app origin, and allows IPTV playback
sources through media-src and connect-src for http:, https:, blob:,
and data:. The policy keeps script-src self-hosted and currently keeps
unsafe-inline for existing inline styles.
Angular production builds must not rely on inline event handlers for stylesheet
activation. Keep web:build:production and web:build:pwa configured without
critical CSS stylesheet deferral (optimization.styles.inlineCritical: false)
unless the CSP is intentionally changed and runtime-validated in both Electron
and the self-hosted PWA.
Before tightening either value, validate both Electron development startup and the PWA/electron build configurations. Playback-heavy changes should also check that HLS, MPEG-TS, thumbnails, and local file playback are still allowed by the policy.
Scoped Request Header Overrides
Inline playback can request temporary User-Agent, Referer, and Origin
header overrides through window.electron.setUserAgent(userAgent, referer, scopeUrl).
The Electron backend handles that IPC in apps/electron-backend/src/app/events/shared.events.ts
and delegates to apps/electron-backend/src/app/services/request-header-overrides.service.ts.
The service registers one session.defaultSession.webRequest.onBeforeSendHeaders
listener and updates layered in-memory overrides instead of stacking a new
listener for every channel change.
Rules:
- empty playlist-level
userAgentandrefererclear all active overrides - empty channel-level
userAgentandrefererwith ascopeUrlclear only the scoped channel override, preserving playlist-level defaults - channel playback should pass the stream URL as
scopeUrl - scoped overrides apply only to the active stream origin and referer origin
- playlist-level user agents and referrers may call the bridge without a
scopeUrl; that is intentionally broader because playlist settings apply to the whole M3U playlist - header names are replaced case-insensitively before canonical
User-Agent,Referer, andOriginnames are written
When changing this flow, keep stale header cleanup covered. Switching from a channel or playlist with custom headers to one without custom headers must clear the previous override.