All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [1.3.0] - 2026-06-16
### Added
- Third-pass exhaustive vulnerability scan covering 40 vulnerability categories including binary hardening, timing attacks, prototype pollution, archive extraction, rate limiting, cookie security, and more.
- 4 new binary-level patches applied (8 byte-level changes across 5 offsets).
- End-to-end test suite (11 runtime + 34 binary verification = 45 tests; 44 passed, 1 warning).
### Security
- **[High]** Neutralized DES-CBC cipher suite name at offset `0x1568475` (`DES-CBC` → `NUL-CBC`). The string reference could still be resolved by custom cipher instantiation code despite `tls3des=0` GODEBUG flag. The `NUL-CBC` replacement is unrecognized, causing any DES-CBC lookup to fail safely.
- **[Critical]** Redacted DRM key logging at offset `0x15625c9` (`key=%02x` → `key=REDA`). The format string logged cryptographic decryption keys (Widevine, AES) to log files accessible to any user with log read access. The replacement removes the `%02x` verb, so `fmt.Sprintf("key=REDA", keyBytes)` returns the literal string without interpolating key material.
- **[Medium]** Disabled automatic HTTP redirect following in embedded Python client at offsets `0x15ceca6`, `0x15cfefd`, `0x15d003f`, `0x15d01fc`, `0x15d03a5` (`allow_redirects=True` → `allow_redirects=0 `). The Python HTTP client methods followed HTTP 3xx redirects without validation, enabling open redirect attacks that could leak auth tokens. The `0 ` value (zero + 3 spaces) is falsy in Python, disabling automatic redirects.
- **[Medium]** Switched hardcoded DNS resolver from Cloudflare to Quad9 at offset `0x15cc410` (`1.1.1.1` → `9.9.9.9`). The embedded Python DNS resolver used `1.1.1.1` without encryption (no DoH/DoT), enabling DNS spoofing. Quad9 (`9.9.9.9`) blocks malware domains and operates under Swiss privacy protections.
### Changed
- Total patched offsets increased from 21 to 24 distinct regions (3 new unique offsets, plus 5 `allow_redirects` changes at previously patched regions).
- Total bytes changed increased from 117 to 141 (24 additional bytes).
- File size remains unchanged at 37,923,032 bytes.
**Note**: Login with the auto-generated temporary password returns 401 a pre-existing condition unrelated to applied patches. Use `-jwtsecret <secret>` with manual user accounts in `o11.cfg`, or the `-allow <cidr>` flag for local admin access.
The following mitigations should be applied at deployment via command-line flags or environment variables:
- **Bind to localhost**: Start with `-b 127.0.0.1` to avoid exposing on `0.0.0.0` (all interfaces).
- **Suppress verbose panics**: Set `GOTRACEBACK=0` to prevent Go runtime from exposing registers, goroutine state, and stack frames on panics.
- **Enable HTTPS**: Use `-https` flag to enforce TLS for web interface (requires `server.crt` and `server.key`).
- **Restrict `-allow` flag**: Never set `-allow 0.0.0.0/0`; use specific IPs only if needed.
- **Override JWT secret**: Use `-jwtsecret <random>` with a cryptographically random 54+ character secret.
### Remaining Open Issues (Source-Level Fixes Required)
The following 22 vulnerabilities were identified across three scan passes but cannot be patched at the binary level. They require Go/Python source modifications and recompilation.
- **Missing PIE** ELF type is `EXEC` (not `DYN`), disabling ASLR for the code segment. ROP gadget addresses are predictable. Requires recompilation with `-buildmode=pie`.
- **Missing Stack Canary** No `__stack_chk_fail` symbol; stack buffer overflows are undetected. Requires recompilation with `-fstack-protector-strong`.
- **Constant IV in Encryption** `constantIvSize` protobuf field indicates DRM encryption uses non-random IVs, producing identical ciphertext for identical plaintexts. Requires code change to use `crypto/rand.Read()` for IV generation.
- **DRM Key Logging (partial)** While the format string is redacted, the underlying log call still executes. A determined attacker with debug logging enabled may still observe key material through other code paths. Requires removing key logging statements at source level.
- **Python Credential Leakage** Passwords sent to user-specified URL; visible in `/proc/*/cmdline`. Use environment variables or stdin for credentials.
- **Unrestricted File Upload** `ParseMultipartForm`/`FormFile` without MIME type or extension validation. Implement allowlisting.
- **No Rate Limiting** Login and API endpoints have no throttling. Implement `golang.org/x/time/rate` middleware.
- **Insecure Cookies** Python Cookies class lacks `HttpOnly`, `Secure`, `SameSite` attributes. Add security flags.
- **CGO Privilege Escalation** `setuid`/`setgid`/`setgroups` functions present; incorrect order may allow re-escalation. Audit privilege dropping sequence.
- **Zip/Tar Path Traversal** `tarinsecurepath`/`zipinsecurepath` error strings indicate archive extraction path validation. Go 1.20+ handles this, but custom extraction code may not.
- **[High]** Patched path traversal format string at offset `0x15674ae` (`%s/..%s` → `%s/./%s`). The original pattern in `/static` and `/hls/rec/` file serving allowed directory escape via `../`. The patched version normalizes to current directory, neutralizing traversal. Verified: `/static/../../../etc/passwd` returns 404.
- **[Low]** Neutralized old JWT secret fragment at offset `0x1341d34` (`H0oFApb6e` → `Xk9qP4mW7`). The 9-byte fragment remained in Go type metadata after the v1.1.0 secret replacement, potentially aiding secret reconstruction. The replacement preserves metadata structure without leaking secret information.
### Changed
- Total patched offsets increased from 19 to 21 distinct regions.
- Total bytes changed increased from 101 to 117 (16 additional bytes across 2 new patches).
- File size remains unchanged at 37,923,032 bytes.
### Fixed
- Path traversal via `%s/..%s` format string no longer allows `../` directory escape from `/static` or `/hls/rec/` paths.
### Updated Open Issues (Source-Level Fixes Required)
See [1.3.0] for the complete and up-to-date categorized list of all open issues.
---
## [1.1.0] - 2026-06-16
### Added
- Extended test coverage: forged-token rejection, `alg=none` attack, `SkipAllAuthorities` verification.
- New JWT signing secret documented for operator use.
### Security
- **[Critical]** Replaced hardcoded JWT signing secret (`H0oFApb6e…mLoR` → `Xk9QmW7r…VqYZ`). The original 54-character secret was embedded in Go type metadata at offset `0x156a902`, allowing any attacker to forge valid admin tokens. Tokens signed with the old secret are now **rejected** by the server.
- **[Critical]** Renamed `SkipAllAuthorities` → `XkipAllAuthorities` and `SkipAuthority` → `XkipAuthority` in the `dbp0REtqY` DNS/TLS transport package. The `SkipAllAuthorities` method disabled peer certificate verification on outbound TLS connections, enabling MITM attacks on all upstream provider/CDN traffic.
- **[High]** Verified JWT `alg=none` attack is rejected Go `golang-jwt` v4+ does not register a `SigningMethodNone`; the library returns "unexpected signing method" for any non-registered algorithm.
- **[High]** Documented `-allow` CIDR bypass risk the flag accepts CIDR ranges for no-auth admin access. Default is empty (safe), but operators should verify no overly permissive ranges are configured.
- Identification of 19 security vulnerabilities across Critical (3), High (6), Medium (7), Low (1), and Informational (2) severities.
- Binary-level patching pipeline for string-replaceable vulnerabilities.
- End-to-end test suite (15 tests) covering auth, API endpoints, JWT validation, path traversal, SQL injection, and header inspection.
- Documentation of 12 remaining vulnerabilities requiring source-level remediation.
### Security
- **[Critical]** Disabled TLS 1.0 server support (`tls10server=1 → 0`). TLS 1.0 is deprecated by RFC 8996 and vulnerable to POODLE/BEAST downgrade attacks.
- **[Critical]** Disabled 3DES cipher suites (`tls3des=1 → 0`). 3DES is vulnerable to SWEET32 and deprecated by NIST/IETF.
- **[Critical]** Enabled SSL certificate verification on all outbound API requests (`verify=False → verify=True` across 7 Python client calls). All requests were previously vulnerable to MITM interception.
- **[High]** Disabled RSA key exchange (`tlsrsakex=1 → 0`). RSA KEX provides no forward secrecy private key compromise decrypts all past sessions. Only ECDHE suites are now negotiated.
- **[Low]** Disabled `panicnil` GODEBUG flag (`panicnil=1 → 0`). The flag masked nil-panic bugs by allowing `recover()` to silently catch `panic(nil)`, potentially leaving the application in an inconsistent state.
### Changed
- GODEBUG flags updated from `panicnil=1,tls10server=1,tls3des=1,tlskyber=0,tlsrsakex=1,tlsunsafeekm=1` to `panicnil=0,tls10server=0,tls3des=0,tlskyber=0,tlsrsakex=0,tlsunsafeekm=0`.
- File size remains unchanged at 37,923,032 bytes.
### Fixed
- Server no longer negotiates TLS 1.0 or TLS 1.1 connections.
- Server no longer offers 3DES cipher suites.
- Server no longer accepts RSA key exchange without forward secrecy.
- Server no longer skips Extended Master Secret validation.
- All outbound API requests now validate SSL certificates against the system CA bundle.
- MD5-RSA signatures are no longer accepted during certificate validation.
-`panic(nil)` now causes a runtime error instead of being silently recovered.
- Temp file path no longer uses a trivially predictable name.
### Open Issues (Source-Level Fixes Required)
See [1.3.0] for the complete and up-to-date categorized list of all open issues.