What the eMudhra CA Compromise Means for Elixir Developers

Michael Lubas, 2026-10-21

The eMudhra Intermediate CA Compromise site details how the private keys of eight eMudhra intermediate CA certificates are not secret. You may have seen reporting by now that one of the private keys used was the integer ‘4’. In summary, eMudhra did not generate their private keys correctly and now anyone on the internet can make a certificate for any domain, and many non-browser TLS clients, including Erlang’s :ssl, will accept it. Firefox, Chrome, Apple and Microsoft now block the intermediates with their own revocation data. Developers need to update their software and packages.

If you are responsible for a deployed Elixir/Phoenix application, this means an attacker who sits between your application and an intended destination (such as an API server) can impersonate that destination, and read and change all traffic between them. To divert the traffic, the attacker needs a DNS hijack, a BGP hijack, a compromised proxy, or one compromised host in your network. Before this incident, the lack of a trusted certificate usually stopped these attacks. That protection is gone, hence the current rush to patch this vulnerability.

If you are an Elixir developer, this means you must update every CA store your application uses.

  1. For your operating system, use the versions published on the incident page.
  2. Elixir castore - 1.0.22 is live - https://hex.pm/packages/castore/1.0.22
  3. Erlang certifi - pending - PR is open now
  4. Hex client - 2.5.4 is live - https://github.com/hexpm/hex/releases/tag/v2.5.4

If your application relies on the Erlang certifi, monitor for a new release and update as soon as it becomes available.


How to Check Your Application

Start with the versions in your lock file. Both of these stores usually arrive as transitive dependencies, so you likely have them whether or not you asked for them. Phoenix depended on castore up through 1.7, and anything that makes HTTP calls through hackney, which both Swoosh and ExAws use by default, pulls in certifi:

$ mix deps | grep -E "^\* (castore|certifi)"
* castore 1.0.20 (Hex package) (mix)
* certifi 2.15.0 (Hex package) (rebar3)

Both of these are affected. Mozilla removed three emSign roots from its store: emSign ECC Root CA - G3, emSign Root CA - C1, and emSign ECC Root CA - C3. The one on the attack path is emSign ECC Root CA - G3, because it cross-signs the eMudhra root that issued the eight compromised intermediates. You can see all three in the bundle each package ships:

$ grep -i "emSign" deps/castore/priv/cacerts.pem
emSign Root CA - G1
emSign ECC Root CA - G3
emSign Root CA - C1
emSign ECC Root CA - C3

Upgrade castore to 1.0.22 and run the same command again:

$ mix deps.update castore
$ grep -i "emSign" deps/castore/priv/cacerts.pem
emSign Root CA - G1

emSign Root CA - G1 was not removed by Mozilla and is still in the store, so seeing it here is expected. The three roots that were pulled are gone.

The same check works on certifi, which labels every certificate in its bundle:

$ grep -i 'Label: "emSign' deps/certifi/priv/cacerts.pem
# Label: "emSign Root CA - G1"
# Label: "emSign ECC Root CA - G3"
# Label: "emSign Root CA - C1"
# Label: "emSign ECC Root CA - C3"

There is no certifi release to upgrade to yet. Run this check again after one ships.


Do Not Forget the Operating System Store

If your application calls :public_key.cacerts_load/0 and :public_key.cacerts_get/0, or passes cacerts: :public_key.cacerts_get() to :ssl, then it is using the trust store of the operating system, not castore or certifi. Updating a hex dependency does nothing for that code path. On Debian and Ubuntu you can confirm the update landed:

$ ls /etc/ssl/certs | grep -i emsign
emSign_Root_CA_-_G1.pem

On a patched system the three distrusted roots are absent, and the G1 file above is expected to remain. The same applies to your Docker base images, your CI runners, and anything else that terminates or initiates TLS on your behalf. A deployed release built on an unpatched base image carries the unpatched store with it, so this is a rebuild and redeploy, not just a mix deps.update.

The Hex client ships its own CA store, so update it too, then confirm you are on the patched version:

$ mix local.hex --force
$ mix hex.info
Hex:    2.5.4
Elixir: 1.20.1
OTP:    28.5

Paraxial.io Customers

Paraxial.io App Audit collects the list of every dependency and version loaded in your application at runtime. Go to the most recent App Audit for your site and search for “castore” or “certifi” to see what each deployed application is actually running, which is the fastest way to find the one service that was missed when the rest of the fleet was upgraded.


Dan Janowski of the Erlang Ecosystem Foundation (EEF) Security Working Group also published an excellent summary on the EEF blog.


Paraxial.io is the only security platform built specifically for Elixir and Phoenix, helping developers and agents ship secure applications. Contact us today to get started.

Subscribe to stay up to date on new posts.