Skip to content

Latent: MuxedRtpSession::recv_muxed ignores packet source and fails-closed on malformed input #117

Description

@ryanmurf

Summary

MuxedRtpSession::recv_muxed does not apply the RTP ingress hardening that RtpSession::recv_frame does. Currently latentrecv_muxed has no callers in-tree (MuxedRtpSession is only defined, never wired to a live receive loop) — so severity is LOW today, but it should be fixed before rtcp-mux/BUNDLE media is enabled.

Location

crates/asterisk-sip/src/rtp/mod.rs, recv_muxed (~line 1147):

let (len, _src) = self.rtp.socket.recv_from(&mut buf).await?;  // source discarded
buf.truncate(len);
if self.mux_enabled && is_rtcp_packet(&buf) {
    Ok(MuxedPacket::Rtcp(Bytes::from(buf)))
} else {
    let (header, payload) = parse_rtp_header(&buf)?;           // error tears down the loop
    Ok(MuxedPacket::Rtp(header, Bytes::copy_from_slice(payload)))
}

Gaps vs. the hardened recv_frame

  1. No source-address validation. _src is ignored, so once the port is known an attacker can inject RTP/RTCP from any address (media injection/hijack). recv_frame rejects packets whose source != negotiated/latched remote (discarded_wrong_source).
  2. Fails closed on one bad packet. A malformed datagram returns Err to the caller via ? instead of being counted and skipped; a single spoofed packet could tear down the media receive loop. recv_frame discards-and-continues.
  3. No payload-type / SSRC-stability checks either.

Recommendation

When wiring muxed sessions, mirror recv_frame: validate source, discard-and-loop on malformed/unexpected, and reuse the same discard counters. Not fixing now (contract change on an unused path; would affect WebRTC/BUNDLE media policy).

Axis

RTP/media ingress — source-address validation.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions