Chrome · WebRTC
CVE-2026-14078
Logic Error in WebRTC
Overview
Low
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
TEST_Fpc/sdp_munging_detector_unittest.cc |
modified | |
ifpc/sdp_offer_answer.cc |
modified |
Files Changed
pc/sdp_munging_detector_unittest.ccpc/sdp_offer_answer.cc
Patch
From 1be66414df0bd836e958c9636f263b02c7d3a2a6 Mon Sep 17 00:00:00 2001 From: Philipp Hancke <[email protected]> Date: Mon, 18 May 2026 11:12:58 +0200 Subject: [PATCH] sdp: fix sdp munging detection edge case Bug: chromium:512953564 Change-Id: Ia56457b98b8a71b7c641764eef5b1b82498223d6 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/472600 Reviewed-by: Markus Handell <[email protected]> Reviewed-by: Harald Alvestrand <[email protected]> Commit-Queue: Philipp Hancke <[email protected]> Cr-Commit-Position: refs/heads/main@{#47737} --- diff --git a/pc/sdp_munging_detector_unittest.cc b/pc/sdp_munging_detector_unittest.cc index f266c10..813a6ad 100644 --- a/pc/sdp_munging_detector_unittest.cc +++ b/pc/sdp_munging_detector_unittest.cc @@ -1549,6 +1549,38 @@ ElementsAre(Pair(SdpMungingType::kDataChannelSctpInit, 1))); } +TEST_F(SdpMungingTest, SctpInitAndIceUfrag) { + auto pc = CreatePeerConnection("WebRTC-Sctp-Snap/Enabled/"); + EXPECT_TRUE(pc->CreateDataChannel("dc")); + auto offer = pc->CreateOffer(); + ASSERT_THAT(offer, Not(IsNull())); + + auto& transport_infos = offer->description()->transport_infos(); + ASSERT_EQ(transport_infos.size(), 1u); + transport_infos[0].description.ice_ufrag = + "amungediceufragthisshouldberejected"; // But is not right now. + + auto& contents = offer->description()->contents(); + ASSERT_THAT(contents, SizeIs(1)); + auto* media_description = contents[0].media_description(); + ASSERT_THAT(media_description, Not(IsNull())); + auto* sctp_description = media_description->as_sctp(); + ASSERT_THAT(sctp_description, Not(IsNull())); + EXPECT_TRUE(sctp_description->sctp_init()); + + std::vector<uint8_t> test_value = { + 0x01, 0x00, 0x00, 0x1e, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x50, + 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xde, 0xad, 0xbe, 0xef, + 0xc0, 0x00, 0x00, 0x04, 0x80, 0x08, 0x00, 0x06, 0x82, 0xc0}; + sctp_description->set_sctp_init(test_value); + + RTCError error; + EXPECT_FALSE(pc->SetLocalDescription(std::move(offer), &error)); + EXPECT_THAT( + metrics::Samples("WebRTC.PeerConnection.SdpMunging.Offer.Initial"), + ElementsAre(Pair(SdpMungingType::kDataChannelSctpInit, 1))); +} + TEST_F(SdpMungingTest, MaxMessageSize) { auto pc = CreatePeerConnection(); EXPECT_TRUE(pc->CreateDataChannel("dc")); diff --git a/pc/sdp_offer_answer.cc b/pc/sdp_offer_answer.cc index 2af7466..a2bb704 100644 --- a/pc/sdp_offer_answer.cc +++ b/pc/sdp_offer_answer.cc @@ -2740,22 +2740,26 @@ DetermineSdpMungingType(desc.get(), last_created_desc); if (!disable_sdp_munging_checks_) { - bool reject_error = false; - if (HasUfragSdpMunging(desc.get(), last_created_desc)) { + bool reject_with_error = + !IsSdpMungingAllowed(sdp_munging_type, pc_->trials()); + if (!reject_with_error && + HasUfragSdpMunging(desc.get(), last_created_desc)) { + // ice-ufrag munging may still trigger rejection for other reasons + // guarded by this variable. has_sdp_munged_ufrag_ = true; + if (pc_->trials().IsEnabled("WebRTC-NoSdpMangleUfrag")) { RTC_LOG(LS_ERROR) << "Rejecting SDP because of ufrag modification"; - reject_error = true; + reject_with_error = true; } - } else { - reject_error = !IsSdpMungingAllowed(sdp_munging_type, pc_->trials()); } - SdpMungingOutcome outcome = reject_error ? SdpMungingOutcome::kRejected - : SdpMungingOutcome::kAccepted; + SdpMungingOutcome outcome = reject_with_error + ? SdpMungingOutcome::kRejected + : SdpMungingOutcome::kAccepted; RTC_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.SdpMunging.Outcome", static_cast<int>(outcome), static_cast<int>(SdpMungingOutcome::kMaxValue)); - if (reject_error) { + if (reject_with_error) { observer->OnSetLocalDescriptionComplete( RTCError(RTCErrorType::INVALID_MODIFICATION, "SDP is modified in a non-acceptable way"));
Loading diff…
Regression Test / PoC
shipped with the fix
diff --git a/pc/sdp_munging_detector_unittest.cc b/pc/sdp_munging_detector_unittest.cc
index f266c10..813a6ad 100644
--- a/pc/sdp_munging_detector_unittest.cc
+++ b/pc/sdp_munging_detector_unittest.cc
@@ -1549,6 +1549,38 @@
ElementsAre(Pair(SdpMungingType::kDataChannelSctpInit, 1)));
}
+TEST_F(SdpMungingTest, SctpInitAndIceUfrag) {
+ auto pc = CreatePeerConnection("WebRTC-Sctp-Snap/Enabled/");
+ EXPECT_TRUE(pc->CreateDataChannel("dc"));
+ auto offer = pc->CreateOffer();
+ ASSERT_THAT(offer, Not(IsNull()));
+
+ auto& transport_infos = offer->description()->transport_infos();
+ ASSERT_EQ(transport_infos.size(), 1u);
+ transport_infos[0].description.ice_ufrag =
+ "amungediceufragthisshouldberejected"; // But is not right now.
+
+ auto& contents = offer->description()->contents();
+ ASSERT_THAT(contents, SizeIs(1));
+ auto* media_description = contents[0].media_description();
+ ASSERT_THAT(media_description, Not(IsNull()));
+ auto* sctp_description = media_description->as_sctp();
+ ASSERT_THAT(sctp_description, Not(IsNull()));
+ EXPECT_TRUE(sctp_description->sctp_init());
+
+ std::vector<uint8_t> test_value = {
+ 0x01, 0x00, 0x00, 0x1e, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x50,
+ 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xde, 0xad, 0xbe, 0xef,
+ 0xc0, 0x00, 0x00, 0x04, 0x80, 0x08, 0x00, 0x06, 0x82, 0xc0};
+ sctp_description->set_sctp_init(test_value);
+
+ RTCError error;
+ EXPECT_FALSE(pc->SetLocalDescription(std::move(offer), &error));
+ EXPECT_THAT(
+ metrics::Samples("WebRTC.PeerConnection.SdpMunging.Offer.Initial"),
+ ElementsAre(Pair(SdpMungingType::kDataChannelSctpInit, 1)));
+}
+
TEST_F(SdpMungingTest, MaxMessageSize) {
auto pc = CreatePeerConnection();
EXPECT_TRUE(pc->CreateDataChannel("dc"));
Loading diff…
Original Bug Report
The reporter's bug is still restricted on the tracker. Chrome de-restricts security bugs ~30–90 days after the fix ships; a later run will backfill it here.
References
On This Page