Ghost Arcade Community takes security seriously. Thank you for helping keep the project + its users safe.
Do not file a public GitHub issue for a security vulnerability.
Instead, use GitHub's private vulnerability reporting: https://github.com/riskcapital/ghost-arcade-community/security/advisories/new
Include:
- A description of the vulnerability
- Reproduction steps
- Affected versions
- Your assessment of impact + suggested mitigation
We aim to acknowledge reports within 5 business days and ship a fix within 30 days for critical vulnerabilities. We'll credit you in the release notes unless you prefer to remain anonymous.
Ghost Arcade Community is pre-1.0; only the latest tagged release is actively patched. Older releases will not receive backports.
The Electron renderer is locked down with:
contextIsolation: true- renderer cannot directly access Node APIsnodeIntegration: false- norequire()in renderer scripts- IPC allowlist - only commands in
electron/preload.cjsALLOWED_IPC_COMMANDSreach the main process - Content Security Policy - production blocks runtime eval, limits
connections to local companion services plus documented download hosts,
and injects
object-src 'none'/frame-ancestors 'none'. Inline scripts remain allowed for local animation surfaces; imported JS animation HTML is rendered in a sandboxed frame. Seeelectron/main.jssetupPermissions()for the full policy. setWindowOpenHandler-window.open()from the renderer routes to the system browser viashell.openExternal; no child BrowserWindow is created (would otherwise inherit the IPC bridge)will-navigateblocker - renderer cannot navigate away from the app's own origin, defeating injection-driven page replacement
The HTTP proxy (http_fetch / http_fetch_binary / http_put_binary IPC
handlers in electron/main.js) enforces:
- HTTPS only (HTTP allowed only for
localhost/127.0.0.1) - Host allowlist - defaults to
github.com,*.githubusercontent.com; forks override via theFETCH_HOSTS_ALLOWenv var - Private/loopback/link-local IP literals rejected to prevent SSRF (e.g.
169.254.169.254AWS metadata,192.168.x.xintranet probing)
The WebSocket server (server/ws-server.js, port 9001) and HTTP server
(port 9002) bind to all network interfaces to support the mobile
companion. Desktop builds generate a fresh per-launch pairing token, include
it in the mobile QR URL, and reject WebSocket clients that do not present it.
The HTTP server still serves the mobile UI on the LAN, so only run this app
on networks you trust.
- Unsigned binaries on first launch - Windows SmartScreen + macOS Gatekeeper will warn. See README troubleshooting section.
- Demo project zip downloaded on first launch - fetched from this
project's public GitHub Releases. Forks should override the URL via
the
download_demo_zipIPCurlargument.
Ghost Arcade Community is intended for use:
- On the local machine by the operator
- On a trusted LAN for mobile companion access (one operator + their iPad / phone, both connected to the same Wi-Fi)
It is NOT designed for:
- Running on a public internet host
- Multi-user authentication / authorization
- Use as a server-side service receiving arbitrary uploads
If your fork wants to deploy this in a multi-tenant SaaS context, you will need to add authentication, rate limiting, sandboxing, and audit logging. The AGPL-3.0 license also requires you to publish your modifications.