Skip to content

CVE-2026-39821 — Go standard library (golang.org/x/net/idna)

Key facts

CVE-2026-39821 (The Go Authors) is a Critical (10.0) vulnerability: Go standard library (golang.org/x/net/idna). This entry ships ready-to-deploy detection and prevention rules (Snort) plus a detection-only PoC and a Docker test lab.

CVE CVE-2026-39821
Severity Critical (10.0)
Vendor The Go Authors
Product Go standard library (golang.org/x/net/idna)
Detection / prevention Snort
PoC poc.py
Source 2026/CVE-2026-39821/

Details

CVE-2026-39821 (The Go Authors) is a Critical (10.0) vulnerability: Go standard library (golang.org/x/net/idna). This entry ships a detection-only proof-of-concept (PoC), a Docker test lab, and ready-to-deploy detection and prevention rules (Snort) — see Detection and prevention below. Source: NVD record.

Overview

Field Value
CVE CVE-2026-39821
CVSS 10.0 (Critical)
Vendor The Go Authors
Product Go standard library (golang.org/x/net/idna)
Affected All Go versions shipping affected golang.org/x/net prior to fix
Fixed Upgrade Go runtime and golang.org/x/net to patched version

Root Cause

The ToASCII and ToUnicode functions in Go's golang.org/x/net/idna package incorrectly accept internationalized domain name labels prefixed with xn-- (Punycode labels) that decode to sequences containing only ASCII characters. Per IDNA2008 (RFC 5891), such labels are invalid — a Punycode-encoded label that round-trips to a purely ASCII string is a non-conformant encoding. Go's implementation fails to reject these malformed labels, causing downstream components that receive the "decoded" domain to see a different hostname than was originally presented, enabling homograph-style attacks without requiring non-ASCII glyphs.

Problem

Attackers can craft domains using malformed xn-- Punycode labels that visually or structurally impersonate legitimate domains:

  • Certificate validation bypass: TLS libraries performing hostname verification may compare the Punycode form while the certificate was issued for the ASCII form (or vice versa), allowing an attacker's certificate to be accepted as valid for the target domain.
  • Domain spoofing / phishing: Malicious domains pass ToASCII validation and are displayed to users as legitimate-looking hostnames, facilitating credential harvesting campaigns.
  • Security control bypass: Allowlist-based security controls (WAFs, proxy filters, SSRF mitigations) that normalize domains via ToASCII before comparison can be evaded by submitting malformed Punycode variants of blocked domains.
  • OAuth / OIDC redirect validation bypass: Applications using Go's IDNA library to validate redirect URIs may accept malformed Punycode variants of unregistered domains.

Detection

Run the proof-of-concept to test whether your Go runtime is vulnerable:

python poc.py --check-version
# Or build and run the Go test binary:
go run poc.go

The PoC constructs a malformed xn-- label that decodes to an ASCII-only string and passes it through idna.ToASCII(). A vulnerable runtime returns success (nil error) and the decoded ASCII string rather than returning an ErrInvalidLabel error.

Manual check in Go:

import "golang.org/x/net/idna"
result, err := idna.ToASCII("xn--nxasmq6b.com") // should error on patched versions

Remediation

  1. Upgrade Go: Update to the Go version that includes the patched golang.org/x/net/idna package. Check the Go release notes for the specific version containing this fix.
  2. Update golang.org/x/net: Run go get golang.org/x/net@<patched-version> and rebuild all affected binaries.
  3. Validate domains post-decode: In application code, after calling ToASCII, verify the result contains no unexpected character transformations by comparing the label character set.
  4. Rebuild and redeploy: All Go binaries that perform domain validation (TLS, HTTP clients, proxy servers) must be rebuilt against the patched library and redeployed.
  5. Audit domain validation logic: Review application code that uses golang.org/x/net/idna for security-sensitive operations (certificate pinning, SSRF filtering, allowlists) and add secondary validation layers.

References

  • NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-39821
  • Go Issue Tracker: https://github.com/golang/go/issues
  • RFC 5891 - IDNA2008: https://datatracker.ietf.org/doc/html/rfc5891
  • golang.org/x/net releases: https://pkg.go.dev/golang.org/x/net

Detection and prevention

Ready-to-deploy defensive rules for CVE-2026-39821, for authorized testing and blue-team detection engineering:

References: NVD — CVE-2026-39821 · full write-up on the searchable site

Detection & prevention rules

alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (msg:"CVE-2026-39821 Go Punycode xn-- homograph in Host header"; flow:to_server,established; content:"xn--"; http_header; pcre:"/Host:\s*xn--[a-z0-9\-]+\.[^\r\n]+/i"; classtype:policy-violation; sid:9002697; rev:1;)
alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (msg:"CVE-2026-39821 Go Punycode IDN label in request URI"; flow:to_server,established; content:"xn--"; http_uri; pcre:"/xn--[a-z0-9]+-[a-z0-9a-z]+/i"; classtype:policy-violation; sid:9002698; rev:1;)
alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (msg:"CVE-2026-39821 Go Punycode xn-- domain in Referer bypass attempt"; flow:to_server,established; content:"Referer:"; http_header; content:"xn--"; http_header; pcre:"/Referer:\s*https?:\/\/xn--[a-z0-9\-]+\./i"; classtype:policy-violation; sid:9002699; rev:1;)

:material-file-download: prevention/snort.rules

Frequently asked questions

What is CVE-2026-39821?

CVE-2026-39821 (The Go Authors) is a Critical (10.0) vulnerability: Go standard library (golang.org/x/net/idna). This entry ships ready-to-deploy detection and prevention rules (Snort) plus a detection-only PoC and a Docker test lab.

How do I detect CVE-2026-39821?

Deploy the Snort detection rule included with this entry (see Detection & prevention rules below), then validate it against the detection-only PoC in the Docker test lab.

How do I block or mitigate CVE-2026-39821?

Upgrade to a fixed version per the vendor advisory; the NVD record lists the affected versions. Use the included PoC to verify your remediation.


For authorized security testing and research only. See the full source and NVD record.