Skip to content

fix(push): enforce per-stream push authentication (S-8); remove webhook egress guard; triage remaining findings#29

Merged
ntt0601zcoder merged 1 commit into
mainfrom
fix/push-ingest-auth
Jun 15, 2026
Merged

fix(push): enforce per-stream push authentication (S-8); remove webhook egress guard; triage remaining findings#29
ntt0601zcoder merged 1 commit into
mainfrom
fix/push-ingest-auth

Conversation

@ntt0601zcoder

Copy link
Copy Markdown
Owner

What

Closes out the security triage: fixes the one remaining real gap (S-8) and removes a guard that blocked a legitimate use case; the rest of the open MEDIUM/LOW findings are risk-accepted with rationale in the audit doc.

S-8 — push ingest now authenticated (the fix)

Push ingest previously accepted any client that knew a registered stream code — the per-stream StreamKey was in the data model but never checked.

  • RTMP publishers supply the secret as ?key=<secret> on the publish URL; the query is stripped from the stream name, so routing is unaffected.
  • The RTMP server resolves a stream's configured StreamKey via a resolver (publisher in-memory table for live + auto-publish runtime streams, with a store+template fallback for configured streams — mirroring the media-auth PolicyResolver) and constant-time-compares it before claiming the registry slot. A mismatch is rejected before any slot/pipeline state changes.
  • An empty StreamKey opts the stream out (unauthenticated, backward-compatible).
  • Auto-publish enforces the matching template's StreamKey inside ResolveOrCreate before materialising the runtime stream, so an unauthorised push never starts a pipeline.

Operational note: after deploy, any stream with a configured stream_key will require encoders to push with ?key=…; streams without a key are unaffected.

Webhook egress guard removed

The internal/netguard dial guard on the webhook client (and the package) is removed: webhooks legitimately target private/local endpoints (sidecar collectors, internal services on loopback), the admin API that made it reachable is now authenticated, and delivery is blind POST — so the guard blocked a real use case for negligible benefit.

Triage (audit doc)

  • S-8 → fixed.
  • S-6 (webhook SSRF), S-7/S-9/S-10/S-11 (MEDIUM), S-12/S-14/S-15/S-16 (LOW) → risk-accepted, each with rationale.

Tests

TestPushKeyOK, TestPushSecretFromQuery, TestResolveOrCreate_StreamKeyEnforced. make check green (build + vet + lint 0 issues + test -race, 31 packages).

Residual (noted, not in scope)

Concurrent-runtime-stream cap + per-source-IP rate-limit (DoS hardening, orthogonal to the auth gap); SRT push has no server in the codebase so there is nothing to gate there.

…indings

Push ingest previously accepted any client that knew a registered stream
code — the per-stream StreamKey was defined in the data model but never
checked. Wire it:

- RTMP publishers supply the secret as ?key=<secret> on the publish URL;
  the query is stripped from the stream name so routing is unaffected.
- The RTMP server resolves a stream's configured StreamKey via a resolver
  (publisher in-memory table for live + auto-publish runtime streams, with
  a store+template fallback for configured streams) and constant-time-
  compares before claiming the registry slot. An empty key opts the stream
  out (backward-compatible).
- Auto-publish enforces the matching template's StreamKey before
  materialising the runtime stream, so an unauthorised push never starts a
  pipeline.

Also remove the webhook egress dial guard (and delete the now-unused guard
package): webhooks legitimately target private/local endpoints, the admin
API that made it reachable is authenticated, and delivery is blind POST —
so the guard blocked a real use case for negligible benefit.

Audit doc: S-8 marked fixed; the webhook-SSRF and the remaining MEDIUM/LOW
findings (secrets in logs/metrics/store, playlist-param nuisance, local
unix socket, proxy-trusted client IP, profiling endpoint) marked
accepted with rationale.

Tests: push key + secret-parse + auto-publish key enforcement.
make check green (build + vet + lint + test -race).
@ntt0601zcoder ntt0601zcoder merged commit 44a9f94 into main Jun 15, 2026
4 checks passed
@ntt0601zcoder ntt0601zcoder deleted the fix/push-ingest-auth branch June 16, 2026 02:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant