Skip to content

Bounds check the DCEP OPEN label and protocol lengths - #1779

Merged
sipsorcery merged 1 commit into
masterfrom
fix/dcep-open-bounds-check
Aug 14, 2026
Merged

sipsorcery merged 1 commit into
masterfrom
fix/dcep-open-bounds-check

Conversation

@sipsorcery

Copy link
Copy Markdown
Member

Fixes the DCEP OPEN parser bounds check reported in #1778.

Changes

DataChannelOpenMessage.Parse now checks the label and protocol lengths against the space actually left in the buffer before using them:

int variableLength = labelLength + protocolLength;
if (variableLength > buffer.Length - posn - DCEP_OPEN_FIXED_PARAMETERS_LENGTH)
{
    throw new ApplicationException("The buffer was not big enough for the label and protocol lengths in the DCEP open message.");
}

The lengths are summed as an int so a pair that only overflows when combined is caught, and neither value can wrap.

Malformed messages now surface as ApplicationException, consistent with the rest of the parser, so they are handled by the recoverable-error path in RTCSctpTransport.DoReceive rather than the defence-in-depth catch below it.

Also corrected two places where posn was ignored:

  • the minimum length check compared buffer.Length against the fixed parameters length rather than the bytes remaining from posn
  • the label and protocol were read from a hardcoded offset of 12 instead of posn + 12

Every current caller passes posn = 0, so this was latent rather than live, but it did not match the signature or WriteTo, which does honour posn.

Tests

New DataChannelOpenMessageUnitTest covering:

All 7 pass, along with the 127 existing SCTP, WebRTC and data channel unit tests on net8.0.

Note on classification

#1778 arrived as a private security report. It is a genuine parser defect but not a vulnerability: reaching this code requires completing the DTLS handshake as the peer authenticated against the signalled fingerprint, and the only consequence is that the sender's own data channel does not open. Encoding.UTF8.GetString validates its arguments and throws before reading, so nothing is read past the buffer. The reasoning is recorded in the issue.

🤖 Generated with Claude Code

DataChannelOpenMessage.Parse read the label and protocol lengths from the
buffer and passed them to Encoding.UTF8.GetString without checking they fit
within it. A DCEP OPEN message declaring a label longer than the data it
carried threw an ArgumentException rather than the ApplicationException used
to signal a malformed message, and the data channel silently failed to open.

The label and protocol were also read from a fixed offset of 12 rather than
relative to posn, as was the minimum length check. Every caller passes a posn
of 0 so this was latent, but the function was wrong as written.

Resolves #1778.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
[Trait("Category", "unit")]
public class DataChannelOpenMessageUnitTest
{
private Microsoft.Extensions.Logging.ILogger logger = null;
@sipsorcery
sipsorcery merged commit 23ce702 into master Aug 14, 2026
8 checks passed
@sipsorcery
sipsorcery deleted the fix/dcep-open-bounds-check branch August 14, 2026 13:18
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