CVE-2026-39821
Critical · 9.6CVSS
9.6
EPSS
0.7%
Published
May 22, 2026
CISA due date
—
Cloudanix analysis
A malformed encoded domain name can trick some Go-based applications into treating a blocked or protected domain as allowed.
- Exploitation
- Remote Authenticated
- Attacker needs
- Low Privilege
- Complexity
- Moderate
- Impact
- Privilege Gain
- Component
- Library
- Class
- Improper Input Validation
- Remediation
- Upgrade
- Effort
- Medium
- Patch risk
- Low
What it actually does
This is an input-validation flaw in Go's IDNA hostname conversion logic. The affected ToASCII and ToUnicode behavior can incorrectly accept malformed Punycode/ACE labels beginning with xn-- that decode to an ASCII-only hostname label instead of rejecting them. Applications that make authorization, routing, tenancy, allowlist, denylist, or privilege decisions on one hostname representation and then later convert it to another representation can be tricked into treating a blocked or privileged ASCII hostname as if it were an allowed internationalized hostname. The result is hostname confusion that can enable authorization bypass and privilege escalation in software using the affected IDNA functionality.
Why it matters to the business
Applications that rely on Go IDNA hostname processing for access control, domain ownership checks, allowlists, denylists, proxy routing, SSO callback validation, multi-tenant isolation, or administrative boundary checks may grant access to resources that should have been blocked. The CVSS score is high because exploitation can be remote, low-complexity, and may allow compromise of confidentiality and integrity when hostname-based privilege checks are security-sensitive. EPSS is currently low and there is no known CISA KEV listing or ransomware association, but the pattern is easy to misuse in many applications because hostname normalization is commonly embedded in authentication, authorization, and network-routing logic.
How an attack unfolds
An attacker identifies an application feature that accepts a user-controlled hostname, domain, callback URL, tenant domain, upstream target, or service name and uses Go's IDNA conversion routines. The application first checks the ASCII form of the supplied hostname against a policy, such as denying example.com or reserving it for privileged users. The attacker supplies a crafted ACE/Punycode form such as a label beginning with xn-- that should be rejected but is incorrectly accepted by the vulnerable conversion logic. Because the pre-conversion value does not exactly match the protected hostname, the policy check may pass. The application then converts the value with ToUnicode or otherwise normalizes it, causing the malformed label to collapse into the protected ASCII hostname. Subsequent authorization, routing, certificate, callback, or resource-access logic operates on the privileged hostname, allowing the attacker to reach functionality or data associated with a name they were not authorized to use.
How to fix it
Upgrade to a Go/toolchain or golang.org/x/net/idna version that contains the vendor fix as soon as one is available for the affected product line; no exact fixed version was provided in the input, so teams should monitor the Go security advisory and package release notes and pin to the first non-vulnerable release. In the meantime, do not make security decisions on a different hostname representation than the one used later for routing or access. Canonicalize and validate hostnames once, reject invalid ACE/Punycode labels, and perform authorization on the exact canonical value that will be used downstream. Add explicit validation that labels beginning with xn-- must decode to valid non-ASCII IDNA labels and must not decode to ASCII-only labels. Avoid denylist-only hostname controls where possible; use strict allowlists, verified ownership, and exact canonical-domain comparisons. For high-risk services, add compensating controls at the application or gateway layer to reject suspicious malformed Punycode hostnames until dependencies are patched.
How to confirm the fix worked
Confirm all applications and libraries using Go IDNA handling are built with a fixed Go/x/net dependency once a fixed version is released. Run dependency inventory checks for golang.org/x/net/idna and any vendored copies. Add regression tests verifying that malformed labels such as ToUnicode("xn--example-.com") fail validation rather than returning "example.com". Test security-sensitive hostname workflows with crafted xn-- inputs and confirm policy checks, routing, and authorization all use the same canonical hostname representation. Review CI/CD dependency lockfiles and compiled artifacts to ensure rebuilt services no longer include vulnerable IDNA code. Where a compensating control is deployed, verify requests containing malformed ACE labels are rejected before business logic performs authorization or routing.
Typical attack path
- Find an application endpoint or workflow that accepts a hostname, domain name, URL, callback domain, tenant domain, or upstream target controlled by a low-privileged user.
- Determine whether access controls compare the raw ASCII hostname before later applying IDNA/Punycode normalization.
- Craft a malformed ACE/Punycode label beginning with xn-- that decodes to an ASCII-only label that should have been rejected.
- Submit the crafted hostname in the vulnerable workflow.
- Bypass the initial allowlist, denylist, ownership, or privilege check because the raw submitted hostname does not match the protected ASCII name.
- Trigger subsequent conversion through the affected IDNA ToUnicode or ToASCII behavior.
- Cause the application to treat the input as the protected ASCII hostname and gain unauthorized access, routing, or privilege.
How to detect it
This vulnerability does not create a universal host-level artifact; evidence of exploitation is most likely in application, API gateway, reverse proxy, authentication, authorization, domain-management, tenant-onboarding, callback-validation, and audit logs. Search for user-supplied hostnames, domains, URLs, redirect_uri values, callback URLs, upstream targets, or tenant domains containing ACE/Punycode labels beginning with xn--, especially labels that include unusual trailing hyphens or later normalize to an ASCII-only protected name. Compare raw submitted hostname fields with normalized/canonical hostname fields where both are logged; exploitation is indicated by a raw xn-- value being accepted and then processed as a sensitive ASCII hostname. Review authorization logs for allow/deny mismatches, such as a protected domain normally denied in raw form but allowed when supplied as Punycode. Investigate successful privileged actions, tenant changes, routing decisions, SSO/OAuth callback registrations, webhooks, or proxy fetches shortly after suspicious xn-- submissions. Because there are no known named threat actors, KEV listing, or public exploit maturity in the supplied data, detection should focus on behavior and normalization mismatches rather than actor-specific indicators.
- xn--
- xn--example-.com
- ToUnicode("xn--example-.com")
- raw_host=xn--
- hostname=xn--
- domain=xn--
- redirect_uri=*xn--*
- callback_url=*xn--*
- url=*xn--*
- Host: xn--
What your security team should do
- Inventory services written in Go or using Go-based components that accept or process hostnames, domains, URLs, callback URLs, tenant domains, federated identity endpoints, proxy targets, or service discovery names.
- Prioritize review of systems where hostname decisions affect authorization, tenant isolation, administrative access, SSRF protection, allowlists, denylist enforcement, certificate validation, or request routing.
- Monitor Go and golang.org/x/net security advisories for the fixed release and schedule upgrades promptly despite the currently low EPSS score, because exploitation depends heavily on application logic and may not require public exploit code.
- Add application-layer validation to reject malformed ACE/Punycode labels beginning with xn-- that decode to ASCII-only labels until the underlying dependency is patched.
- Ensure authorization checks are performed after canonicalization and against the same canonical hostname used for downstream access.
- Create regression tests for IDNA normalization edge cases and require them for services that perform hostname-based security decisions.
- Search historical logs for suspicious xn-- hostnames in authentication, authorization, routing, callback, domain-registration, proxy, and API request logs.
- If suspicious requests are found, investigate whether the normalized hostname maps to a protected, denied, administrative, internal, or tenant-owned domain.
The record
The ToASCII and ToUnicode functions incorrectly accept Punycode-encoded labels that decode to an ASCII-only label. For example, ToUnicode("xn--example-.com") incorrectly returns the name "example.com" rather than an error. This behavior can lead to privilege escalation in programs using the idna package. For example, a program which performs privilege checks on the ASCII hostname may reject "example.com" but permit "xn--example-.com". If that program subsequently converts the ASCII hostname to Unicode, it will inadvertently permits access to the Unicode name "example.com".
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|---|---|---|
| openSUSE:Leap 16.0 | amazon-ecs-init | 0 | 1.103.2-160000.1.1 |
| openSUSE:Leap 16.0 | amazon-ssm-agent | 0 | 3.3.4624.0-160000.1.1 |
| openSUSE:Leap 16.0 | containerd | 0 | 1.7.33-160000.1.1 |
| openSUSE:Leap 16.0 | distribution | 0 | 3.1.1-160000.1.1 |
| openSUSE:Leap 16.0 | docker | 0 | 29.4.0_ce-160000.7.1 |
| openSUSE:Leap 16.0 | docker-stable | 0 | 24.0.9_ce-160000.6.1 |
| openSUSE:Leap 16.0 | golang-github-prometheus-alertmanager | 0 | 0.28.1-bp160.2.1 |
| openSUSE:Leap 16.0 | google-cloud-sap-agent | 0 | 3.15-160000.1.1 |
| openSUSE:Leap 16.0 | google-guest-agent | 0 | 20260529.00-160000.1.1 |
| openSUSE:Leap 16.0 | google-osconfig-agent | 0 | 20260615.01-160000.1.1 |
| openSUSE:Leap 16.0 | grafana | 0 | 11.6.14+security04-bp160.1.1 |
| openSUSE:Leap 16.0 | helm | 0 | 3.21.1-160000.1.2 |
| openSUSE:Leap 16.0 | mcphost | 0 | 0.34.0-160000.2.1 |
| openSUSE:Leap 16.0 | trivy | 0 | 0.71.0-160000.1.1 |
| openSUSE:Leap 16.0 | warewulf4 | 0 | 4.7.0-bp160.1.1 |
| openSUSE:Tumbleweed | alloy | 0 | 1.17.0-1.1 |
| openSUSE:Tumbleweed | amazon-ecs-init | 0 | 1.103.2-1.1 |
| openSUSE:Tumbleweed | amazon-ssm-agent | 0 | 3.3.4515.0-1.1 |
| openSUSE:Tumbleweed | apptainer | 0 | 1.4.5-6.1 |
| openSUSE:Tumbleweed | azure-storage-azcopy | 0 | 10.32.4-1.1 |
| openSUSE:Tumbleweed | cadvisor | 0 | 0.60.3-1.1 |
| openSUSE:Tumbleweed | cloudflared | 0 | 2026.5.2-1.1 |
| openSUSE:Tumbleweed | containerd | 0 | 1.7.33-1.1 |
| openSUSE:Tumbleweed | distribution | 0 | 3.1.1-3.1 |
| openSUSE:Tumbleweed | docker | 0 | 29.4.0_ce-40.1 |
| openSUSE:Tumbleweed | docker-stable | 0 | 24.0.9_ce-18.1 |
| openSUSE:Tumbleweed | golang-github-prometheus-alertmanager | 0 | 0.32.2-2.1 |
| openSUSE:Tumbleweed | golang-github-prometheus-node_exporter | 0 | 1.11.1-2.1 |
| openSUSE:Tumbleweed | golang-github-prometheus-prometheus | 0 | 3.12.0-2.1 |
| openSUSE:Tumbleweed | google-guest-agent | 0 | 20260529.00-1.1 |
| openSUSE:Tumbleweed | grafana | 0 | 11.6.14+security04-2.1 |
| openSUSE:Tumbleweed | hauler | 0 | 1.4.3-4.1 |
| openSUSE:Tumbleweed | helm | 0 | 4.2.0-3.1 |
| openSUSE:Tumbleweed | helm3 | 0 | 3.21.0-2.1 |
| openSUSE:Tumbleweed | mcphost | 0 | 0.34.0-7.1 |
| openSUSE:Tumbleweed | prometheus-blackbox_exporter | 0 | 0.26.0-6.1 |
| openSUSE:Tumbleweed | rclone | 0 | 1.74.2-1.1 |
| openSUSE:Tumbleweed | rqlite | 0 | 10.1.0-2.1 |
| openSUSE:Tumbleweed | trivy | 0 | 0.70.0-4.1 |
| openSUSE:Tumbleweed | v2ray-core | 0 | 5.51.2-1.1 |
| openSUSE:Tumbleweed | velociraptor | 0 | 0.7.0.4.git185.a5708584-2.1 |
| openSUSE:Tumbleweed | warewulf4 | 0 | 4.7.0-1.1 |
| openSUSE:Tumbleweed | yq | 0 | 4.53.2-2.1 |
Related vulnerabilities
- CVE-2026-33814 When processing HTTP/2 SETTINGS frames, transport will enter an infinite loop of writing… Also affects amazon-ecs-init
- CVE-2026-44740 Billy is an interface filesystem abstraction for Go. Also affects amazon-ssm-agent
- CVE-2026-46597 An incorrectly placed cast from bytes to int allowed for server-side panic in the AES-GCM… Also affects amazon-ssm-agent
- CVE-2026-46598 For certain crafted inputs, a 'ed25519.PrivateKey' was created by casting malformed wire… Also affects amazon-ssm-agent
- CVE-2026-42508 Previously, a revoked 'SignatureKey' belonging to a CA was not correctly checked for… Also affects amazon-ssm-agent
- CVE-2026-46595 Previously, CVE-2024-45337 fixed an authorization bypass for misused ssh server… Also affects amazon-ssm-agent
- CVE-2026-39835 SSH servers which use CertChecker as a public key callback without setting… Also affects amazon-ssm-agent
- CVE-2026-39834 When writing data larger than 4GB in a single Write call on an SSH channel, an integer… Also affects amazon-ssm-agent