prathik@chicago:~$

CRLite+

A Chrome extension that checks TLS certificate revocation locally, using Bloom filters.

when
Apr 2025
where
University of Illinois Chicago, CS588 (Security and Privacy in Networked and Distributed Systems)
role
Design and implementation
stack
Chrome extension (Manifest V3), Node.js, Python, Bloom filters, TLS, MurmurHash3, SHA-256
links
paper · github · chrome web store
problem
CRLs are big and go stale, OCSP tells the CA every site you visit, and Chrome has no local check like Firefox's CRLite.
built
A Manifest V3 extension that checks each certificate against cascaded Bloom filters on your machine, with a Node.js backend and a Python filter generator behind it.
result
Every revoked certificate I tested was blocked, at 2 to 5 ms a check with no false positives. The revocations were simulated.
Contents
The problem
Approach
Requirements
Architecture
Data pipeline
Implementation
Evaluation
Not done yet

The problem

Browsers have two standard ways to learn that a certificate was revoked. CRLs are large and updated slowly. OCSP asks the certificate authority about every site you visit, which adds latency and tells the CA where you browse. Firefox ships CRLite, which avoids both by checking a local filter. Chromium browsers have nothing like it.

Mozilla's CRLite shows that local Bloom filter checks work. This project asks whether the same idea fits in a Chrome extension.

Approach

Revoked certificates live in cascaded Bloom filters: one filter for revoked serial numbers and one for known-good ones, which removes the false positives a single Bloom filter would give. The extension checks every certificate against them locally, so there are no network calls and nothing about your browsing leaves the machine.

  • Static filters cover the revocations we already know about and are built ahead of time.
  • A smaller dynamic filter handles updates between rebuilds, so a new revocation does not wait for a full regeneration.
  • Checks run in the browser: the extension reads the certificate, looks it up, and blocks the page if it is revoked.

Requirements

What the design had to satisfy

I started by reading how CRLs and OCSP fall short and how CRLite's cascade works, then wrote down what the extension had to do.

  • Fast: a check in under 10 ms, so pages do not feel slower.
  • Private: no network round trip per site.
  • Small: filters well under 1 MB, so they fit in a browser extension.
  • Compatible: runs on Chromium under Manifest V3.
  • Accurate: catches every revoked certificate it knows about, without blocking good ones.

Architecture

Three parts that can be built and tuned on their own

A Python script generates the filter cascades. A Node.js backend retrieves certificates and keeps the revocation lists. The Chrome extension does the lookup in the browser. The filters use MurmurHash3 for speed and SHA-256 to hash certificate identifiers.

CRLite+ system architecture showing the Chrome extension, Node.js backend, Bloom filters and the Python filter generator
Fig. 1 How the pieces fit together.

Keeping the parts separate means the filter generator can change without touching the extension.

Data pipeline

From certificate to filter to browser

  1. The Node.js backend opens raw TLS connections, pulls out each certificate's serial number and hashes it with SHA-256.
  2. It keeps the revocation lists up to date.
  3. The Python script reads those lists and generates the cascaded filters offline.
  4. The extension loads the static filters and asks a small JSON endpoint for dynamic updates, so new revocations do not need a full rebuild.
CRLite+ data flow from offline filter generation through distribution to the browser
Fig. 2 Offline generation, distribution, and the runtime check in the browser.

Implementation

  • Extension: reads the certificate during the TLS handshake, looks it up in the cascade (revoked filter first, then the known-good one), and blocks the domain if it is revoked.
  • Backend: raw TLS connections, certificate extraction and the revocation list, served over a REST API.
  • Python: filter generation with configurable parameters.
The extension blocking access to a site with a revoked certificate
Fig. 3 A blocked site (github.com, added to the revoked list for the test).
Popup showing the details of a revoked certificate
Fig. 4 Popup for a revoked certificate.
Popup showing a valid certificate for piazza.com
Fig. 5 Popup for a valid one.

Evaluation

What I measured

I simulated revocations by adding domains I trust, like github.com and uic.blackboard.com, to the revoked list and checking that the extension blocked them end to end. I tuned the filter parameters across a few rounds to shrink memory.

revoked certificates caught in my tests
100%
per check
2 to 5 ms
false positives
0
static / dynamic filters
< 512 KB / < 200 KB

These are results on simulated revocations. I have not tested against live CA feeds.

Not done yet

  • Real CA feeds, converted from live CRL and OCSP data.
  • Revocations of intermediate CAs.
  • Native browser integration instead of an extension.
  • A transparency log for revocations.

< back to projects/