Skip to main content

Netty CVE-2026-56821

HIGH
Improper Check for Certificate Revocation (CWE-299)
2026-07-22 https://github.com/netty/netty GHSA-g7hg-vrcf-mvmr
7.4
CVSS 3.1 · Vendor: https://github.com/netty/netty
View

Attack ChainAIDerived

Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain

  1. Recon
    Obtain since-revoked certificate and old GOOD OCSP response
  2. Delivery
    Gain on-path position between client and server
  3. Exploit
    Present revoked certificate during TLS handshake
  4. Install
    Replay expired GOOD OCSP response
  5. C2
    Missing return fires VALID event despite staleness
  6. Execute
    Client trusts revoked certificate
  7. Impact
    Intercept and tamper with session

Vulnerability Assessment

Weakness
CWE
OWASP Top 10:2025
A07:2025 - Authentication Failures
ASVS 5.0
V12 - Secure Communication Certificate revocation checking
Exploitation Conditions

Exploitation requires that the target application actually uses OcspServerCertificateValidator (the netty-handler-ssl-ocsp module wired into the pipeline) with the default configuration where nonce validation is disabled - making stale-response freshness the only replay defense. The attacker must (1) hold a certificate that is currently revoked but was previously valid, (2) possess a genuine, correctly-signed GOOD OCSP response issued for that certificate before revocation, and (3) occupy an on-path/man-in-the-middle position to present the revoked cert and serve the replayed response. Limiting factors: the High attack complexity in the CVSS vector reflects these stacked prerequisites; the attack fails if nonce validation is enabled, if the application does not use this optional validator, or if the attacker cannot obtain a previously-valid signed GOOD response. Separately, a null nextUpdate triggers a NullPointerException rather than a bypass, which is a crash condition, not a silent accept.

Impact

The provided CVSS 3.1 vector (AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N, base 7.4 High) reflects a network-reachable, unauthenticated weakness whose High attack complexity is well justified: exploitation is not opportunistic - the attacker must occupy an on-path/MITM position AND possess both a certificate that has since been revoked and a previously-issued GOOD OCSP response for it. That combination limits this to targeted scenarios rather than mass exploitation, which is consistent with the absence of any KEV listing. No EPSS score was supplied, so probabilistic exploitation likelihood cannot be quantified here; treat the lack of an EPSS figure as missing data, not as low risk. A working PoC exists, so the mechanism is proven, but PoC availability is distinct from active exploitation and there is no evidence of the latter. Net: a genuine security-control failure (revocation is silently bypassed), but real-world priority is bounded by the narrow preconditions and by how rarely the affected optional module is deployed. The C:H/I:H rating is defensible because a successful bypass undermines TLS peer authentication, exposing the session to interception and tampering.

Exploit ScenarioDerived

An attacker who previously obtained a server certificate that has since been revoked (for example, a compromised key that was reported and revoked) positions themselves on-path between a Netty-based client and the server. They present the revoked certificate and, when the client's OcspServerCertificateValidator fetches OCSP status, replay an old GOOD response captured before revocation; despite being expired, it is still reported as VALID and the client proceeds to trust the connection. A public PoC unit test demonstrating a 7-day-stale GOOD response being accepted is included in the advisory.

This Week Schedule remediation this week. Why: HIGH severity (CVSS 7.0-8.9).
Patch available 0.1% exploitation probability (EPSS)

Get an e-mail when this CVE is exploited, patched or re-scored. Free account.

Alert me

AnalysisAIv1 – Jul 22, 2026

Certificate revocation bypass in the Netty netty-handler-ssl-ocsp module (versions before 4.1.136.Final, and 4.2.0.Final through 4.2.15.Final) lets an on-path attacker replay a stale, expired-but-GOOD OCSP response to make OcspServerCertificateValidator accept a certificate that has since been revoked. A missing return statement after the freshness check causes execution to fall through and still fire a VALID OcspValidationEvent even after flagging the response as out-of-date. Publicly available exploit code exists (a PoC unit test is embedded in the GHSA advisory); the issue is not listed in CISA KEV and no EPSS score was provided.

RemediationAI

Vendor-released patch: upgrade to 4.1.136.Final (for 4.1.x deployments) or 4.2.16.Final (for 4.2.x deployments), per the release notes at https://github.com/netty/netty/releases/tag/netty-4.1.136.Final and https://github.com/netty/netty/releases/tag/netty-4.2.16.Final and the advisory at https://github.com/netty/netty/security/advisories/GHSA-g7hg-vrcf-mvmr. If you cannot upgrade immediately, enable OCSP nonce validation where your deployment supports it so that replayed responses are rejected on nonce mismatch rather than relying solely on freshness (trade-off: requires OCSP responders that echo nonces, and not all responders do). As a stronger compensating control, do not depend on OcspServerCertificateValidator as the sole revocation mechanism - pair it with short-lived certificates or an independent CRL/OCSP check outside the vulnerable code path - and shorten certificate lifetimes to reduce the window in which a revoked-but-cached GOOD response remains replayable. Upgrading is strongly preferred, as the workarounds only narrow rather than close the gap.

Affected Packages

maven io.netty:netty-handler-ssl-ocsp fix: 4.1.136.Final, 4.2.16.Final

Source: OSV (Open Source Vulnerabilities)

Affects your stack

Affects 1 package in maven

Checking this CVE against your own stacks and servers is part of the Basic plan and up.

Technical ContextAI · show details

The flaw lives in io.netty.handler.ssl.ocsp.OcspServerCertificateValidator#userEventTriggered, part of Netty's optional OCSP (Online Certificate Status Protocol, RFC 6960) stapling/validation support built on Bouncy Castle. Per RFC 6960 section 3.2, a client must confirm both that thisUpdate is sufficiently recent and that nextUpdate is greater than the current time before trusting a status. The code performs this check - if the current time is not within the thisUpdate/nextUpdate window it raises IllegalStateException('OCSP Response is out-of-date') via fireExceptionCaught - but omits a return, so the method continues and still emits a VALID event. Because nonce validation is optional and disabled by default, temporal freshness is the only defense against replay, and it is not enforced. This maps to CWE-299 (Improper Check for Certificate Revocation). A secondary defect exists: getNextUpdate() may return null, causing current.before(null) to throw NullPointerException, a potential crash/DoS path.

Know when Java gets its next vulnerability

  • Watch products and get an email when something new is published
  • Check this CVE against your own stack and servers
  • Exploit and PoC references, threat intelligence from 22 sources

No credit card · 7-day full trial

Severity by source

Vendor (https://github.com/netty/netty) PRIMARY 7.4 HIGH
AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N
vuln.today AI 7.4 HIGH

Network-reachable and unauthenticated (AV:N/PR:N) but AC:H because the attacker needs on-path position plus a revoked cert and a pre-captured signed GOOD response; bypassing TLS auth yields C:H/I:H, A:N (NPE DoS scored separately).

3.1 AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N
4.0 AV:N/AC:H/AT:N/PR:N/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N
SUSE HIGH
Red Hat 5.7 MEDIUM

Primary rating from Vendor (https://github.com/netty/netty).

CVSS VectorVendor: https://github.com/netty/netty

Attack Vector
Network
Attack Complexity
High
Privileges Required
None
User Interaction
None
Scope
Unchanged
Confidentiality
High
Integrity
High
Availability
None

DescriptionCVE.org

Summary

OcspServerCertificateValidator flags an out-of-date OCSP response but does not stop processing it, so an expired GOOD response is still reported as VALID, letting an on-path attacker replay a stale GOOD response to bypass revocation of a since-revoked certificate.

Details

In io.netty.handler.ssl.ocsp.OcspServerCertificateValidator#userEventTriggered the freshness check has no return, so execution falls through and a VALID OcspValidationEvent is still fired:

java
                        if (!(current.after(response.getThisUpdate()) &&
                                current.before(response.getNextUpdate()))) {
                            ctx.fireExceptionCaught(new IllegalStateException("OCSP Response is out-of-date"));
                        }

Nonce validation is optional and off by default, so freshness is the only replay defense - and it is not enforced. Additionally getNextUpdate() may be null, making current.before(null) throw NullPointerException.

https://datatracker.ietf.org/doc/html/rfc6960#section-3.2

   5. The time at which the status being indicated is known to be
      correct (thisUpdate) is sufficiently recent;

   6. When available, the time at or before which newer information will
      be available about the status of the certificate (nextUpdate) is
      greater than the current time.

PoC

Add the test below to io.netty.handler.ssl.ocsp.OcspServerCertificateValidatorTest

java
    @Test
    void staleOcspResponseIsRejected() throws Exception {
        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.id_ad_ocsp, 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);

        Date past = new Date(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(7));
        CertificateID certId = new CertificateID(
                new JcaDigestCalculatorProviderBuilder().build().get(CertificateID.HASH_SHA1),
                new JcaX509CertificateHolder(caRoot.getCertificate()),
                targetCert.getCertificate().getSerialNumber());
        BasicOCSPRespBuilder respBuilder = new BasicOCSPRespBuilder(
                new RespID(new JcaX509CertificateHolder(caRoot.getCertificate()).getSubject()));
        respBuilder.addResponse(certId, CertificateStatus.GOOD, past, past);
        BasicOCSPResp expiredBasicResp = respBuilder.build(
                new JcaContentSignerBuilder("SHA256withRSA").build(caRoot.getKeyPair().getPrivate()),
                new X509CertificateHolder[0],
                past);
        final byte[] responseEncoded = new OCSPRespBuilder()
                .build(OCSPRespBuilder.SUCCESSFUL, expiredBasicResp).getEncoded();

        IoTransport defaultTransport = createDefaultTransport();
        IoTransport mockTransport = IoTransport.create(defaultTransport.eventLoop(), () -> {
                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().execute(() -> {
                            ctx.pipeline().fireChannelActive();
                            DefaultFullHttpResponse httpResponse = new DefaultFullHttpResponse(
                                    HttpVersion.HTTP_1_1, HttpResponseStatus.OK,
                                    Unpooled.wrappedBuffer(responseEncoded));
                            httpResponse.headers().set(HttpHeaderNames.CONTENT_TYPE, "application/ocsp-response");
                            httpResponse.headers().set(HttpHeaderNames.CONTENT_LENGTH,
                                    httpResponse.content().readableBytes());
                            ctx.pipeline().fireChannelRead(httpResponse);
                        });
                    }
                });
                return channel;
            }, defaultTransport.datagramChannel());

            SslContext serverSslCtx = SslContextBuilder
                    .forServer(targetCert.getKeyPair().getPrivate(),
                            targetCert.getCertificate(), caRoot.getCertificate())
                    .build();
            Channel serverChannel = new ServerBootstrap()
                    .group(defaultTransport.eventLoop())
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) {
                            ch.pipeline().addLast(serverSslCtx.newHandler(ch.alloc()));
                        }
                    })
                    .bind(0).sync().channel();

            int serverPort = ((InetSocketAddress) serverChannel.localAddress()).getPort();

            AtomicBoolean validEventFired = new AtomicBoolean();
            AtomicReference<Throwable> caughtException = new AtomicReference<>();
            CountDownLatch latch = new CountDownLatch(1);

            DnsNameResolver resolver = OcspServerCertificateValidator.createDefaultResolver(mockTransport);
            SslContext clientSslCtx = SslContextBuilder.forClient()
                    .trustManager(InsecureTrustManagerFactory.INSTANCE)
                    .build();
            new Bootstrap()
                    .group(defaultTransport.eventLoop())
                    .channel(NioSocketChannel.class)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) {
                            ch.pipeline().addLast(clientSslCtx.newHandler(ch.alloc(), "127.0.0.1", serverPort));
                            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 OcspValidationEvent &&
                                            ((OcspValidationEvent) evt).response().status() ==
                                                    OcspResponse.Status.VALID) {
                                        validEventFired.set(true);
                                    }
                                    ctx.fireUserEventTriggered(evt);
                                }

                                @Override
                                public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
                                    caughtException.compareAndSet(null, cause);
                                    ctx.channel().close();
                                    latch.countDown();
                                }
                            });
                        }
                    })
                    .connect("127.0.0.1", serverPort).sync();

            assertTrue(latch.await(5, TimeUnit.SECONDS));
            assertFalse(validEventFired.get(),
                    "OcspValidationEvent(VALID) must not be emitted for a stale OCSP response");
            assertNotNull(caughtException.get());
            assertInstanceOf(IllegalStateException.class, caughtException.get());

            serverChannel.close().sync();
            resolver.close();
    }

Impact

Certificate revocation bypass via replay of an expired OCSP response. Any application using OcspServerCertificateValidator is affected; a revoked certificate can be accepted.

Blast Radius

ecosystem impact
† from your stack dependencies † transitive graph · vuln.today resolves 4-path depth
  • 74 maven packages depend on io.netty:netty-handler-ssl-ocsp (2 direct, 72 indirect)

Ecosystem-wide dependent count for version 4.2.0.Final.

Executive ViewAI

Why It Matters

Netty's OCSP certificate validation module contains a logic error allowing on-path attackers to replay expired OCSP responses, bypassing certificate revocation checks. Organizations using Netty with OCSP validation could inadvertently accept revoked certificates, creating exposure to man-in-the-middle attacks and compromising TLS authentication integrity.

Business Impact: High
Compensating Controls

Disable OCSP validation in netty-handler-ssl-ocsp if operationally feasible and acceptable for your risk posture; implement certificate pinning for critical endpoints; enforce network segmentation restricting OCSP responder communication; establish out-of-band certificate revocation status verification processes where applicable.

Threat Intelligence Overview

EPSS Score
0.1%
Top 96% exploitable
Prevalence
Low
optional Netty OCSP artifact, rarely wired into TLS pipelines
Threat Intel
1
1 source
Exploit
POC
Public exploit code exists
Social Media
1
Sightings
Data Quality
7 sources
Confidence: High
NVD CVE.org EPSS Vulnrichment GHSA Vendor CIRCL GitHub VulDB

How this decision was reached

The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.

SignalValue
Severity HIGH
CISA KEV No
Public POC Yes
EPSS 0.1%
Patch available Yes
Active threat No
Deciding rule
HIGH severity (CVSS 7.0-8.9)
What every action level means
Emergency Immediate action required. Criteria: CRITICAL + in CISA KEV (actively exploited) without patch, OR CRITICAL + EPSS > 30% without patch, OR CRITICAL + active threat signals without patch.
Act Now Prioritize within 24-48h. Criteria: in KEV with patch available, OR CRITICAL + public POC, OR HIGH + EPSS > 10%, OR CRITICAL + active threat, OR any CRITICAL severity.
This Week Schedule remediation this week. Criteria: HIGH severity (CVSS 7.0-8.9). Patch within normal change window.
This Month Plan within 30 days. Criteria: MEDIUM severity (CVSS 4.0-6.9), lower exploitation probability. Include in regular patch cycle.
Monitor Track and reassess. Criteria: LOW severity (CVSS 0.1-3.9), minimal exploitation risk. No immediate action needed.

SSVC AssessmentENISA

SSVC Decision
Scheduled
Exploitation
Poc
System Exposure· derived
Open
Automatable
No
Human Impact
High
Technical Impact
Partial

Priority Score

57
Low Medium High Critical
KEV: 0
EPSS: 0
CVSS: +37
PoC: +20
Weaponized: 0
Threat intel: 0
Gov advisory: 0

Attack Technique

Authentication bypass attacks exploit flaws in the verification mechanisms that control access to systems and applications.

Affected Products (CPE)CVE.org

pkg:maven/io.netty:netty-handler-ssl-ocsp
pkg:maven/io.netty:netty-handler-ssl-ocsp

More in Java

View all
CVE-2012-4681 CRITICAL POC
9.8 Aug 28

Oracle Java SE 7 Update 6 and earlier contains multiple sandbox bypass vulnerabilities via the ClassFinder and forName m

CVE-2015-7450 CRITICAL POC
9.8 Jan 02

Remote code execution in IBM Sterling B2B Integrator, Sterling Integrator, and Tivoli Common Reporting allows unauthenti

CVE-2013-2465 CRITICAL POC
9.8 Jun 18

Java Runtime Environment sandbox bypass via incorrect image channel verification in 2D component allows remote unauthent

CVE-2011-3544 CRITICAL POC
9.8 Oct 19

Oracle Java SE JDK/JRE 7 and 6 Update 27 and earlier allows remote code execution with complete system compromise throug

CVE-2010-1871 HIGH POC
8.8 Aug 05

JBoss Seam 2 in Red Hat JBoss EAP 4.3.0 fails to sanitize JBoss Expression Language inputs, allowing remote attackers to

CVE-2012-1723 CRITICAL POC
9.8 Jun 16

Unspecified vulnerability in the Java Runtime Environment (JRE) component in Oracle Java SE 7 update 4 and earlier, 6 up

CVE-2013-0422 CRITICAL POC
9.8 Jan 10

Multiple vulnerabilities in Oracle Java 7 before Update 11 allow remote attackers to execute arbitrary code by (1) using

CVE-2012-0507 CRITICAL POC
9.8 Jun 07

Unspecified vulnerability in the Java Runtime Environment (JRE) component in Oracle Java SE 7 Update 2 and earlier, 6 Up

CVE-2015-4852 CRITICAL POC
9.8 Nov 18

The WLS Security component in Oracle WebLogic Server 10.3.6.0, 12.1.2.0, 12.1.3.0, and 12.2.1.0 allows remote attackers

CVE-2012-5076 CRITICAL POC
9.8 Oct 16

Unspecified vulnerability in the Java Runtime Environment (JRE) component in Oracle Java SE 7 Update 7 and earlier allow

CVE-2017-3066 CRITICAL POC
9.8 Apr 27

Remote unauthenticated attackers can execute arbitrary code on Adobe ColdFusion servers through Java deserialization fla

CVE-2012-0391 CRITICAL POC
9.8 Jan 08

The ExceptionDelegator component in Apache Struts before 2.2.3.1 interprets parameter values as OGNL expressions during

Vendor StatusVendor

SUSE

Severity: Important
Product Status
SUSE Linux Enterprise Desktop 15 SP7 Not-Affected
SUSE Linux Enterprise Desktop 15 SP7 Not-Affected
SUSE Linux Enterprise High Performance Computing 15 SP7 Not-Affected
SUSE Linux Enterprise High Performance Computing 15 SP7 Not-Affected
SUSE Linux Enterprise Module for Development Tools 15 SP7 Not-Affected

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy