Open Bug 1535235 Opened 9 months ago Updated 8 months ago

Plaintext OCSP can leak server name, even with ESNI


(Core :: Security: PSM, defect, P5)

67 Branch





(Reporter: david, Unassigned)


(Whiteboard: [psm-would-take])


(1 file)

37.61 KB, application/vnd.tcpdump.pcap

User Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0

Steps to reproduce:

Forgive me if this is off base; I searched online but didn't find anything substantive about the interaction between ESNI and OSCP. I marked this report security-sensitive out of an abundance of caution, because it describes a way to reveal the server name of some ESNI-protected sessions. I only noticed this today and haven't done much investigation.

I used Firefox Developer Edition, 67.0b1 linux64.

  1. Start a packet capture.
  2. Go to about:config and enable ESNI:
  3. Browse to an ESNI-supporting (i.e. on Cloudflare) site. The OCSP details will differ depending on the site's CA, so probably not every site will exhibit the problem. I used ! I also reproduced it also on a site with a Cloudflare Universal SSL certificate.

Actual results:

See the attached packet capture,

Packet 54 shows that ESNI is in use, in the absence of a server_name extension and the presence of an extension with type 0xffce.

Secure Sockets Layer
    TLSv1.3 Record Layer: Handshake Protocol: Client Hello
        Content Type: Handshake (22)
        Version: TLS 1.0 (0x0301)
        Length: 711
        Handshake Protocol: Client Hello
            Handshake Type: Client Hello (1)
            Length: 707
            Version: TLS 1.2 (0x0303)
            Random: b0d147fb528800fe0b125bc3a4e69bd618e6530d983f4295...
            Session ID Length: 32
            Session ID: 0adb221d6ff7f7f500126d30d4ba552b43297c892160a237...
            Cipher Suites Length: 36
            Cipher Suites (18 suites)
            Compression Methods Length: 1
            Compression Methods (1 method)
            Extensions Length: 598
            Extension: extended_master_secret (len=0)
            Extension: renegotiation_info (len=1)
            Extension: supported_groups (len=14)
            Extension: ec_point_formats (len=2)
            Extension: SessionTicket TLS (len=0)
            Extension: application_layer_protocol_negotiation (len=14)
            Extension: status_request (len=5)
            Extension: key_share (len=107)
            Extension: supported_versions (len=9)
            Extension: signature_algorithms (len=24)
            Extension: psk_key_exchange_modes (len=2)
            Extension: Unknown type 65486 (len=366)
            Extension: Unknown type 28 (len=2)

So far the server name has not been revealed to an eavesdropper: the client encrypts it with ESNI, and TLS 1.3 encrypts the server's certificate. But packet 97 is a plaintext OCSP request that reveals the certificate serial number:

Online Certificate Status Protocol
        requestList: 1 item
                    hashAlgorithm (SHA-1)
                    issuerNameHash: 105fa67a80089db5279f35ce830b43889ea3c70d
                    issuerKeyHash: 0f80611c823161d52f28e78d4638b42ce1c6d9e2
                    serialNumber: 0x0a6f47ebf07889f52e3916ee3ebcab6d

A search for the serial number finds a match that reveals the server name.

    commonName                = *
    organizationalUnitName    = Tech
    organizationName          = Avaaz Foundation
    localityName              = New York
    stateOrProvinceName       = New York
    countryName               = US

Expected results:

I don't know exactly what should happen, but the OCSP request defeats the purpose of ESNI. Suppose a network intermediary wants to block a site. DNS over HTTPS, ESNI, and TLS 1.3 mean that it cannot match on DNS queries, SNI, or the server certificate; nor even on the IP address without blocking unrelated sites. But it can make a blacklist of certificate serial numbers, then watch for OCSP requests/responses with serial numbers on the blacklist, and then infer (e.g. temporally) which TLS sessions they belong to, or take some other action such as blocking the client's source IP address.

Maybe the trr and/or esni prefs should additionally affect OSCP? Or maybe OCSP needs consideration in documentation about activating ESNI in Firefox?

I'm not involved in ESNI but I would assume that OCSP is intentionally not considered here. Forwarding this to some folks who probably know.

Group: firefox-core-security → core-security
Component: Untriaged → Networking
Product: Firefox → Core
Group: core-security → network-core-security

OCSP leaking hostnames is a well known problem.

Group: network-core-security

OCSP stapling and perhaps eventually CRLite are the mitigations here. CRLite (bug 1429800) is complex, but moving along, and would have the widest potential applicability.

I think it's probably best, for now, to get this into documentation somewhere.

(In reply to J.C. Jones [:jcj] (he/him) from comment #3)

I think it's probably best, for now, to get this into documentation somewhere.

Documentation works for me, seeing as ESNI is still fairly experimental. I'd appreciate an informed opinion as to the best way to reduce the risk of OSCP leaks. My first inclination would be to set the pref security.OCSP.enabled=0, but I don't know for example what other side effects that may have, or if there are better ways to do it.

Component: Networking → Security: PSM

I found a blog post on the same topic that predates this report.

Despite DoH and ESNI, with OCSP, web activity is insecure and not private by Sean McElroy, 2019-01-05.

Priority: -- → P5
Whiteboard: [psm-would-take]
You need to log in before you can comment on or make changes to this bug.