Most microcontrollers probably escaped the eMudhra intermediate CA compromise, because their firmware trusts one or two roots for the service it talks to. Devices that ship a full Mozilla root bundle, Linux-class gateways and anything with frozen firmware are different. Check which roots each device class trusts, test it, and plan firmware updates.
For what happened and how browsers responded, read our eMudhra CA key compromise explainer; for language runtimes, see our Python, Node, Go and Electron guide. This post stays on hardware: how embedded TLS stacks choose roots, what pinning buys you, and how to audit a fleet you cannot simply apt upgrade.
The short version for device teams
Eight eMudhra intermediate CAs, six for TLS and two for code signing, had private keys so small that anyone could compute them from the public certificates. Scott Helme recovered all of them and lists values such as 4, 56 and 115. He also reports that the intermediates were cross-signed in May 2025 by Sectigo's AAA Certificate Services root, so two paths lead to them: one through the emSign ECC Root CA G3, one through that Sectigo root.
Browsers blocked the intermediates within hours and enforce Certificate Transparency. Helme's concern is clients that trust a bundle on disk and check neither revocation nor CT. He names IoT, embedded and OT devices and warns that frozen firmware will keep trusting these certificates until they expire in July 2039.
Daniel Mangum, who writes about embedded systems on his blog, argues that most microcontroller (MCU) devices are probably fine anyway, because of how MCU firmware handles trust in the first place.
| Device class | Typical trust source | Likely exposure | Source of the reasoning |
|---|---|---|---|
| MCU firmware that trusts one root for its own cloud endpoint | One or two root certificates compiled into the image | Low, unless that root is emSign ECC Root CA G3 or the Sectigo AAA root | Daniel Mangum |
| MCU firmware built with a large bundled root list (for example ESP-IDF's full bundle) | Mozilla's root list as of the SDK release | Possible: our check found emSign ECC Root CA G3 in ESP-IDF's current full bundle file | ESP-IDF docs and repository |
| Linux-class IoT (gateways, Raspberry Pi-class boards, routers) | The distro's ca-certificates package | Likely, until the package is updated | Daniel Mangum, Scott Helme |
| Devices that cannot or do not update | Whatever shipped at manufacture | Exposed until the certificates expire | Scott Helme, Russ Cox quoted by Mangum |
Why most MCUs likely escaped
Mangum's post, published 21 October, makes four points. We summarise them in our own words.
MCU trust stores are small. Servers ship large vendor-maintained bundles. A microcontroller often has under 1 MB of non-volatile storage, so firmware carries only the certificates it needs.
Nobody else maintains them. On bare metal or an RTOS, the developer decides which roots to trust; no OS vendor adds or removes roots for the device.
One root is common. His example is Zephyr's http_get sample, which connects to google.com and embeds a single root, GlobalSign Root CA, a little under 1 KB in DER form. A device that trusts only that root never accepts an eMudhra chain.
Bigger chains cost resources. Longer chains need larger buffers, and every extra algorithm, curve and hash adds code size.
His conclusion is that devices pinned to a specific root or service chain are probably not directly affected, but only if the firmware includes neither an eMudhra root nor the Sectigo root used for the cross-signing. Linux-class IoT is a different story; for those devices he writes "you should update them as soon as possible."
He also cites Russ Cox, who wrote that "IOT boxes that can't or don't update are now trivially MITM'able forever." Both views hold: a well-scoped MCU trust store sidesteps this incident, while a device that copied a full bundle and never updates does not.
How embedded TLS stacks choose roots
Whether a device is exposed comes down to one question: what is in its trust store, and who put it there? Here is what each stack's own documentation says about where roots come from. We have not tested these stacks against the eMudhra chains ourselves.
| Stack | Where trusted roots come from | Revocation, per the docs we read | Narrower option |
|---|---|---|---|
| Mbed TLS | The application parses certificates with mbedtls_x509_crt_parse_file() (or the buffer variant) and passes them to mbedtls_ssl_conf_ca_chain(). The tutorial tells you to supply your own trusted CA list. | mbedtls_ssl_conf_ca_chain() takes an optional CRL list alongside the CA chain | Ship only the roots your endpoints use; mbedtls_ssl_conf_ca_cb() lets the app supply trusted certificates through a callback when the set changes often |
| ESP-IDF certificate bundle | Built from Mozilla's NSS root store. CONFIG_MBEDTLS_DEFAULT_CERTIFICATE_BUNDLE picks the full list (more than 130 roots) or a common list of about 35 | Not described for the bundle | Common list, a custom bundle via CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE_PATH, or no bundle with a single CA |
| wolfSSL | wolfSSL_CTX_load_verify_locations() from files, or wolfSSL_CTX_load_verify_buffer() from memory when built with NO_FILESYSTEM | The manual chapter we read does not cover CRL or OCSP checking | wolfSSL_CTX_trust_peer_cert() and wolfSSL_CTX_trust_peer_buffer() for trusted peer certificates |
| BearSSL | A configurable set of trust anchors, each a name plus a public key | The minimal X.509 engine "does not handle revocation" | The known-key engine ignores the certificate chain and uses one configured public key |
| Zephyr | tls_credential_add() registers a TLS_CREDENTIAL_CA_CERTIFICATE under a security tag; tls_credential_delete() removes it | Not covered on the credentials page | Register only the CA for your endpoint |
Two things stand out. None of the general-purpose libraries ships a public root bundle by default; Mbed TLS, wolfSSL, BearSSL and Zephyr all expect the developer to load specific roots, which is why Mangum expects most MCUs to be fine. The exception is an SDK that bundles a public root list for convenience, and ESP-IDF is the clearest documented example: its bundle inherits whatever Mozilla trusted on the day it was generated.
The docs we read also describe revocation either as an optional CRL input (Mbed TLS) or not at all. On an MCU there is rarely a CRL fetcher, so revocation by eMudhra changes nothing. Only a new trust store in a new firmware image does.
What we found in the ESP-IDF bundle
Because the ESP-IDF bundle is the case most likely to matter, we read the bundle file in the ESP-IDF repository's master branch on 22 October. Its header says the certificate data is from Mozilla as of 13 August 2026, generated with curl's mk-ca-bundle.pl. It includes a certificate titled "emSign ECC Root CA G3", alongside emSign Root CA G1, C1 and ECC C3. Only G3 ECC is part of the current removal.
So, as of our reading, an ESP-IDF application built from that source with the full bundle selected would trust the eMudhra G3 root, and through it the direct chains to the weak intermediates. We could not find an Espressif statement on eMudhra yet; check the ESP-IDF release notes and repository for an updated bundle before acting on our reading.
The common list is different. Its CSV of owners and names does not include eMudhra or emSign. It does name "Comodo AAA Services root", the name Mozilla-derived lists use for the Sectigo AAA Certificate Services root. We did not find that root in the bundle file itself, so we cannot say whether a given build includes it. The tracking site run by Mozilla's Dennis Jackson lists both "Comodo AAA Services root" and "emSign ECC Root CA G3" in its Linux workaround, which is a good hint at which two names to search for in any bundle.
Per the ESP-IDF docs, the bundle is embedded in the application, so it changes only when the application is updated over the air; for a newer list you download Mozilla's (or curl's) and rebuild. The tracking site lists a curl CA bundle dated 20 October 2026.
Certificate pinning: what it bought, and what it costs
"Pinning" covers several different decisions, and they behave differently in an incident like this.
| What you pin | eMudhra exposure | Main risk |
|---|---|---|
| A full public root bundle (no pinning) | Exposed if the bundle includes the G3 ECC root or the Sectigo AAA root | Inherits every CA failure in the bundle |
| One or two specific roots | Exposed only if you chose one of those two roots | Breaks if your service moves to a different CA |
| An intermediate | Not exposed unless you pinned an eMudhra intermediate | Intermediates rotate more often than roots |
| A leaf certificate or its public key | Not exposed | Breaks on every renewal unless the key is reused |
| A whole certificate hash, issuer included | Not exposed | Breaks when the same key is cross-signed under another issuer |
The AWS IoT Core documentation is a useful real-world reference. AWS recommends installing all of the supported Amazon root certificates on devices, and it warns against pinning by hashing the whole certificate because its endpoints' certificates are cross-signed by Starfield and carry a different issuer name. It also tells developers to make sure they can update root certificates on every device.
That is the trade-off. Narrow trust protected many devices from this incident; narrow trust without an update path turns the next CA migration into a field recall. What holds up is a small set of roots for your endpoints, a backup root from a different CA, and a tested way to change both.
Cloudflare's incident post adds that verification often happens in a lower layer: "Updating the SDK alone may not change the underlying policy." On an IoT product, that layer can be the TLS library or a modem's firmware.
How to audit a device fleet
This walkthrough assumes you have the firmware source or build artifacts for each device class, plus a lab unit. Do it per device class, not per device.
-
List device classes by TLS stack and trust source. For each product and hardware revision, record the TLS library, the SDK version, and where the roots come from: a single embedded certificate, an SDK bundle, a file on a Linux filesystem, or a modem module.
-
Search the source tree for the two root names. Embedded roots usually live in a PEM file, a header with a byte array, or a generated bundle.
# PEM files and generated bundles
grep -rIl -e "emSign ECC Root CA - G3" -e "Comodo AAA Services root" -e "AAA Certificate Services" .
# List every subject in a PEM bundle you ship
awk -v cmd='openssl x509 -noout -subject' '/BEGIN CERT/{close(cmd)};{print | cmd}' < certs/ca_bundle.pem
grep -c "BEGIN CERTIFICATE" certs/ca_bundle.pem
- Check ESP-IDF build settings. Find out whether the bundle is on, which list is selected, and whether a custom path adds anything.
grep -E "CONFIG_MBEDTLS_(CERTIFICATE_BUNDLE|DEFAULT_CERTIFICATE_BUNDLE|CUSTOM_CERTIFICATE_BUNDLE)" sdkconfig
grep -n -e "emSign ECC Root CA - G3" -e "Comodo AAA Services root" \
"$IDF_PATH/components/mbedtls/esp_crt_bundle/cacrt_all.pem"
- Search the shipped binary when you do not have the source. Certificate subject names are stored as readable text inside DER, so a string search on a firmware image usually finds them. A miss is not proof; compressed or encrypted images hide them.
strings -n 8 firmware.bin | grep -i -e "emsign" -e "AAA Certificate Services"
- Check Linux-class devices like servers. Look at the bundle and the package version, then compare with your distro's fixed version on the tracking site.
ssh admin@gateway 'grep -c "emSign ECC Root CA - G3" /etc/ssl/certs/ca-certificates.crt'
ssh admin@gateway 'dpkg -l ca-certificates 2>/dev/null || opkg list-installed | grep -i ca-'
- Test a lab unit against the public test hosts. The tracking site hosts endpoints served by the compromised chains, including one through the Sectigo cross-sign. Point a lab build at them; a certificate error is the result you want.
curl https://dv-g3b-emudhra.we-have-a-problem.com/
curl https://dv-g3b-aaa-emudhra.we-have-a-problem.com/
On an MCU, use a lab build with the test hostname in place of your endpoint, and never ship it.
- Check what your own endpoints present. If your device cloud, OTA server or provisioning service uses an eMudhra certificate under the G3 ECC root, your devices may depend on that root. Replace the server certificate before you remove the root from firmware, or devices will lose their connection.
openssl s_client -showcerts -verify 5 -connect ota.example.com:443 -servername ota.example.com </dev/null
Mangum uses the same openssl s_client approach in his post to show a chain.
- Record a decision per device class: not affected, next release, urgent, or cannot update.
Firmware update paths
The update channel is where a forged certificate would do the most harm. Helme lists IoT firmware updaters among the clients where a forged certificate could deliver attacker code. Whether that is realistic for your devices depends on one design choice.
If firmware images are signed with your own key and verified on the device before install, a forged TLS certificate for your update server is not enough to install code. The attacker could block or replay updates, but not substitute an image. TLS then protects confidentiality and metadata rather than integrity.
If the device trusts whatever the update server sends over TLS, the trust store is the only defence, and that device class goes to the top of your list.
A safe order for the fix:
- Confirm your own update and cloud endpoints do not chain to the G3 ECC root or the cross-signed intermediates.
- Build firmware with a refreshed bundle, or better, a reduced set of roots for your endpoints plus a backup.
- Roll out in stages and watch connection error rates; a spike usually means a removed root that some endpoint still needs.
- For Linux-class devices, ship the updated ca-certificates package through your normal OTA mechanism and restart services that load it.
For devices that cannot be updated, use network controls: restrict outbound traffic to your endpoints, control fleet DNS where you can, and set a replacement date. That narrows who can get in the middle without fixing the trust store.
Common mistakes and troubleshooting
- Searching only for "eMudhra". Certificates use the emSign brand. Search for "emSign ECC Root CA G3" and, for the cross-sign path, "Comodo AAA Services root" or "AAA Certificate Services".
- Forgetting the cross-sign. Removing the eMudhra root does nothing for a device that also trusts the Sectigo AAA root. Test both test hosts.
- Removing roots before checking your own endpoints. If your OTA server uses an eMudhra certificate, a firmware update that drops the root can strand the fleet on the old image.
- Assuming the SDK update fixed it. ESP-IDF regenerates its bundle from Mozilla's list in SDK releases, but your product only changes when you rebuild and ship. Check the bundle date inside the image.
- Disabling verification to restore connectivity. Mbed TLS documents that
MBEDTLS_SSL_VERIFY_NONEskips peer checks and is insecure on the client; its own tutorial warns not to use it in a full application. Cloudflare gives the same advice for every client. - Pinning by full certificate hash. As AWS warns, cross-signing changes the issuer and breaks this kind of pin. Pin the public key or the root, with a backup.
What would have helped
Practices any team can use
Trust only what you connect to. Mangum's core point is a design rule worth adopting everywhere, not just on MCUs: ship the roots for your endpoints, not the whole public web PKI. A device that talks to one cloud needs one or two roots and a backup.
Make the trust store an updateable artifact. Where your platform allows it, keep roots in a versioned file or partition that an OTA update can replace, as AWS's guidance implies.
Sign firmware images and verify them on the device. That keeps a TLS trust failure from becoming code execution through the update channel.
Keep an inventory of trust stores per device class. Record the TLS library, SDK version, bundle source and bundle date, so "which products carry a full Mozilla bundle" has an answer on day one.
Test against bad chains in CI. A lab test that expects the eMudhra test hosts to fail, or a similar negative test with your own deliberately untrusted CA, catches a trust store regression before it ships.
Watch CT for your own domains. It tells you if someone issues a certificate for your update server. See certificate authority compromise risks.
Where Safeguard fits
Safeguard covers the software side of a connected product, not the microcontroller.
- Linux-class gateways, companion apps and device clouds. SBOM and dependency scanning covers repos, container images and SBOM files:
safeguard scan --dir .,safeguard scan --image <name>orsafeguard scan --sbom <file>, with JSON results under./output. The platform shows which projects contain a given component and version, so "which gateway images still carry an old ca-certificates package" or "which backend services pin certifi below 2026.10.19" becomes a query. Our post on SBOM incident response shows that workflow. - Keeping old versions out. Policies and gates evaluated in the platform can hold back an image that still carries an outdated bundle package. A bundle change with no advisory will not show as a vulnerability match, so use the component and version view.
- Doing the change with approval. The Safeguard CLI assistant can edit code and run commands with your approval: replace a PEM bundle in a firmware repository, update an sdkconfig option, kick off the build and rerun the grep checks above. Its
/permissionsmodes run from Ask to Strict. Autonomous remediation can open fix PRs; it is off by default.
Where it does not help: Safeguard does not analyse MCU firmware images or certificates compiled into C arrays, and does not reach devices in the field. It cannot assess a CA's key ceremony or tell you whether anyone forged a certificate. It would not have prevented this incident; the keys were weak at the source.
Zero-Day Discovery and Gold
Zero-Day Discovery looks for previously unknown flaws before a CVE exists, in an agentic mode and a deterministic scanner mode, and issues findings as SGZ advisories before they reach public CVE databases. It covers seven package ecosystems. A CA's weak key generation is not a package flaw and sits outside that scope; this one was reported by a researcher credited by Mozilla and Google.
Gold Open Source (gold.safeguard.sh, free, no login) is searchable CVE intelligence with CVSS, EPSS, KEV status, affected and fixed versions and a recommended safe version, with a free read API and a CI gate GitHub Action. Trust store changes often have no CVE, so also check the tracking site and vendor notes.
Gold Registry (registry.safeguard.sh, paid) provides hardened drop-in components and container images held to zero exploitable critical or high CVEs, SLSA L3 or higher and Sigstore-signed, with evidence pages; an artifact loses its badge on regression. We are not claiming it shipped an eMudhra fix early. The habit it supports is the one that matters for gateway and backend images: pull patched, signed base images from a curated source and rebuild fast when upstream trust changes.
FAQ
Is my microcontroller affected by the eMudhra compromise?
Probably not, if its firmware trusts only the root for your own endpoint. Daniel Mangum argues most MCUs fall into that group. It is affected if the firmware includes emSign ECC Root CA G3 or the Sectigo AAA Certificate Services root, for example through a full Mozilla bundle. Search the source or image for both names.
Does the ESP-IDF certificate bundle include the eMudhra root?
In the copy of the full bundle file we read on 22 October, generated from Mozilla data as of 13 August 2026, yes: it lists emSign ECC Root CA G3. The common list of about 35 roots does not name eMudhra. Check your SDK version and sdkconfig, and look for an updated bundle in ESP-IDF releases.
Will revocation protect my devices?
Usually not. BearSSL's docs say its minimal engine does not handle revocation, and most MCU firmware never fetches CRLs or OCSP. eMudhra revoked the intermediates on 18 October; a device that does not check will not notice. Only a new trust store helps.
Is certificate pinning the answer?
Pinning a small set of roots for your own endpoints protected many devices here. It also makes CA changes harder, so pin public keys or roots rather than full certificate hashes, ship a backup from a different CA, and make sure the pins can be updated over the air.
What about devices that can never be updated?
Helme notes the intermediates remain valid until 2039. Use network controls (restrict outbound traffic, control DNS) and plan replacement. That narrows the risk without removing it.
Does the code-signing part of the incident matter for devices?
Two of the eight intermediates were for code signing. Helme's concern there is Windows software that trusts the eMudhra code-signing root. Firmware signed with your own key and verified by your own bootloader does not rely on public code-signing CAs.
Fix it without waiting for upstream
In incidents like this one, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.
1. Autonomous remediation: pull requests, not tickets
When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation covers eight categories, including dependencies, licenses, security posture and findings. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.
2. Gold Open Source: the safe version in seconds, free
gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds. The safeguard-sh/gold-scan-action GitHub Action can fail a build on a known exploited vulnerability, on any known vulnerability, or never, so a version you have just removed cannot quietly come back in next week's merge.
3. Gold Registry: start from components that are already fixed
registry.safeguard.sh provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs, zero malware and a completed license check, with SLSA L3 or higher provenance, a Sigstore signature and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.
When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. This fork and patch flow is in early access today, so ask which packages it covers before you plan around it.
| Your situation | What to use |
|---|---|
| A fixed version exists | Autonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version |
| You need to know today whether you are affected | Gold Open Source lookup and "Am I affected?" checker, free and without login |
| You want vulnerable versions to stop shipping | The Gold scan GitHub Action in CI, plus Safeguard policies and gates |
| Upstream has no fix yet, or will not ship one | A custom Gold request; fork and patch (early access) |
| You want to start clean on new projects | Pull hardened components and images from Gold Registry |
One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.
See how Safeguard would have helped
The CLI demo is a real session fixing a lodash CVE: it reads the finding and advisory, asks before each command, edits package.json, and runs install and tests with approval. For this incident, you would use the same loop in a firmware or gateway repository: ask it to replace the PEM bundle with a reduced root set, update the sdkconfig option, rebuild and rerun the grep checks, approving each step. The demo does not show this incident.
Click through it at your own pace, or open it full screen.
The local runner demo sets up the runner on your own machine, approves it with its device code, then scans from the terminal. For a device product, that machine would be the build host for your gateway images, so you scan them where they are built.
Click through it at your own pace, or open it full screen.
The desktop app demo shows a CLI session in the conversation list, a request for work on your computer, a folder choice, and Approve or Deny on each command and file edit, ending with an upgrade done and tests passing. Here, the folder would be your firmware repository, and each edit to a trust store file would be something you approve after reading it.
Click through it at your own pace, or open it full screen.
To scan the gateway images and services around your devices, download Safeguard and follow the CLI docs. For the rest of the month, see October 2026 security incidents and what would have helped.
Quick check
Your ESP32 firmware uses the ESP-IDF certificate bundle with the full Mozilla list. Is it safe because eMudhra revoked the intermediates?
No. The device does not check revocation, and the full bundle in the ESP-IDF source we read includes emSign ECC Root CA G3. Rebuild with an updated or reduced bundle, test against both public test hosts, and ship the update over the air.
You removed the emSign root from your firmware. Why does the Sectigo test host still connect?
The weak intermediates were also cross-signed by Sectigo's AAA Certificate Services root. If your firmware trusts that root, the chain still validates. Remove or avoid that root too, unless one of your own endpoints needs it, and retest.
Sources
- Daniel Mangum: Your MCU likely escaped the eMudhra intermediate CA compromise
- Scott Helme: Eight Bits of Trust
- eMudhra incident tracking and test site
- Espressif: ESP x509 Certificate Bundle (ESP-IDF docs)
- ESP-IDF repository: cacrt_all.pem (master)
- ESP-IDF repository: cmn_crt_authorities.csv (master)
- Mbed TLS: tutorial
- Mbed TLS: ssl.h API header
- wolfSSL manual: certificates and keys
- BearSSL: X.509 certificates
- Zephyr: TLS credentials API
- AWS IoT Core: Server authentication
- Cloudflare: eMudhra certificate compromise
Last reviewed: 22 October 2026. This is a developing story; check the linked advisories for the latest status.