High severity8.7GHSA Advisory· Published May 14, 2026· Updated May 15, 2026
CVE-2026-44700
CVE-2026-44700
Description
Elixir WebRTC is an Elixir implementation of the W3C WebRTC API. Prior to 0.15.1 and 0.16.1, missing DTLS peer certificate fingerprint validation in the DTLS client (active) role removes one side of WebRTC's mutual authentication. The bug is not independently exploitable for media interception in standard deployments, but enables a full man-in-the-middle attack when chained with insecure signalling or a peer with similar validation gaps. This vulnerability is fixed in 0.15.1 and 0.16.1.
Affected products
1- Range: = 0.16.0
Patches
1658c63221a86[FCE-3227] Fix DTLS fingerprint not being validated in certain cases (#250)
2 files changed · +65 −31
lib/ex_webrtc/dtls_transport.ex+29 −26 modified@@ -481,34 +481,10 @@ defmodule ExWebRTC.DTLSTransport do {:ok, state} {:handshake_finished, lkm, rkm, profile, packets} -> - Logger.debug("DTLS handshake finished") - state = update_remote_cert_info(state) - :ok = do_send(state, packets) - - peer_fingerprint = - state.dtls - |> ExDTLS.get_peer_cert() - |> ExDTLS.get_cert_fingerprint() - |> Utils.hex_dump() - - if peer_fingerprint == state.peer_fingerprint do - :ok = setup_srtp(state, lkm, rkm, profile) - state = update_dtls_state(state, :connected) - state = flush_buffered_remote_rtp_packets(state) - {:ok, state} - else - Logger.debug("Non-matching peer cert fingerprint.") - state = update_dtls_state(state, :failed) - {:ok, state} - end + handle_handshake_finished(state, lkm, rkm, profile, packets) {:handshake_finished, lkm, rkm, profile} -> - Logger.debug("DTLS handshake finished") - :ok = setup_srtp(state, lkm, rkm, profile) - state = update_dtls_state(state, :connected) - state = flush_buffered_remote_rtp_packets(state) - state = update_remote_cert_info(state) - {:ok, state} + handle_handshake_finished(state, lkm, rkm, profile) :handshake_want_read -> {:ok, state} @@ -554,6 +530,33 @@ defmodule ExWebRTC.DTLSTransport do {:ok, state} end + defp handle_handshake_finished(state, lkm, rkm, profile, packets \\ []) do + Logger.debug("DTLS handshake finished") + + if peer_fingerprint_matching?(state) do + :ok = setup_srtp(state, lkm, rkm, profile) + state = update_dtls_state(state, :connected) + state = flush_buffered_remote_rtp_packets(state) + state = update_remote_cert_info(state) + :ok = do_send(state, packets) + {:ok, state} + else + Logger.debug("Non-matching peer cert fingerprint.") + state = update_dtls_state(state, :failed) + {:ok, state} + end + end + + defp peer_fingerprint_matching?(%{peer_fingerprint: expected_fp} = state) do + actual_fp = + state.dtls + |> ExDTLS.get_peer_cert() + |> ExDTLS.get_cert_fingerprint() + |> Utils.hex_dump() + + expected_fp == actual_fp + end + defp setup_srtp(state, local_keying_material, remote_keying_material, profile) do {:ok, crypto_profile} = ExLibSRTP.Policy.crypto_profile_from_dtls_srtp_protection_profile(profile)
test/ex_webrtc/dtls_transport_test.exs+36 −5 modified@@ -163,8 +163,15 @@ defmodule ExWebRTC.DTLSTransportTest do ice_transport: ice_transport, ice_pid: ice_pid } do - :ok = DTLSTransport.start_dtls(dtls, :active, @fingerprint) remote_dtls = ExDTLS.init(mode: :server, dtls_srtp: true) + + remote_fingerprint = + remote_dtls + |> ExDTLS.get_cert() + |> ExDTLS.get_cert_fingerprint() + |> Utils.hex_dump() + + :ok = DTLSTransport.start_dtls(dtls, :active, remote_fingerprint) :ok = DTLSTransport.set_ice_connected(dtls) # perform DTLS-SRTP handshake @@ -240,9 +247,15 @@ defmodule ExWebRTC.DTLSTransportTest do ice_transport: ice_transport, ice_pid: ice_pid } do - :ok = DTLSTransport.start_dtls(dtls, :active, @fingerprint) remote_dtls = ExDTLS.init(mode: :server, dtls_srtp: true) + remote_fingerprint = + remote_dtls + |> ExDTLS.get_cert() + |> ExDTLS.get_cert_fingerprint() + |> Utils.hex_dump() + + :ok = DTLSTransport.start_dtls(dtls, :active, remote_fingerprint) :ok = DTLSTransport.set_ice_connected(dtls) assert {:ok, _, _, _} = check_handshake(dtls, ice_transport, ice_pid, remote_dtls) @@ -296,9 +309,15 @@ defmodule ExWebRTC.DTLSTransportTest do ice_transport: ice_transport, ice_pid: ice_pid } do - :ok = DTLSTransport.start_dtls(dtls, :active, @fingerprint) remote_dtls = ExDTLS.init(mode: :server, dtls_srtp: true) + remote_fingerprint = + remote_dtls + |> ExDTLS.get_cert() + |> ExDTLS.get_cert_fingerprint() + |> Utils.hex_dump() + + :ok = DTLSTransport.start_dtls(dtls, :active, remote_fingerprint) :ok = DTLSTransport.set_ice_connected(dtls) assert {:ok, _, _, _} = check_handshake(dtls, ice_transport, ice_pid, remote_dtls) @@ -328,9 +347,15 @@ defmodule ExWebRTC.DTLSTransportTest do ice_transport: ice_transport, ice_pid: ice_pid } do - :ok = DTLSTransport.start_dtls(dtls, :active, @fingerprint) remote_dtls = ExDTLS.init(mode: :server, dtls_srtp: true) + remote_fingerprint = + remote_dtls + |> ExDTLS.get_cert() + |> ExDTLS.get_cert_fingerprint() + |> Utils.hex_dump() + + :ok = DTLSTransport.start_dtls(dtls, :active, remote_fingerprint) :ok = DTLSTransport.set_ice_connected(dtls) # perform DTLS-SRTP handshake @@ -380,9 +405,15 @@ defmodule ExWebRTC.DTLSTransportTest do ice_transport: ice_transport, ice_pid: ice_pid } do - :ok = DTLSTransport.start_dtls(dtls, :active, @fingerprint) remote_dtls = ExDTLS.init(mode: :server, dtls_srtp: true) + remote_fingerprint = + remote_dtls + |> ExDTLS.get_cert() + |> ExDTLS.get_cert_fingerprint() + |> Utils.hex_dump() + + :ok = DTLSTransport.start_dtls(dtls, :active, remote_fingerprint) :ok = DTLSTransport.set_ice_connected(dtls) # perform DTLS-SRTP handshake
Vulnerability mechanics
AI mechanics synthesis has not run for this CVE yet.
References
8- github.com/advisories/GHSA-qwfw-ggxw-577cghsaADVISORY
- github.com/elixir-webrtc/ex_webrtc/commit/658c63221a869fb12bb9989599c3688751b0531bghsa
- github.com/elixir-webrtc/ex_webrtc/issues/249nvd
- github.com/elixir-webrtc/ex_webrtc/pull/250nvd
- github.com/elixir-webrtc/ex_webrtc/releases/tag/v0.15.1nvd
- github.com/elixir-webrtc/ex_webrtc/releases/tag/v0.16.1nvd
- github.com/elixir-webrtc/ex_webrtc/security/advisories/GHSA-qwfw-ggxw-577cnvd
- nvd.nist.gov/vuln/detail/CVE-2026-44700ghsa
News mentions
0No linked articles in our index yet.