srmdn.

Back

Go 1.26.2: Three Stdlib Vulnerabilities ExplainedBlur image

A deploy blocked by govulncheck. No exotic dependency, no third-party package with a sketchy maintainer. Three vulnerabilities in Go’s own standard library, all requiring go1.26.2 to fix.

govulncheck is Go’s official vulnerability scanner. Unlike npm audit, which flags every package in your dependency tree whether your code touches it or not, govulncheck uses static analysis to trace call graphs. It only reports vulnerabilities in code paths reachable from your binary. If it fires, the issue is real.

All three are fixed in go1.26.2, released April 7, 2026. Here is what each one actually does.

CVE-2026-32283: TLS 1.3 KeyUpdate Deadlock#

Package: crypto/tls | ID: GO-2026-4870

TLS 1.3 introduced the KeyUpdate handshake message. Either side can send it post-handshake to rotate traffic keys, a security improvement over TLS 1.2. The issue: if a client packs multiple KeyUpdate messages into a single TLS record, the server deadlocks.

No authentication required. Any client connecting to your server can send this record. The connection hangs, consuming a goroutine and its stack until the server process is killed or the connection times out. Under load, that is resource exhaustion.

The affected symbols include Conn.Read, Conn.Write, Dial, and DialWithDialer. If your Go server accepts inbound TLS connections, or makes outbound TLS calls where a malicious endpoint could respond, this is reachable.

The attacker controls the record contents. Crafting the payload is trivial.

CVE-2026-32289: XSS in html/template via JS Template Literals#

Package: html/template | ID: GO-2026-4865

Go’s html/template package is the “safe” alternative to text/template. It tracks rendering context (HTML, JS, CSS, URL) and escapes content accordingly. The promise: you cannot accidentally output unescaped user content. Most Go developers treat this as settled.

The bug lives in JavaScript template literals, the backtick strings: `Hello ${name}`. Two things broke simultaneously. Context was not tracked correctly across template branches ({{if}}...{{else}}) inside a JS literal. And brace depth was not tracked, so the parser could lose its position inside the expression.

The result: template actions inside JS template literals could receive incorrect escaping. User-controlled content in those positions can inject executable JavaScript.

If you render HTML that embeds Go template actions inside JS template literals and that HTML ever contains user input, this is exploitable. Affected surface includes Template.Execute, Template.ExecuteTemplate, and the parse functions.

CVE-2026-33810: x509 Wildcard DNS Constraint Bypass#

Package: crypto/x509 | ID: GO-2026-4866

X.509 certificates support name constraints: a CA can issue a cert that is only valid for specific domains, or explicitly excluded from others. The excluded constraint means even a cert signed by a trusted root must not be accepted for those domains.

The bug: excluded DNS name constraints are not applied to wildcard SANs when the case differs. If the excluded constraint is internal.example.com but the cert’s SAN is *.INTERNAL.EXAMPLE.COM, the check fails to match and the certificate is accepted.

This is a regression. It only affects go1.26.0 and go1.26.1, not earlier versions. If you upgraded to go1.26 thinking it was the safer choice, you picked up a new certificate validation bypass that did not exist in go1.25.

The only affected symbol is Certificate.Verify. The case-insensitive mismatch is a recurring class of bug in security code: the same pattern has appeared in HTTP host header parsing, URL normalization, and email address validation. Security-critical string comparisons should be case-folded before comparison, not after.

The Fix#

Update the toolchain and rebuild:

go get [email protected]
go build -o your-binary ./cmd/server/
bash

If you are on go1.25, the TLS and html/template fixes were backported to go1.25.9. The x509 regression only exists in go1.26.x, so go1.25 users are not exposed.

Is This Right for You?#

Running govulncheck as a hard gate before every production deploy makes sense if you ship Go binaries directly. The signal-to-noise ratio is high enough that a block is meaningful. This exact scenario, a stdlib regression you did not actively notice, is what it catches.

Skipping it is defensible if you are on a long upgrade cycle with no external-facing TLS and no HTML rendering. But then you need a different mechanism for tracking CVEs, and “reading the release notes” is not one.

The XSS in html/template is the most surprising of the three. The package exists specifically to prevent this class of bug. Reading the advisory rather than just bumping the version is worth the five minutes. You learn where the package’s context tracking actually breaks down, and that changes how you write templates.

Enjoyed this post?

Get Linux tips, sysadmin war stories, and new posts delivered to your inbox.

No spam. Unsubscribe anytime.

Go 1.26.2: Three Stdlib Vulnerabilities Explained
https://srmdn.com/blog/go-1-26-2-stdlib-vulnerabilities
Author srmdn
Published at April 13, 2026