Eight Hashes, No Explanation: Go Hard-Codes a Certificate Distrust in CVE-2026-111943
Go shipped 1.27.3 and 1.26.10 on 19 October 2026. The release notes for both say the same ten words: they include security fixes to the crypto/x509 package. That is the entire public description of CVE-2026-111943, and it is a security release with exactly one item in it.
The tracking issue, golang/go#82345, was opened on 19 October by Go security team member Neal Patel, labelled Security and release-blocker, and routed down Go's URGENT track — the path reserved for problems that cannot wait for the regular minor-release cadence. Its text, in full, is four sentences: Go is blocking trust in a small set of intermediate certificates “due to specific security concerns around their operation”; Verify will now filter out chains containing them; and “we highly recommend immediately upgrading to this release.” The issue was later retitled from security: fix CVE-2026-111943 to crypto/x509: mitigation for security concerns with a specific Certificate Authority — singular — and closed on 20 October.
What the patch actually does
The master commit, 7f86f95, authored 19 October at 21:20 UTC, touches three files and adds 42 lines with no deletions: src/crypto/x509/verify.go (+31), src/crypto/x509/root_windows.go (+6) and src/crypto/x509/root_darwin.go (+5). Backports landed as aa64342 for the 1.26 branch and 90617fb for 1.27, under issues #82348 and #82349.
The mechanism is as blunt as the disclosure. verify.go gains a package-level map, distrustedSPKIHashes, containing eight hex-encoded SHA-256 digests and nothing else — no names, no comment identifying the issuer, only the hashes. A new helper, containsDistrustedSPKIHash, walks every certificate in a candidate chain, takes sha256.Sum256(c.RawSubjectPublicKeyInfo), and reports a hit. The chain-building loop in Verify then discards any candidate chain that contains one. The two platform files extend the same filter to the macOS and Windows system verifiers, so the behaviour does not change depending on whether Go does the path building itself or delegates to the OS.
Hashing the SubjectPublicKeyInfo rather than the whole certificate is the right call and worth noting, because it is what makes the block durable: the same key re-issued under a new serial, a new validity window, or a renewed cross-signature still hashes identically and is still filtered. A fingerprint-based blocklist would have been defeated by the next re-issuance.
Who it is, and why we are not telling you
Go names no certificate authority. Secondary reporting and the discussion thread around the issue point at a specific CA's intermediates, revoked in CCADB on 18–19 October, and several outlets have published that attribution; Go has not confirmed it and neither will we. We tried to settle it from primary data and could not: we pulled CCADB's two public Mozilla intermediate-certificate reports (the all-intermediates report with PEM, 2,552 records, and the CRL report, 1,767 parseable certificates), computed SHA-256 over each certificate's DER SubjectPublicKeyInfo, and matched against all eight hashes. Zero hits.
That is a null result, not a refutation. Those reports describe the currently disclosed intermediate population, so certificates that have been revoked and pulled are precisely the ones expected to be absent — the outcome is consistent with the published attribution without confirming it. The honest summary is that as of this writing the eight keys Go distrusts are not identifiable from the public CCADB corpus, and the only parties who have stated the reason are declining to state it.
Worth separating two things that are getting conflated in coverage. A CVE number was assigned, but nothing in Go was broken: there is no parsing bug, no bypass, no memory-safety defect in crypto/x509. This is a trust-policy change issued through the vulnerability pipeline because that is the only delivery channel a language runtime has. The “vulnerability” is being willing to build a chain through those keys.
The operational problem: distrust is compiled in
Here is the part that will bite operators. A browser distrust lands through a certificate-store update or a remotely managed blocklist, and takes effect on restart. Go's does not. The hashes are a literal in the standard library, so a Go binary only starts rejecting those chains after it is rebuilt with a patched toolchain and redeployed. Upgrading the Go installation on a build host changes nothing about the services already running in production.
For anyone running a fleet of Go services — which, in this sector, means most control planes, agent gateways, sidecars, CLIs and Kubernetes components — the remediation is a rebuild-and-redeploy sweep, not a package upgrade. Vendored and container-baked toolchains make that worse: a service whose image pins go1.27.1 stays on the old policy indefinitely, and nothing in its runtime will tell you so. The same structural property applies to the many Go-written CLIs your developers install from release pages, which is a point this week has made separately and vividly.
And the failure mode on the other side is availability, not compromise. Once rebuilt, a service that must talk to an endpoint still presenting one of these intermediates will fail verification outright, with no partial-trust or grace period in the code path. If your estate depends on certificates from the affected issuer, you will discover it as an outage during rollout rather than as a warning beforehand. Plan the sweep accordingly: rebuild a canary first, exercise the outbound TLS paths it actually uses, and only then fan out.
Why a four-sentence advisory is the right call — up to a point
Partial disclosure during an active CA investigation is defensible. Naming a compromised issuer before the relying-party ecosystem has shipped its blocks tells an attacker holding those keys exactly how long their window is. Go's URGENT track exists for this, and a 24-hour turnaround from issue to closed, with backports to both supported branches and releases out the same day, is a good showing.
The cost is that every downstream operator is now asked to perform a fleet-wide rebuild on the strength of “specific security concerns around their operation,” with no way to scope the blast radius in advance — you cannot check whether your dependencies chain through the affected keys, because you are not told which keys they are, only their hashes. The hashes are at least actionable: an operator can compute the SHA-256 of the SPKI of each intermediate their endpoints present and compare locally, which is the self-service check Go's design happens to make possible even while withholding names. That is the practical move this week, alongside the rebuild. It is the same class of trust-root problem as the ccTLD registry hijacks that produced unauthorised certificates for Google domains, and the same category of quiet TLS-verification failure as the OpenTelemetry empty-certificate-variable bug: the chain either means something or it does not, and the gap between those states is usually invisible until someone publishes eight hashes.
Our verification was read-only. The issue text, labels, URGENT-track designation, retitling, backport issues (#82348, #82349) and closure date were read first-hand from golang/go#82345. The commit metadata, file-level diff statistics and commit message for 7f86f95, aa64342 and 90617fb were read from the GitHub REST API, and the distrustedSPKIHashes map and containsDistrustedSPKIHash implementation were read from the patched src/crypto/x509/verify.go at that commit. The 19 October 2026 release dates and the crypto/x509-only scope of go1.27.3 and go1.26.10 were read from Go’s official release history page, and both versions confirmed current stable via the go.dev download index. The CCADB SPKI comparison described above was run locally against Mozilla’s published CSV reports; no certificate authority, endpoint or third-party host was probed. The certificate-authority attribution circulating in other coverage is explicitly not adopted here. Brave Search was used for discovery only.
Sources:
- golang/go issue #82345 — “crypto/x509: mitigation for security concerns with a specific Certificate Authority” (CVE-2026-111943; opened 19 October 2026, closed 20 October 2026)
- golang/go commit 7f86f95 — “crypto/x509: distrust a handful of intermediates” (verify.go, root_darwin.go, root_windows.go)
- Go release history — go1.27.3 and go1.26.10, released 19 October 2026, security fixes to crypto/x509
- Go security policy — the URGENT track
- al-ice.ai — ccTLD registry hijacks and unauthorised Google HTTPS certificates
- al-ice.ai — The empty-string certificate variable that disabled TLS verification