cybersecurity

Why mitmproxy Added `--emudhra`

Why mitmproxy Added `--emudhra`

Picture a test client that accepts a certificate for service.test even though the certificate chain passes through a certificate authority your team intended to distrust. That awkward result is exactly the sort of thing security engineers need to reproduce, not wave away. A mitmproxy commit listed for its unreleased next version adds --emudhra, an opt-in switch that makes mitmproxy sign generated interception certificates with a compromised eMudhra intermediate Certificate Authority (CA) key. Mozilla reported on October 17, 2026, that private keys associated with eight eMudhra intermediate certificates had been compromised and could be used to issue fraudulent HTTPS certificates. (blog.mozilla.org)

First, what normal mitmproxy does

Transport Layer Security (TLS) encrypts network traffic and lets a client check that it is talking to the right server. That second part depends on certificates. A CA is an organization trusted to sign certificates, while an intermediate CA is a delegated signer beneath a trusted root. The certificate at the end of the chain, issued for a hostname such as service.test, is often called the leaf certificate.

Mitmproxy normally creates its own local CA inside ~/.mitmproxy. After you install that CA on a test device, mitmproxy can inspect an HTTPS connection, create a matching leaf certificate on the fly, and sign it with the local CA. The client accepts the replacement certificate because you deliberately taught it to trust mitmproxy. This is controlled man-in-the-middle (MITM) interception: mitmproxy acts as the server to the client and as the client to the real upstream server. (docs.mitmproxy.org)

That normal arrangement is useful, but it does not test how software reacts to a damaged public trust path. A client may correctly trust a local testing CA while still mishandling a revoked or compromised intermediate CA. Why would a proxy deliberately use a broken CA? To make that difference measurable.

What --emudhra changes

The new option is a Boolean setting whose default is false. That detail matters: ordinary mitmproxy behavior does not change unless an operator explicitly enables the switch. The command-line parser exposes the setting as --emudhra, while mitmproxy’s shared option system also supports setting named options through --set. The web interface’s generated option state was updated as well. (github.com)

When the option is enabled, the certificate store stops using the ordinary mitmproxy CA as its default signing identity. The commit adds an embedded PEM fixture, a text format commonly used to store certificates and private keys. That fixture contains one specific compromised eMudhra intermediate key and its certificate chain, including a cross-signed parent path. This is not a general “use any eMudhra certificate” feature; it is a reproducible test fixture for one affected chain.

The configuration code loads that private key, installs the associated certificates as the default chain, selects the first certificate as the default CA, and creates a dummy certificate revocation list (CRL) for the store. A CRL is a signed list of certificates that should no longer be trusted. Here, the dummy CRL is internal test plumbing, not evidence that the compromised key is safe. The private key is intentionally test material and should never be treated as a secret or copied into a production system.

There is also a small cryptography refactor hiding underneath. Mitmproxy’s certificate store previously described its default private key as RSA-only. The eMudhra fixture uses an Elliptic Curve (EC) key, so the type annotations and helper functions now accept either an RSA key or an EC private key. That change is easy to miss in a diff, but it is what allows the same certificate-generation machinery to handle both families of algorithms.

Why certificate-chain handling matters

A certificate is not useful to a client in isolation. The client needs a chain that connects the leaf certificate to a root it trusts. The patch adjusts how extra chain certificates are collected so an existing certificate entry can contribute its own intermediate certificates even when there is no separate chain file. Upstream certificates can still be added when that option is enabled.

That distinction matters for this fixture because the compromised intermediate is the entire point of the test. If mitmproxy generated a leaf certificate but accidentally dropped the intermediate, the client would fail for the wrong reason. The regression test performs a TLS handshake with a client configured to trust the relevant eMudhra root, checks the hostname in the certificate’s Subject Alternative Name (SAN), and verifies that the certificate chain is also passed correctly into QUIC, the transport used by HTTP/3.

The intended shape looks like this:

trusted test root
 │
 ▼
compromised eMudhra intermediate
 │
 ▼
generated certificate for service.test

A client that still accepts this path is not necessarily vulnerable in a real attack. An attacker would also need to get the victim’s traffic to a server presenting the forged certificate, through control of a network path, DNS, routing, or another interception point. The flag isolates one important question: does this verifier reject the certificate chain it should no longer accept?

How to use it without creating a new problem

The commit places the feature under mitmproxy’s unreleased “next” changelog, so first check that the build you are using actually contains the option:

# Unix-like systems
mitmproxy --options | grep -i emudhra

# Run only in an isolated test environment
mitmproxy --emudhra

# Equivalent option-store form
mitmproxy --set emudhra=true

Use a disposable virtual machine, container, or dedicated test device. Give the test application its own trust store instead of installing anything globally, use synthetic hostnames and dummy credentials, and capture only traffic you own. Modern browsers may already block affected eMudhra certificates through vendor-managed protections, so a small TLS test program or library with a deliberately controlled trust store can produce a clearer result. Mozilla used a centralized blocklist for Firefox and also updated its broader certificate store; that split illustrates why different TLS consumers need separate testing. (blog.mozilla.org)

The useful experiment has two halves. First, enable --emudhra and confirm that the client accepts the expected chain. Then run the same test after applying the client’s update or trust-store fix and confirm that the handshake fails. That before-and-after comparison turns a frightening certificate incident into a regression test with a clear pass condition.

The larger lesson

--emudhra is not a convenience switch for everyday proxying. It is a lab instrument built around an uncomfortable fact: certificate security depends on every verifier, library, operating system, and embedded trust store learning which keys are no longer trustworthy. By embedding a known-bad chain and testing it across TLS and QUIC paths, mitmproxy gives maintainers a way to find those gaps before someone else does.

ahsan

ahsan

Hello! I am Mr Ahsan, the writer of the Website. I am from Netherland. I like to write about technology and the news around it.

Comments (0)

No comments yet. Be the first to respond!

Leave a Comment

Your comment will be visible after review.