Jul 20, 2026·6 min read·154 visits
A critical state desynchronization vulnerability in .NET's SslStream allows remote attackers to bypass mutual TLS (mTLS) policies. An attacker authenticates with a valid client certificate, requests renegotiation with an invalid or empty certificate, and relies on the server failing to clear its cached validation credentials to transmit unauthorized payloads over the unauthenticated connection.
A security feature bypass vulnerability exists in the .NET runtime's SslStream component. The flaw is caused by a state synchronization mismatch during Transport Layer Security (TLS) renegotiation or Post-Handshake Authentication (PHA). When renegotiation with a client fails due to an invalid or missing client certificate, the managed SslStream wrapper fails to invalidate its previously cached authentication properties. Consequently, downstream application logic continues to authorize requests under the context of the original valid identity, leading to incorrect authorization and authentication bypass.
CVE-2026-50528 describes a security feature bypass vulnerability located within the .NET runtime's implementation of SslStream (System.Net.Security namespace). This component serves as the core managed abstraction layer for establishing secure, transport-layer encrypted channels. The vulnerability manifests during dynamic transport state changes, specifically TLS renegotiation and Post-Handshake Authentication (PHA) routines, exposing systems utilizing mutual TLS (mTLS) to authentication bypass risks.
The vulnerability is classified under CWE-863 (Incorrect Authorization). In mutual TLS configurations, the server application queries the SslStream object to verify client certificates before granting access to protected endpoints. Because the underlying managed state machine fails to cleanly separate individual authentication epochs across renegotiations, the application exposes a critical security boundary bypass where transport state transitions fail to propagate down to authorization filters.
The root cause of CVE-2026-50528 lies in a synchronization lag between native platform security APIs and the managed .NET wrapper layers. The .NET SslStream relies on a Platform Abstraction Layer (PAL) to interface with native libraries: Schannel on Windows platforms, and OpenSSL on Linux and macOS environments. When a connection is initialized, the native layer negotiates the cryptographic parameters, and the managed SslState object caches variables such as RemoteCertificate and IsMutuallyAuthenticated.
Under normal circumstances, these variables are evaluated once. However, under TLS 1.2 renegotiation or TLS 1.3 Post-Handshake Authentication, a peer is allowed to update its credentials dynamically mid-session. When a renegotiation is triggered, the native library performs a secondary handshake. If the client fails to complete this handshake with a valid certificate, the native library flags the transport session as unauthenticated or failed.
Despite the failure at the native protocol level, the managed SslState machine fails to invalidate its internal cache. The RemoteCertificate property remains populated with the certificate provided during the initial handshake, and IsMutuallyAuthenticated remains set to true. The system fails open (CWE-636) because downstream application code evaluates the stale, cached metadata instead of querying the current, invalidated native state.
The bug resides in how SslState.cs handles transitions when the cryptographic context is renegotiated. Prior to the patch, the CompleteHandshake method inside the internal SslState class presumed that any reached state block represented a successful handshake transition, overwriting values only when new ones were successfully negotiated, rather than explicitly clearing out stale states on handshake failure.
// Vulnerable Code Path
internal void CompleteHandshake()
{
// Missing validation of state transition during renegotiation
_localCertificate = _context.LocalCertificate;
// Stale remote certificate and auth statuses are kept
_remoteCertificate = _context.RemoteCertificate;
_isMutuallyAuthenticated = _context.IsMutuallyAuthenticated;
}The official fix, introduced across commits 9db47f0b4f02e0804f4b16958f1c70068b95e7c3 and 013aa09028a670051e21cb7bd6d96cb1d761ac5d, resolves the issue by tracking the validation state explicitly. If the handshake context indicates an unresolved or failed state, the validation fields are explicitly cleared, and an exception is raised before the application can read incoming payloads.
// Patched Code Path
internal void CompleteHandshake()
{
if (!_context.IsValidHandshakeState)
{
// Explicitly clear cached properties to prevent identity inheritance
_remoteCertificate = null;
_isMutuallyAuthenticated = false;
throw new AuthenticationException("Handshake state is invalid.");
}
_localCertificate = _context.LocalCertificate;
_remoteCertificate = _context.RemoteCertificate;
_isMutuallyAuthenticated = _context.IsMutuallyAuthenticated;
}Additionally, the patch enforces the re-evaluation of custom RemoteCertificateValidationCallback results on session resumption, ensuring that validation logic is not bypassed when resuming previously established security sessions.
To execute this attack, a remote adversary must target an application utilizing .NET's SslStream configured with mutual authentication (mTLS) where the ClientCertificateRequired option is active. The attack operates entirely over the network and does not require pre-existing system privileges.
First, the attacker establishes a valid connection using a legitimate client certificate. This allows the connection to pass initial filters, prompting the .NET application to load and cache the authenticated identity context. Second, the attacker issues a TLS renegotiation message (e.g., via a ClientHello or HelloRequest frame) on the existing connection.
During renegotiation, the attacker purposely provides a spoofed, invalid, or empty certificate. While the native socket records a validation failure, the managed .NET layer continues to keep the connection socket open. Finally, the attacker sends the malicious endpoint payload. When the target server application inspects SslStream.RemoteCertificate to authorize the incoming payload, the stale, valid certificate from the initial handshake is returned, allowing the request to proceed.
The impact of CVE-2026-50528 is rated high, with a CVSS v3.1 base score of 8.2. The primary consequence is incorrect authorization, which leads directly to an authentication bypass. Because the vulnerability allows an unauthenticated attacker to assume the security context of a previously validated identity, it can lead to complete compromise of API endpoints, gRPC services, and microservice frameworks running on affected .NET runtimes.
The CVSS vector is breakdown as follows: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N. The integrity impact is high because unauthorized actions can be executed within the security context of a valid user. Confidentiality impact is low, allowing partial read access. There is no direct availability impact, as the exploit does not trigger system crashes or resource exhaustion.
The primary remediation for this vulnerability is upgrading the .NET runtime to patched versions. Microsoft has released security updates addressing the bug across all maintained release channels. Operators must update runtime environments to .NET 8.0.29, .NET 9.0.18, or .NET 10.0.6 as appropriate.
For systems where runtime patches cannot be deployed immediately, administrators should implement defensive configuration changes. The most effective workaround is disabling client-initiated renegotiation at the protocol level. For example, enforcing TLS 1.3 exclusively mitigates legacy TLS 1.2 renegotiation attack paths, as TLS 1.3 replaces renegotiation with a distinct Post-Handshake Authentication mechanism that is managed more securely.
// Secure configuration mitigating renegotiation vectors
var sslOptions = new SslServerAuthenticationOptions
{
EnabledSslProtocols = SslProtocols.Tls13,
ClientCertificateRequired = true,
RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) =>
{
// Implement custom validation logic
return sslPolicyErrors == SslPolicyErrors.None;
}
};Security operation centers can detect potential exploit attempts by monitoring network traffic for anomalous TLS handshake patterns. High rates of client-initiated renegotiation messages over a single TCP connection should be flagged as potential indicators of compromise.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
.NET 8.0 Microsoft | 8.0.0 to < 8.0.29 | 8.0.29 |
.NET 9.0 Microsoft | 9.0.0 to < 9.0.18 | 9.0.18 |
.NET 10.0 Microsoft | 10.0.0 to < 10.0.6 | 10.0.6 |
Visual Studio 2022 version 17.12 Microsoft | 17.12.0 to < 17.12.22 | 17.12.22 |
Visual Studio 2022 version 17.14 Microsoft | 17.14.0 to < 17.14.36 | 17.14.36 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-863 (Primary), CWE-302, CWE-636 |
| Attack Vector | Network |
| CVSS v3.1 Score | 8.2 |
| EPSS Score | 0.00436 |
| EPSS Percentile | 35.41% |
| Impact | Security Feature Bypass |
| Exploit Status | none |
| KEV Status | Not Listed |
The software performs authorization checks but fails to correctly restrict actions, allowing a peer that fails authentication to inherit the authorized context of a different state.
A path traversal vulnerability (CWE-22) in Contao CMS allows unauthenticated remote attackers to bypass directory boundary restrictions in ImagesController and access files within the project directory.
Contao Open Source CMS versions 4.0.0 through 5.3.49 and 5.4.0-RC1 through 5.7.11 contain a Cross-Site Request Forgery (CSRF) vulnerability in backend parameter handling. The `RequestTokenListener` component validates anti-CSRF tokens solely for HTTP POST requests, while GET-based declarative guards run only when an `act` parameter is present in the query string. Consequently, custom backend actions dispatched via alternative parameters such as `key=` can execute without CSRF token verification when triggered by an authenticated user.
Contao CMS versions 4.1.0 through 5.3.49 and 5.4.0-RC1 through 5.7.11 fail to validate form submission tokens and enforce rate limiting when processing activation email resend requests via HTTP POST, enabling resource exhaustion and account state enumeration.
An information disclosure vulnerability in Contao CMS allows unauthenticated site visitors to view protected page titles, URLs, and text excerpts through search queries when protected page indexing is disabled after previously being enabled.
In Vikunja prior to version 2.6.0, relation creation via the CalDAV endpoint fails to invoke the TaskRelation.CanCreate authorization check. This missing access control allows an authenticated user to establish unauthorized relationships and perform write operations against any task, provided its unique identifier (UID) is known.
A cross-project information disclosure vulnerability in Vikunja allows authenticated users with read access to one project to view private task details from unauthorized projects via subtask expansion parameters.