Skip to content

Pause/unpause cycling resets setup timer allowing connection-slot squatting DoS #209

Description

@cursor

Summary

An unauthenticated RTMP peer can hold server connection slots indefinitely by cycling pause/unpause commands, even when it never receives any outbound relay media.

Attacker

Any network client that can complete the RTMP handshake and AMF connect exchange against a librtmp2 server.

Controlled input

Repeated pause(true) / pause(false) NetStream commands on a playing session that has never received relayed media (media_bytes_sent == 0).

Attack path

  1. Connect, send connect, createStream, and play for any stream name (no publisher required).
  2. Before the 10-second setup-timeout reaper closes the idle viewer, send pause(true).
  3. The pause handler resets session_setup_started, granting another full grace window.
  4. Briefly send pause(false) so the next pause(true) is accepted (timer reset only fires on transitions into paused state).
  5. Repeat steps 2-4 every few seconds.

Because the player never receives relay data, the post-2f40c6d idle-viewer reaper never applies the slow-reader exemption, yet each pause transition keeps refreshing the timeout anchor.

Impact

Medium — denial of service. With max_connections configured, the attacker can exhaust all available slots and deny legitimate publishers/players. With unlimited connections, each squatter retains per-connection buffers and poll-loop work.

Location

src/session/conn.rs

Remediation

Only refresh session_setup_started on pause when the viewer has actually received outbound relay (media_bytes_sent > 0), preserving the grace window for legitimate paused viewers while blocking timer reset for squatters.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions