The deployment serves a strict HTTP Content Security Policy configured in vercel.json and mirrored in the Vite preview server:
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' data: https://fonts.gstatic.com https://tiles.openfreemap.org https://*.openfreemap.org; img-src 'self' data: blob: https://tiles.openfreemap.org https://*.openfreemap.org https://tile.openstreetmap.org https://*.tile.openstreetmap.org https://basemaps.cartocdn.com https://*.basemaps.cartocdn.com; connect-src 'self' blob: https://tiles.openfreemap.org https://*.openfreemap.org https://tile.openstreetmap.org https://*.tile.openstreetmap.org https://basemaps.cartocdn.com https://*.basemaps.cartocdn.com; worker-src 'self' blob:; child-src 'self' blob:; frame-ancestors 'none'; form-action 'none'; base-uri 'self';| Directive | Scope | Rationale & Tradeoff |
|---|---|---|
script-src 'self' |
Strict | All dynamic evaluation (eval(), Function(), WASM dynamic compilation) is strictly forbidden. MapLibre GL JS functions with pure JavaScript rendering. |
style-src 'self' 'unsafe-inline' https://fonts.googleapis.com |
Pinned + Relaxed | 'unsafe-inline' is required for MapLibre GL dynamic canvas/DOM styling (markers, popups, scalebars) and React dynamic inline style attributes. Pinned to Google Fonts for external font stylesheets. |
font-src 'self' data: https://fonts.gstatic.com https://tiles.openfreemap.org https://*.openfreemap.org |
Pinned | Pinned to Google Fonts CDN (fonts.gstatic.com) for Space Grotesk/JetBrains Mono fonts, OpenFreeMap for PBF vector glyphs, and data: for KaTeX mathematical font subsets. |
connect-src / img-src |
Pinned | Pinned to OpenFreeMap (tiles.openfreemap.org, *.openfreemap.org), OpenStreetMap (tile.openstreetmap.org, *.tile.openstreetmap.org), and Carto (basemaps.cartocdn.com, *.basemaps.cartocdn.com). Wildcards are scoped to subdomain prefixes only. api.mapbox.com is omitted. |
worker-src / child-src |
'self' blob: |
Required for MapLibre background workers (blob:) and off-thread Vite Web Workers ('self' blob:) computing 2D hyperbolic LOP grids and spatial ASF simulations. |
frame-ancestors 'none' |
Strict | Prevents clickjacking by forbidding embedding in foreign iframes. |
form-action 'none' |
Strict | Simulator has no form submissions. |
base-uri 'self' |
Strict | Prevents base tag hijacking attacks. |
The site serves:
Strict-Transport-Security: max-age=63072000; includeSubDomains; preloadWarning
Preload Decision Caution:
While preload is safe on standard *.vercel.app preview deployments, if attaching a custom production domain (e.g., simuloran.org), do NOT submit the domain to the HSTS preload list (hstspreload.org) without a deliberate engineering decision. Inclusion in browser preload lists is permanent and irreversible for months, and will break any internal subdomains that lack valid public HTTPS certificates.
To maintain a clean production namespace while supporting automated sub-pixel regression testing:
- Gating Mechanism: Inspection hooks
window.__maplibreInstanceandwindow.__baselineGeoJsonare strictly gated insrc/components/map/MapView.jsxbehind:if (typeof window !== 'undefined' && (import.meta.env.DEV || window.__SIMULORAN_E2E__ || window.__LORAN_E2E__)) { window.__maplibreInstance = mapInstance; }
- Production Visitor Experience: In production builds (
npm run build),import.meta.env.DEVisfalse. Normal visitors tohttps://simuloran.vercel.app(and incomingsimuloran.com/simuloran.org) will havewindow.__maplibreInstance === undefinedandwindow.__baselineGeoJson === undefined. - E2E Automation Hook: Automated test suites (Playwright) explicitly inject
window.__SIMULORAN_E2E__ = true(or legacywindow.__LORAN_E2E__ = true) viapage.addInitScript()before page navigation to inspect map coordinate projection accuracy and worker layer readiness. - Threat Model & State Exposure: The simulator contains no user authentication, no database, no session credentials, and no PII. All data structures represent synthetic radio navigation physics (TDOA, ECD, ASF, transmitter coords). Tampering with the MapLibre instance or GeoJSON layer via console does not expose private data or present any security privilege escalation.
- Tamper-Proofing Tradeoff: Setting
window.__SIMULORAN_E2E__ = truemanually in DevTools prior to reload is technically possible by any visitor. This is an accepted engineering tradeoff: the hook is gated to maintain a clean default window namespace, not as a security barrier, which is acceptable since no privileged or sensitive state exists.