Skip to main content

Audit the certificate authorities your machine trusts: who runs them, which government they answer to, and which roots nobody vouches for.

Project description

certlens

Your machine trusts ~150 certificate authorities. Do you know who they are?

certlens reads a trust store, joins it against the Common CA Database, and tells you who operates every root you trust, which government they answer to, and which roots nobody's root program vouches for.

PyPI License: MIT Python Dependencies Tests Read only

[English] · Русский


certlens scanning a trust store

Real output. That scan found two TLS-interception proxies and an unidentified root on the machine it ran on.


The problem

Any one of the ~150 root CAs your machine trusts can issue a certificate for any domain, and your browser will accept it silently. Most people have never looked at the list. The tooling to enumerate a trust store exists. The tooling to judge one did not.

This is not a hypothetical concern, and it is not a niche one:

"Windows trusts 322 root certificates issued by 122 different organizations. I think this is a good point I would never trust 122 people in my life with my bank-account details. But if I trust my browser it seems that is exactly what I'm doing. Isn't there a better way?" — Hacker News, on a 255-point thread

"Is there any tool out there that will monitor my system's use of root CAs? So far I have not found anything … there are root CAs I do not think I need to trust; Hong Kong Post Office comes to mind as one I would rather not trust." — security.stackexchange.com, Nov 2023

"Is there a way to check if any non-standard root CAs have been added to my browser, without going through them one by one and comparing them to a fresh install? … It's too easy for arbitrary programs to add root CAs." — Hacker News, after the Superfish scandal

"There are now tons of Certification Authorities (CAs) that are trusted by default in major OS's, many of which are unrecognizable without online lookup or reference." — security.stackexchange.com, 177 votes, 25,884 views

And the stakes are documented history, not speculation:

When What
2019 Kazakh ISPs required a government root on every device. Mozilla and Google blocked it: "once installed, allowed the government to decrypt and read anything a user types or posts."
2020 Kazakhstan tried again. Mozilla, Apple, Google and Microsoft all blocked it.
2022 Russia's Ministry of Digital Development issued its own root, valid until 2032. EFF: "paves the way for a decade of digital surveillance."
2023 EU eIDAS Article 45 would have forced browsers to trust state-designated CAs. 504 scientists from 39 countries objected.
2024 Chrome distrusted Entrust after "a pattern of compliance failures."

certlens exists so you can answer the question for your own machine, in two seconds, without reading 150 certificates by hand.


Install

pip install certlens

No runtime dependencies. A tool that tells you what to trust should not ask you to trust a dependency tree first.

Quick start

certlens                      # audit the system trust store
certlens scan node            # audit Node.js's compiled-in roots
certlens stores               # list every trust store on this machine
certlens explain "Hongkong Post"

Answer the "should I remove this?" question

certlens explain

Use it as a CI gate

Fail a build when an unexpected root is baked into an image:

certlens scan --fail-on high

Exit codes: 0 clean · 1 findings at or above the threshold · 2 error.

# .github/workflows/trust.yml
- run: pip install certlens
- run: certlens scan --fail-on high

Other output formats

certlens scan -f json | jq '.findings[] | select(.severity=="high")'
certlens scan -f html -o report.html
certlens refresh              # pull the newest CCADB data

What it detects

Finding Severity Meaning
REVOKED_ROOT_TRUSTED critical CCADB says revoked; it is still in your store
UNRECOGNISED_ROOT high In no root program, matching no known product
LOCAL_INTERCEPTION_ROOT high/medium A known proxy, antivirus or dev tool root — named
NO_ROOT_PROGRAM high Known CA, included by no vendor
SHORT_LIVED_ROOT high Unknown root valid under a year — a proxy signature
EXPIRED_ROOT medium Expired but still trusted
STALE_AUDIT low Audit period ended over 460 days ago
STATE_OPERATED_CA low Operator is a government or state-owned body
CA_INCIDENT_HISTORY low Operator has a documented distrust event
WIDE_DELEGATION info 5+ external organisations can issue under this root
JURISDICTION_CONCENTRATION info One country holds over 30% of your roots
VENDOR_PLATFORM_ROOT info An OS vendor's own root (e.g. Apple), verified by pinned fingerprint

certlens recognises roots from Burp Suite, Fiddler, Charles, mitmproxy, mkcert, HTTP Toolkit, Proxyman, Zscaler, Netskope, Palo Alto, Fortinet, Forcepoint, Blue Coat, Cisco Umbrella, Sophos, McAfee, Kaspersky, Avast, AVG, Bitdefender and ESET — so a legitimate corporate proxy shows up as named, not as an unexplained mystery.


How it compares

certlens trust_stores_observatory paranoia cert-manage openssl/certmgr
Lists your roots yes yes container images only yes yes
Names the operator yes no no no no
Shows jurisdiction yes no no no no
Flags state-operated CAs yes no no no no
Detects injected/proxy roots yes no no no no
Names the proxy product yes no no no no
Vendor-program membership yes partial no no no
Audit staleness yes no no no no
CI exit codes yes no yes no no
HTML report yes no no no no
Runtime dependencies none several Go binary Go binary n/a
Modifies your store never no no yes yes

The closest thing ever built for the specific "which of these are governments?" question was certaintls — 8 stars, last touched in 2021, and it keyed on country freedom scores rather than operator identity.


How it works

  1. Enumerate certificates from the chosen store, read-only.
  2. SHA-256 fingerprint each one.
  3. Join against CCADB, the database Mozilla, Apple, Microsoft, Google and Cisco use to run their root programs. certlens ships a snapshot (940 roots), so it works offline and in air-gapped CI.
  4. Apply the rule set and rank by severity.

Decoding uses the standard library's ssl module — the same OpenSSL your Python already relies on. certlens hand-rolls no cryptography.

certlens never modifies a trust store. There is no code path that writes to one. Removing roots breaks machines in confusing ways; certlens gives you the information and gets out of the way.


A note on language

"State-operated" here is a statement about corporate structure — the operator is a government body or state-owned enterprise — not an accusation of wrongdoing. Plenty of state-run CAs are well-administered. The point is that you should know, and right now most people cannot find out.


Roadmap

  • Windows CTL trust store support
  • Firefox NSS cert9.db reader
  • --diff against a previously saved scan, for fleet drift detection
  • SARIF output for code-scanning dashboards
  • Optional check of which roots your machine has actually used
  • Community-maintained interception-product signature list

Contributing

See CONTRIBUTING.md. The most valuable contributions are new interception-product signatures and corrections to the state-operator mapping — both live in certlens/knowledge.py and both are plain data.

git clone https://github.com/Ax1zz/certlens
cd certlens
python3 -m unittest discover -s tests -t .

Data and licence

Certificate authority data comes from the Common CA Database, published by the CCADB and used here under its terms of use. certlens is not affiliated with CCADB, Mozilla, or any certificate authority.

certlens is released under the MIT licence.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

certlens-1.0.1.tar.gz (116.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

certlens-1.0.1-py3-none-any.whl (101.5 kB view details)

Uploaded Python 3

File details

Details for the file certlens-1.0.1.tar.gz.

File metadata

  • Download URL: certlens-1.0.1.tar.gz
  • Upload date:
  • Size: 116.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.25

File hashes

Hashes for certlens-1.0.1.tar.gz
Algorithm Hash digest
SHA256 29396b5e2e9f8007384757267b6ea7af1629f2351ebbbabb37ae8359afce6bcf
MD5 4ef6828d7f2ddf641b6adfe798a0695a
BLAKE2b-256 60e41d8b3b870b6e9303cdc16ec0160acf0860b65f9ac3732fc78558f36d43d9

See more details on using hashes here.

File details

Details for the file certlens-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: certlens-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 101.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.25

File hashes

Hashes for certlens-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 fb9eeebc5ead4dd0127779fe85866f4668bab5ea59a79ffc440d636684662cc3
MD5 40978591f6d9acf5cd98fe97c4a3dd05
BLAKE2b-256 e2aff30a0a8c556ca54658e2c2d3745e692670edeb60bf4edbadf1902d9e2013

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page