curl · Report #3784125
GnuTLS OCSP stapling accepts unrelated SingleResponse (no cert-ID binding)
How it was found
Summary
This report describes a variant of the publicly disclosed curl vulnerability CVE-2020-8286 (OCSP stapling verification bypass), found in the GnuTLS TLS backend (lib/vtls/gtls.c). The original CVE affected the NSS backend; this variant reproduces the same logical class of defect — accepting revocation status from OCSP response entry singleResponse[0] without verifying that the entry corresponds to the authenticated server certificate — in the GnuTLS code path. An attacker who controls or can MitM a TLS connection can supply a crafted stapled OCSP response that bypasses revocation checking, allowing a revoked certificate to be accepted.
Vulnerability Details
| Field | Value |
|---|---|
| Variant of | CVE-2020-8286 (curl OCSP stapling verification bypass — NSS) |
| Component | lib/vtls/gtls.c — GnuTLS TLS backend |
| Function | gtls_verify_ocsp_status |
| Sink line | gtls.c:1527–1528 |
| CWE | CWE-295: Improper Certificate Validation |
| CVSS v3 vector | AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N |
| CVSS v3 score | 7.4 (High) |
| Affected config | GnuTLS backend + CURLOPT_SSL_VERIFYSTATUS enabled |
Relationship to CVE-2020-8286
CVE-2020-8286 was originally fixed in the NSS/OpenSSL code paths of curl by ensuring that each OCSP SingleResponse entry is matched against the actual peer certificate's CertID (certificate + issuer hash) before its status is trusted. The GnuTLS path (gtls_verify_ocsp_status) was not covered by that fix and continues to blindly trust the revocation status from singleResponse[0], regardless of whether that entry corresponds to the authenticated peer certificate.
Vulnerable Code Path
gnutls_ocsp_status_request_get(session, &status_request) // gtls.c:1437
→ gnutls_ocsp_resp_import(ocsp_resp, &status_request) // gtls.c:1457
→ gnutls_ocsp_resp_get_single(ocsp_resp, 0, ..., &status, ..., &reason) // gtls.c:1464–1465
→ trust sink: (status != GNUTLS_OCSP_CERT_GOOD) ? CURLE_SSL_INVALIDCERTSTATUS : CURLE_OK // gtls.c:1527–1528
The hard-coded index 0 is used to select the OCSP SingleResponse entry. No certificate-ID matching step exists between the entry and the validated peer certificate — there is no call to any *_check_crt-style binding function or equivalent issuer/serial cross-check.
Steps to Reproduce
Preconditions:
- curl built against GnuTLS (not OpenSSL/NSS).
CURLOPT_SSL_VERIFYSTATUS(or--cert-statusCLI flag) is enabled.- Attacker controls the TLS server or can perform a MitM on the connection.
Attack steps:
- Obtain or fabricate a valid OCSP response containing at least two
SingleResponseentries:singleResponse[0]:certStatus = goodfor an unrelatedcertID(e.g., a different certificate/issuer pair).singleResponse[1](or absent): entry for the actual (revoked) peer certificate'scertID.
- Serve this crafted stapled OCSP response during the TLS handshake with a revoked server certificate.
- curl reads
singleResponse[0], seesGNUTLS_OCSP_CERT_GOOD, and returnsCURLE_OK— the revoked certificate is accepted.
Payload (conceptual DER structure):
OCSPResponse {
responseStatus: successful
responseBytes: BasicOCSPResponse {
responses: [
SingleResponse { ← index 0 (trusted by gtls.c)
certID: { <UNRELATED cert/issuer hash> }
certStatus: good
},
SingleResponse { ← index 1 (ignored by gtls.c)
certID: { <actual peer cert hash> }
certStatus: revoked
}
]
}
}
Impact
A successful exploit allows a TLS peer presenting a revoked certificate to be accepted as valid when curl is built against GnuTLS and CURLOPT_SSL_VERIFYSTATUS is enabled. The revocation check that users explicitly opt into provides no protection.
- Confidentiality: High — traffic sent to an attacker-controlled (revoked-cert) host is exposed.
- Integrity: High — responses from a revoked-cert server are accepted as authentic.
- Availability: None — no service disruption.
- Attack complexity: High — requires controlling the TLS server or performing active MitM; OCSP response must be cryptographically valid (signed by a trusted OCSP responder, or the attacker must also compromise the OCSP responder).