Closed Bug 1535235 Opened 5 years ago Closed 9 months ago

Plaintext OCSP can leak server identity, even with ECH

Categories

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

Firefox 102
defect

Tracking

()

RESOLVED INACTIVE

People

(Reporter: david, Unassigned)

References

(Blocks 1 open bug)

Details

(Keywords: privacy, Whiteboard: [psm-would-take])

Attachments

(3 files)

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:
    network.trr.mode=3
    network.trr.uri=https://1.1.1.1/dns-query
    network.security.esni.enabled=true
    
  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 !https://avaaz.org/. I also reproduced it also on a site with a Cloudflare Universal SSL certificate.

Actual results:

See the attached packet capture, esni-avaaz.org-ff67.0b1.pcap.

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
    tbsRequest
        requestList: 1 item
            Request
                reqCert
                    hashAlgorithm (SHA-1)
                    issuerNameHash: 105fa67a80089db5279f35ce830b43889ea3c70d
                    issuerKeyHash: 0f80611c823161d52f28e78d4638b42ce1c6d9e2
                    serialNumber: 0x0a6f47ebf07889f52e3916ee3ebcab6d

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

Subject:
    commonName                = *.avaaz.org
    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]
Severity: normal → S3

Packet capture of browsing https://tls-ech.dev/ with Firefox 102.14.0esr, showing DoH, TLS, and OCSP. Frame 55 is the OCSP request that leaks the certificate serial number 04c2af6ca57920cb3aada02b9a1391a565a2.

Leaking of certificate serial numbers via OCSP is still a problem with ECH and Firefox 102.14.0esr. I was checking again because of the recently declared intention to ship ECH (Bug 1725938).

  1. Start the browser on a new profile.
  2. Enable DNS over HTTPS in Connection Settings.
  3. Set network.dns.echconfig.enabled=true in about:config. (Per the Mozilla blog. network.dns.use_https_rr_as_altsvc was true by default.)
  4. Browse to https://tls-ech.dev/ and see "You are using ECH."

I attached a new ech-tls-dev-ff102.41.0.pcap. 192.168.2.2 is the local IP address, 172.64.41.4 is mozilla.cloudflare-dns.com (DoH), 34.138.246.121 is the tls-ech.dev web server, and 184.28.41.139 is the OSCP server.

Frame 27 is the TLS Client Hello, which shows the encrypted_client_hello extension 65037 and an outer Client Hello with a public name of public.tls-ech.dev (all expected).

Extension: server_name (len=23)
    Type: server_name (0)
    Length: 23
    Server Name Indication extension
        Server Name list length: 21
        Server Name Type: host_name (0)
        Server Name length: 18
        Server Name: public.tls-ech.dev
Extension: Unknown type 65037 (len=249)
    Type: Unknown (65037)
    Length: 249
    Data: 00000100012b0020511d0e49d11cf65378383be7a05609d9f039f0f3f2e409e4faca60ba…

But frame 55, the OCSP request, leaks the certificate serial number:

Request
    reqCert
        hashAlgorithm (SHA-1)
            Algorithm Id: 1.3.14.3.2.26 (SHA-1)
        issuerNameHash: 48dac9a0fb2bd32d4ff0de68d2f567b735f9b3c4
        issuerKeyHash: 142eb317b75856cbae500940e61faf9d8b14c2c6
        serialNumber: 0x04c2af6ca57920cb3aada02b9a1391a565a2

A certificate search on the serial number reveals the server_name that ECH was supposed to hide:

Subject:
    commonName                = tls-ech.dev
Summary: Plaintext OCSP can leak server name, even with ESNI → Plaintext OCSP can leak server name, even with ECH
Version: 67 Branch → Firefox 102
Blocks: ech

On the server side, the server should use OCSP stapling if they care enough about privacy to implement ECH.
On the client side we are working to address the OCSP privacy issue with CRLite (a general problem of OCSP, not limited to ECH).

Status: UNCONFIRMED → NEW
Depends on: crlite
Ever confirmed: true

ObNit: OCSP reveals the serial number, not the name directly (though in these days of tools like crt.sh it's not hard to get to the name)

The other reason we'd like to get rid of OCSP is because of perf (e.g. bug 803582)

Keywords: privacy
See Also: → 803582
Summary: Plaintext OCSP can leak server name, even with ECH → Plaintext OCSP can leak server identity, even with ECH

Dan's summary is correct. Sites offering ECH should also deploy privacy preserving revocation checking methods like OCSP Stapling (as Cloudflare currently do). tls-ech.dev is BoringSSL's test site and so is just configured for ECH without OCSP Stapling. On our side, we're working on CRLite which would deliver privacy preserving revocation checking for everyone.

Users who are concerned about misconfigured ECH-aware servers can use the option in Firefox's settings to disable OCSP entirely (see attached screenshot), but the downside is then that revocation checking won't be done. Note that even in the hypothetical situation that a site deploys ECH but not OCSP Stapling there's still a substantial privacy benefit because OCSP responses are typically cached for days and so most site visits will not have an associated OCSP Request.

I've added a note on this to the ECH Mozilla Wiki Page. Thank you for raising the issue and the detailed report. I'm going to close this bug as there's no specific action to take beyond making it clearer how these features interact.

Status: NEW → RESOLVED
Closed: 9 months ago
Resolution: --- → INACTIVE
No longer depends on: crlite
See Also: → crlite
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: