cloudflare / cloudflare/cfssl

revoke: certIsRevokedCRL does not validate cached CRL was issued by the cert's issuer

Open
#1,033 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
9.5k
Forks
1.2k
PR merge metrics
No merged PRs in 30d

Description

In `certIsRevokedCRL`, the CRL's signature is only validated immediately after being fetched and before storing it into the cache keyed by URL. In particular, there's no check to make sure that when a cached CRL is used, that the CRL is valid for the current issuer.

This can be a security issue if a maliciously generated certificate reuses the CRL distribution URL of a legitimate CA, and can MITM a request to that URL.

In practice, this probably isn't a major issue if the certificate chain is first validated against a trusted root store, but package revoke doesn't explicitly caution that. Package revoke might also be used by applications that validate certificate chains against different root stores (e.g., a "test" root store including a test CA that freely signs all well-formed CSRs), and it's inappropriate for one root store to be able to subvert another's security.

Attack scenario:
- Attacker has compromised a public key that has a legitimate *but revoked* VictimCert issued by VictimCA; the CRL is published via HTTP at VictimURL (most CRLs are published over HTTP).
- Attacker has the ability to MITM HTTP requests made by the cfssl/revoke-using application.
- Attacker can have the application invoke `revoke.VerifyCertificate` to validate an attacker supplied certificate chain (e.g., MaliciousCert signed by MaliciousCA).

Attack steps:
- Attacker generates MaliciousCert to specify VictimURL as the CRL distribution point.
- Attacker sends the {MaliciousCert, MaliciousCA} chain to the victim application to be checked for revocation.
- The application will try to download VictimURL (as specified by MaliciousCert).
- Attacker MITMs this request and provides a CRL response valid forever and without any revoked certificates.
- The application validates the CRL against MaliciousCA, and then caches it in `revoke.CRLSet` for VictimURL.
- Now if the attacker sends {VictimCert, VictimCA}, the `revoke.VerifyCertificate` will report that it has *not* been revoked, because it will use the maliciously generated CRL that was issued by MaliciousCA.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.