-
Notifications
You must be signed in to change notification settings - Fork 0
Security
GamesDownloader ships with a layered set of defensive controls covering authentication, network access, server-side fetching, and stored secrets. This page is the map: it explains the design stance behind the hardening and gives a one-line summary of each control with a link to where it is configured or explained in depth. For the step-by-step how-to, see Network & Security.
- Design stance and threat model
- Authentication
- Network and abuse protection
- Server-side fetching and injection
- Secrets and configuration hardening
- Access control and distribution
- Content scanning, headers, and monitoring
- Control summary
GamesDownloader is a self-hosted application. The design deliberately accepts two facts:
-
LAN-only with no reverse proxy must keep working. A plain
docker compose upreachable only on your local network is a fully supported deployment. None of the built-in controls require a TLS-terminating proxy, HSTS, or a public hostname to run. Features that only make sense with HTTPS (such as Strict-Transport-Security) activate themselves automatically when a proxy signals a secure connection and stay dormant otherwise. - Securing the local network is the administrator's responsibility. The application does not try to defend against an already-hostile LAN. If untrusted devices share your network, isolate the app port at the firewall or bind it to your reverse proxy host.
The priority of the built-in controls is narrow and explicit: prevent compromise when you choose to expose the instance to the internet. That means preventing remote code execution, account takeover, and the server being tricked into reaching internal services. Everything below is oriented around those three outcomes.
Two things are out of scope by design. Plugins run trusted server-side code (installing a plugin is equivalent to trusting its author with your server), so plugin isolation is handled by gating and documentation rather than a sandbox - see Plugin Trust Model. And a compromised or hostile LAN is assumed to be the operator's problem, not the app's.
-
JWT access + refresh tokens. Short-lived access tokens carry the user, role, and permission scopes; longer-lived refresh tokens mint new access tokens. Every token carries a random 128-bit
jti, so individual sessions can be revoked instantly via a Redis blocklist with a database session check as a fallback. Configured under Users & Permissions. - bcrypt password hashing. Passwords are hashed with bcrypt (per-password salt); plaintext is never stored.
- Optional TOTP two-factor. Standard RFC 6238 authenticator-app codes (Google Authenticator, Authy, 1Password, and similar). A candidate secret is held in a short-lived pending buffer and only persisted once the user proves they configured their app; one-time recovery codes are themselves stored as bcrypt hashes so a database leak yields no working backup keys.
- Single Sign-On (SSO). OpenID Connect providers plus Google, GitHub, and Microsoft, in alongside or replace login modes. See Users & Permissions.
- Brute-force protection. Redis fixed-window rate limiting per client IP with configurable attempt threshold, ban duration, and whitelist. The configurable ban guards the login endpoint and the Basic-auth path, so credential guessing on API requests cannot slip past it. Registration and token refresh are protected separately by a fixed HTTP 429 rate limit that issues no ban and shares no counter with login.
-
Safe real-IP handling. Forwarded headers (
CF-Connecting-IP,X-Real-IP,X-Forwarded-For) are honoured only when the direct TCP peer is a trusted proxy - either a private/LAN address or one you list explicitly. A client connecting directly from an untrusted peer cannot spoof its address to dodge the IP allowlist or a ban. - IP allowlist and trusted-proxy / CORS control. Optionally restrict access to specific IPs or CIDR ranges, declare which upstream proxies to trust, and set allowed CORS origins - all applied dynamically without a restart.
All of the above are configured in Network & Security.
-
SSRF guards on server-side URL fetching. Before the server fetches a user-supplied URL, its host is resolved and checked: loopback, link-local (including the
169.254.169.254cloud-metadata endpoint), reserved, unspecified, and multicast addresses are always rejected. Private LAN addresses are rejected too, except on the URL-upload endpoint where a self-hoster may legitimately pull a file from their own NAS. This stops a crafted URL from reaching internal admin ports or metadata services. -
Sanitised HTML on user-supplied content. Fields that render rich text (game descriptions, usernames, notification bodies, and similar) are passed through an HTML sanitiser on the client, and the Content-Security-Policy blocks inline script execution as a second line of defence, so an injected
<script>in scraped or user-entered text cannot run.
-
Strong auth secret enforced at startup. The app refuses to start if
GD_AUTH_SECRET_KEYis a known default or empty value (signing with a public value is a total auth bypass), and treats a secret shorter than 32 characters as fatal in production. See Configuration. - Secrets encrypted at rest. Sensitive configuration values - scraper API keys, the SMTP password, and OAuth client secrets - are encrypted with a key derived from the auth secret before they are written to the database, so a database dump alone does not expose them.
- Role-based access control. Four roles (Admin, Uploader, Editor, User) map to permission scopes, with per-user grant/revoke overrides and per-game access restrictions layered on top. See Users & Permissions.
- Download tokens. Shareable, time-limited download links that can be capped by a maximum download count and optionally protected with a password, letting you hand out a single file without granting an account. See Downloads & Torrents.
- ClamAV antivirus. Bundled in the container for manual and automatic scans (on upload and after GOG downloads), with live progress and scan history. First run: Settings → Security → ClamAV, then Update Definitions.
-
Security headers.
X-Content-Type-Options,X-Frame-Options,Referrer-Policy, andX-XSS-Protectionon every response, a restrictive Content-Security-Policy that locks script execution to the app's own origin, andStrict-Transport-Securityadded only when the connection is HTTPS. - Audit log. A rolling, filterable log of security events (logins, IP unbans, password resets, and TOTP changes) in the admin UI. A brute-force ban itself is not an audit event - it is recorded in the application log and can raise an email alert.
- Email security alerts. Optional per-event notifications for failed logins, logins from new IP addresses, new registrations, admin privilege grants, and brute-force bans, plus a periodic security report. See Email & Notifications.
| Control | Prevents | Where |
|---|---|---|
| JWT + bcrypt + TOTP | Account takeover | Users & Permissions |
Session revocation (jti blocklist) |
Stolen-token reuse | Users & Permissions |
| Brute-force + safe real-IP | Credential guessing, ban evasion | Network & Security |
| IP allowlist / trusted-proxy / CORS | Unwanted network access | Network & Security |
| SSRF guard | Reaching internal services | Network & Security |
| HTML sanitising + CSP | Script injection (XSS) | this page |
| Startup auth-secret check | Token forgery | Configuration |
| Encrypted secrets at rest | Database-dump exposure | Configuration |
| RBAC + per-game access | Privilege escalation | Users & Permissions |
| Download tokens | Uncontrolled file sharing | Downloads & Torrents |
| ClamAV | Malware distribution | Configuration |
| Security headers | Clickjacking, MIME sniffing | this page |
| Audit log + email alerts | Undetected intrusion | Email & Notifications |
The + in the following capability view marks where each protection applies:
| Deployment | Auth + RBAC | Brute-force | Security headers | HSTS | Encrypted secrets |
|---|---|---|---|---|---|
| LAN-only, no proxy | + | + | + | + | |
| Behind HTTPS reverse proxy | + | + | + | + | + |
Note: plugins are trusted server-side code and are intentionally excluded from this hardening model. Only install plugins you trust, and read Plugin Trust Model before exposing an instance that accepts plugin uploads.
Next: Network & Security for the configuration how-to, and Plugin Trust Model for the plugin threat model.
Getting Started
Configuration
Features
- Dashboard
- Library
- Collections
- Game Requests
- GOG Integration
- ROMs & Emulation
- Downloads & Torrents
- Users & Permissions
- Themes
Plugin Development
Reference