Revoked mTLS Certificates Could Bypass Firewall Rules During Session Resumption

On December 16, 2022, Cloudflare discovered that some users presenting revoked client certificates were not being blocked by Firewall Rules when resuming sessions via mutual TLS (mTLS). The issue was traced to a code path that failed to load the client certificate chain during session resumption, leaving no certificate data for revocation checks. Cloudflare has since applied a fix and found no evidence of exploitation, but notified potentially affected customers as a precaution.

How mTLS Authentication and Revocation Work at the Edge

Cloudflare's edge terminates incoming TLS connections and acts as a reverse proxy between end users and upstream services. When mTLS is enabled for a hostname, the edge parses the incoming client certificate and converts it into metadata attached to forwarded HTTP requests, which upstreams can use for authorization decisions.

Firewall Rules, a feature introduced in March 2021, gives customers the option to enforce certificate revocation at the HTTP request level. When a client presents a certificate during the TLS handshake, the entire certificate chain is stored on the connection. For each HTTP request on that connection, Cloudflare examines:

  1. Leaf certificate Subject Key Identifier (SKI)
  2. Leaf certificate Serial Number (SN)
  3. Issuer certificate SKI
  4. Issuer certificate SN

The issuer SKI and leaf certificate SN query internal data stores containing collections of revoked serial numbers per issuer. If a match is found, metadata is set for Firewall Rules processing.

The Role of Session Resumption in the Bug

Session resumption lets clients and servers skip full handshakes by reusing previously established TLS state. Two mechanisms exist: session IDs (stateful—the server caches session context keyed by ID) and session tickets (stateless—the server encrypts and sends session context to the client, which returns it in future ClientHello messages).

The vulnerability appeared when sessions were resumed: the code that stores the client certificate chain in application data did not execute during resumption, resulting in an empty chain. Without this data, revocation status could not be checked and Firewall Rules could not enforce revocation policies.

In a reconstructed example, Cloudflare used OpenSSL's s_client to handshake with a revoked certificate and save the session context. An HTTP request on the new connection correctly returned a 403 status. However, resuming with that saved session context and issuing the identical request succeeded—revealing the bug.

Immediate Mitigation and Long-Term Fix

Cloudflare's first response was to disable session resumption for all mTLS connections, blocking the vulnerability immediately. To safely re-enable resumption, the team eliminated the dependency on data stored within TLS connection state and instead used an API call that retrieves the leaf certificate whether or not resumption occurs. This requires the leaf certificate serial number and issuer SKI, the latter of which is embedded in the leaf certificate as the Authority Key Identifier (AKI). Cloudflare can now obtain this value using X509_get0_authority_key_id, similar to how X509_get0_subject_key_id retrieves the SKI.

Timeline of Events

All timestamps are in UTC

  • March 2021: Firewall Rules feature enabling revocation blocking for mTLS certificates is introduced.
  • 2022-12-16 21:53: Vulnerability is discovered; work begins on disabling session resumption for mTLS connections.
  • 2022-12-17 02:20: Fix is validated and rollout begins globally.
  • 2022-12-17 21:07: Rollout of the mitigation is complete.
  • 2023-01-12 16:40: Rollout begins for a fix supporting both session resumption and revocation.
  • 2023-01-18 14:07: Rollout of the complete fix finishes.

After reviewing logs, Cloudflare has not observed any evidence that this vulnerability was exploited in the wild. The final fix, supporting both session resumption and certificate revocation, has been fully deployed.