fix(security): bump golang.org/x deps and add container CVE scan gate

- Bump golang.org/x/{net,crypto,sys,text,term} to latest patches to
  clear GHSA module advisories flagged by Docker Scout.
- Add Docker Scout CVE gate to the release workflow (fails only on
  FIXABLE critical/high; unfixed upstream ffmpeg codec CVEs are accepted
  and documented in SECURITY.md).
- Add weekly + manual docker-rebuild workflow so newly fixed base/
  ffmpeg/Go patches land on :latest between tagged releases.
- Document container image vuln-scanning policy and hardening in
  SECURITY.md.
This commit is contained in:
Deivid Soto 2026-05-21 16:53:23 +02:00
parent fb44f3711e
commit 283eb54a74
5 changed files with 128 additions and 19 deletions

View file

@ -59,6 +59,50 @@ This project follows these security practices:
- **Non-root Docker** — Container runs as unprivileged user (UID 1000)
- **Dependency scanning** — Automated via Dependabot
## Container Image Vulnerability Scanning
The Docker image (`torrentclaw/unarr`) is scanned by Docker Scout on Docker Hub and
by a CVE gate in CI (see `.github/workflows/`). Two things matter when reading the
Docker Hub vulnerability count:
- **Scanner database differs.** Docker Hub (Scout) matches `package@version` against
NVD/GHSA. Trivy/Alpine `secdb` only lists CVEs Alpine has acknowledged and patched.
A high Scout count with a clean Trivy report is expected, not a contradiction.
- **The bulk comes from the bundled `ffmpeg` codec stack.** Alpine's `ffmpeg`
package pulls ~40 codec/parser libraries (`x264`, `x265`, `libvpx`, `aom`,
`dav1d`, `libtheora`, `libvorbis`, `libwebp`, `libbluray`, `libopenmpt`, …).
Each carries a long NVD history that Alpine does not backport. ffmpeg is a
**functional dependency** — the WebRTC/HLS transcode pipeline shells out to
`ffmpeg`/`ffprobe` to decode untrusted media and re-encode to H.264 + AAC.
### Accepted risk and policy
- **Fixable** CRITICAL/HIGH findings **block** a release (CI CVE gate, `only-fixed`).
- **Unfixed-upstream** codec CVEs are tracked but **accepted**: there is no patched
Alpine package to move to, and dropping codecs would break playback of common
formats. They are mitigated by the hardening below rather than eliminated.
- Images are **rebuilt and re-pushed weekly** (scheduled workflow) so any newly
*fixed* base/ffmpeg/Go patch lands between tagged releases.
### Mitigations (run the container hardened)
Crafted media (torrents are untrusted input) is the realistic attack vector against
ffmpeg's parsers. The shipped `docker-compose.yml` already applies:
- **Non-root** user (UID 1000), **read-only** root filesystem, writable `tmpfs` only.
- **Resource limits** (memory/CPU) to bound a runaway decode.
Recommended additions for exposed deployments:
```yaml
cap_drop: ["ALL"]
security_opt:
- no-new-privileges:true
```
If you do not need WebRTC/HLS transcoding, you can run with transcoding disabled to
avoid feeding untrusted media to ffmpeg at all.
## Disclosure Policy
We follow coordinated disclosure. We will credit reporters in the release notes unless they prefer to remain anonymous.