-
Notifications
You must be signed in to change notification settings - Fork 17
Security
This page covers the controls operators tune (bans, scan protection, proxies) and the design decisions that protect a TinyIce instance. For login mechanisms (roles, passkeys, OIDC, tokens) see Authentication and Users. For the vulnerability disclosure process see the security policy.
| Control | Config | Behaviour |
|---|---|---|
| Ban | banned_ips |
Dropped at Accept() — banned IPs never reach a handler. |
| Whitelist | whitelisted_ips |
Bypass scan/ban checks (local admin, monitoring nodes). |
| Scan lockout | automatic | An IP probing many distinct paths is temporarily locked out. |
| Auth lockout | automatic | Repeated failed source/admin logins lock the IP out. |
Manage bans and whitelists in Admin → Security (CIDR supported), along with an
audit-log tab (filterable; enable with audit_enabled).
Lockout triggers on distinct paths probed (threshold 25), not raw hit count, so a player hammering one offline mount on reconnect doesn't trip it. Known prefetch / extension paths are skipped entirely. A whitelisted IP bypasses the lockout, so an operator can recover their own access after a misconfiguration without restarting the service.
If TinyIce sits behind nginx / Caddy / Traefik / a Cloudflare tunnel, list the
proxy peer addresses in trusted_proxies (exact IPs or CIDRs):
"trusted_proxies": ["127.0.0.1", "10.0.0.0/8"]-
X-Forwarded-For/X-Real-IPare then honoured for scan detection, bans, and audit logging — you see real client IPs, not the proxy's. -
When the list is non-empty, loopback stops being auto-whitelisted. This is
deliberate: behind a proxy, every request appears to come from
127.0.0.1, so auto-whitelisting loopback would whitelist the entire internet.
Get this wrong and either bans don't work (no trusted_proxies) or everyone is
trusted (proxy not actually in front). See Deployment.
-
CSRF on every mutating admin form, including
/admin/golive/chunkand the pending-user approve/deny endpoints. -
Privilege gates on shell-executing actions: AutoDJ and webhook CRUD
require
superadmin, because both accept strings the server runs as the service user. Adjcannot register an AutoDJ with a malicioussong_command. - SSRF guard on outbound URLs (Webhooks and relays): loopback, RFC 1918, and link-local targets are rejected.
- Source auth on every ingest path, including WebRTC source-ingest (the subject of CVE-2026-45327, below). Wrong-password attempts feed the auth lockout.
-
Constant-time comparisons for login (bcrypt always runs) and the MPD
password (
crypto/subtle). -
Idle read deadlines (60 s) on hijacked Icecast SOURCE connections, relay
bodies, RTMP, and SRT reads — a silent/frozen peer can't pin a goroutine + FD
- mount forever.
- Bounded parsers. The TS demuxer resyncs byte-by-byte; the MPD command-list accumulator is capped; the Ogg page-boundary scanner always advances ≥1 byte (the fix for a production-wide hang — see the 2.5.0 changelog).
- DOMPurify on admin-authored landing Markdown before render (closed an admin→visitor XSS).
-
XSS-safe error surfacing and atomic config writes (serialised, temp +
rename) so concurrent admin writes can't corrupt
tinyice.json.
The .deb/.rpm install a dedicated unprivileged tinyice user and a systemd
unit with NoNewPrivileges, ProtectSystem=strict, ProtectHome,
PrivateTmp, PrivateDevices, MemoryDenyWriteExecute, a restricted syscall
and address-family set, and a CapabilityBoundingSet of just
CAP_NET_BIND_SERVICE. The unit ships masked so an unconfigured daemon can't
auto-start. See Deployment.
| ID | Severity | Summary | Fixed in |
|---|---|---|---|
| CVE-2026-45327 | 7.4 High | Missing auth on the WebRTC source-ingest endpoint (POST /webrtc/source-offer) let any reachable user hijack a mount's broadcast. |
2.5.0 |
Run a current release. Security fixes land on the latest minor line; see the supported-versions table.
Use GitHub
private vulnerability reporting,
or email the maintainer with SECURITY in the subject. Do not open a public
issue for a vulnerability. Maintainers acknowledge within 72 h and aim for a
patched release within 7 days for High/Critical. Advisories go through GitHub's
CNA path and get a CVE ID. Full scope (in/out) is in the
security policy.
Next: Deployment · Observability · Authentication and Users
Repository · Releases · Issues · Security policy · Apache-2.0
Getting started
Streaming
Integrations
Operations
Internals
Help