GopherTrunk's threat model centres on operators running the daemon
on a private network or a single host they own (LAN deployment,
home lab, an EC2 box for a small fleet of SDR receivers). The
binary is single-process, single-host, and stores everything it
decodes to local disk; the API is gated by bearer-token
authentication (see docs/hardening.md).
Optional TLS for the HTTP and gRPC servers is documented in the
same file.
Security fixes land on the default branch (main). The most
recent tagged release receives back-ported fixes; older tags are
not maintained.
| Version | Status |
|---|---|
main |
Supported |
| Latest tag | Supported |
| Older tags | Best-effort, no SLA |
Do not open a public issue for a suspected vulnerability.
Use GitHub's private security advisory workflow:
- Visit the repository's Security → Advisories tab.
- Click Report a vulnerability (or hit
https://github.com/mattcheramie/gophertrunk/security/advisories/new). - Provide a description, reproducer (or minimal IQ capture / API request that triggers the issue), and the affected version / commit SHA.
GitHub's advisory workflow keeps the report private until a fix ships. The maintainer aims for an initial response within 7 days and a fix or mitigation within 30 days for critical issues; less severe issues land on the regular development cadence.
If GitHub advisories aren't available to you (e.g. you're not on
GitHub), open a public issue marked security: contact requested
asking the maintainer to reach out by email — do not include
exploit details in the public issue.
In scope:
- Authentication / authorisation bypass on
/api/v1/{mutations,scanner,audio,...}mutation endpoints (token validation, trusted-network parsing). - Path traversal / arbitrary file write through
recordings.dirortalkgroup_fileconfig keys (the daemon reads / writes these on disk). - SQL injection through the SQLite call-log queries (the
internal/storagepackage uses parameterised statements; report any path that builds a query through string concatenation). - Denial-of-service that crashes the daemon or wedges it via a malformed input from one of the supported wire formats (RTL-SDR IQ, control-channel frames, API JSON, gRPC requests).
- Memory-safety bugs (overflow, out-of-bounds slice access) in any non-test Go code, even if Go's bounds-checking turns them into runtime panics.
Out of scope:
- AMBE+2 patent-encumbered decode (see
docs/vocoders.mdfor the licensing posture). - "The daemon does what its config tells it to" — operator misconfiguration isn't a vulnerability.
- Local-only deployments where the operator already has root (you can't escalate above the privilege you started with).
- Issues that only manifest with
auth.mode: disabledset — that's explicitly documented as the wide-open legacy mode, and operators who set it are opting out of the auth boundary.
- The HTTP and gRPC servers use Go's stdlib
crypto/tls. Cipher suite selection and TLS version negotiation follow Go's built-in policy (TLS 1.2 minimum, modern AEAD suites). Cert rotation requires a daemon restart. - The bearer-token auth uses constant-time comparison
(
crypto/subtle.ConstantTimeCompare) — token-comparison side channels are not in scope by construction.
| Severity | Initial response | Fix / mitigation |
|---|---|---|
| Critical (RCE, auth bypass, data loss) | ≤ 7 days | ≤ 30 days |
| High (DoS, partial info disclosure) | ≤ 14 days | ≤ 60 days |
| Medium / low | ≤ 30 days | Next release cycle |
Fixes are coordinated via the GitHub advisory; once a fix is
merged on main and (where applicable) back-ported to the latest
tag, the advisory is published and a CVE requested for issues at
the high or critical level.