Feb 9, 2026·5 min read·35 visits
OpenSSL trusted a C union without checking the tag. If you send a TimeStamp Response where the 'signing certificate' is an Integer instead of a Sequence, OpenSSL tries to read memory that isn't there. Result: Crash. Impact: DoS.
A classic type confusion vulnerability in OpenSSL's TimeStamp Protocol (TSP) implementation allows attackers to crash applications by supplying malformed ASN.1 structures. By treating a generic ASN.1 type as a Sequence without validation, the library performs an invalid pointer dereference, leading to a reliable Denial of Service.
If you've been in security research long enough, the mere mention of 'ASN.1' (Abstract Syntax Notation One) probably makes you reach for the nearest bottle of strong liquor. It is the protocol equivalent of a horror movie villain that refuses to stay dead. It's complex, archaic, and the parsers written for it are historically some of the most fragile code in existence.
CVE-2025-69420 is the latest entry in this saga. It targets the TimeStamp Protocol (TSP) defined in RFC 3161. TSP is what cryptographic systems use to prove a document existed at a specific time. It's the digital equivalent of holding a newspaper in a hostage video. OpenSSL, being the Swiss Army chainsaw of crypto, implements this protocol.
Here's the kicker: The vulnerability isn't some complex heap-feng-shui needing 400 lines of JavaScript to groom memory. It's a basic, fundamental failure to ask 'What is this thing?' before using it. It is the coding equivalent of drinking from a bottle labeled 'Milk' without checking if someone refilled it with bleach.
To understand this bug, you need to understand the C union. In OpenSSL, generic ASN.1 objects are often stored in an ASN1_TYPE structure. This structure is a tagged union. It contains a type field (telling you what it is) and a value union (holding the data).
When OpenSSL parses a TimeStamp Response, it looks for the signingCertificate attribute. According to the spec, this should be a SEQUENCE. But in the world of vulnerability research, 'should' is where the fun begins.
The vulnerability lies in crypto/ts/ts_rsp_verify.c. The code grabs the attribute and immediately assumes it is a SEQUENCE. It accesses attr->value.sequence.
But what happens if the attacker sends an INTEGER? The ASN1_TYPE structure still exists, but the value union is holding an ASN1_INTEGER pointer, not an ASN1_STRING (sequence) pointer. The memory layout is different. The code blindly follows the pointer as if it were a sequence, leading it off a cliff.
Let's look at the diff. It's painful in its simplicity. The vulnerable functions are ossl_ess_get_signing_cert and ossl_ess_get_signing_cert_v2.
Here is the vulnerable logic before the patch:
static ESS_SIGNING_CERT *ossl_ess_get_signing_cert(const PKCS7_SIGNER_INFO *si)
{
ASN1_TYPE *attr;
const unsigned char *p;
// 1. Get the attribute. It returns a generic ASN1_TYPE.
attr = PKCS7_get_signed_attribute(si, NID_id_smime_aa_signingCertificate);
// 2. Check if it exists.
if (attr == NULL)
return NULL;
// 3. THE BUG: Blindly access 'sequence' member of the union.
p = attr->value.sequence->data;
return d2i_ESS_SIGNING_CERT(NULL, &p, attr->value.sequence->length);
}The fix is literally one check. The developer simply added a verification step to ensure the tag matches V_ASN1_SEQUENCE before touching the union member.
// The Fix (Commit 27c7012c91cc986a598d7540f3079dfde2416eb9)
attr = PKCS7_get_signed_attribute(si, NID_id_smime_aa_signingCertificate);
- if (attr == NULL)
+ if (attr == NULL || attr->type != V_ASN1_SEQUENCE)
return NULL;This is a classic 'Time-of-Check to Time-of-Use' (TOCTOU) logic error, except the 'Check' was entirely missing. They checked if the pointer existed, but not what it pointed to.
Exploiting this does not require advanced memory corruption techniques because we aren't trying to gain code execution (which would be much harder here). We just want to watch the world burn (or at least the process crash).
signingCertificate (OID 1.2.840.113549.1.9.16.2.12) or signingCertificateV2 (OID 1.2.840.113549.1.9.16.2.47).SEQUENCE (Tag 0x30). Change this tag to INTEGER (0x02) or NULL (0x05).TS_RESP_verify_response().When attr->value.sequence->data is accessed, the code is effectively interpreting the bits of an Integer pointer (or NULL) as a Sequence struct. If attr->type was ASN1_NULL, the union value is often zeroed. Dereferencing 0x0->data is an immediate crash.
You might be thinking, "It's just a DoS, who cares?" In a microservices architecture, a DoS in a core cryptographic library is a massive headache.
Imagine a document management system that automatically verifies timestamps on incoming legal contracts. An attacker can flood this system with malformed responses. Every time the worker process touches one, it dies. If the process restart policy is slow or the attack volume is high, the entire ingestion pipeline grinds to a halt.
The CVSS score is 7.5 (High) because it is network exploitable (AV:N) and requires no privileges (PR:N). While it won't dump your database or give an attacker a shell, it effectively acts as a kill switch for any service relying on OpenSSL's TSP verification.
The remediation is straightforward: Update OpenSSL. The vulnerability affects a wide range of versions, including the 3.x series and the lingering 1.1.1 support versions.
If you cannot patch immediately, your only real mitigation is to disable TimeStamp verification in your application logic, or filter out TSP traffic at the firewall level if your application doesn't strictly require it. There is no configuration flag to turn off just this specific check; the code path is triggered automatically during response verification.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
OpenSSL OpenSSL | 3.6.0 | 3.6.1 |
OpenSSL OpenSSL | 3.5.0 | 3.5.5 |
OpenSSL OpenSSL | 3.4.0 | 3.4.4 |
OpenSSL OpenSSL | 3.3.0 | 3.3.6 |
OpenSSL OpenSSL | 3.0.0 | 3.0.19 |
| Attribute | Detail |
|---|---|
| CWE | CWE-754 / CWE-843 |
| Attack Vector | Network |
| CVSS v3.1 | 7.5 (High) |
| EPSS | 0.07% |
| Impact | Denial of Service |
| Exploit Status | PoC Possible (Trivial) |
Improper Check for Unusual or Exceptional Conditions