Go net/url IPv6 Parsing Bug CVE-2026-25679 Fixed in Go 1.26.1

  • Thread Author
The Go standard library’s URL parser has been found to accept malformed IPv6 host literals in a way that can lead to surprising, inconsistent behavior across systems — a defect tracked as CVE-2026-25679 and fixed in the Go project’s March 2026 security releases. The root cause is an insufficient validation in net/url.Parse that allowed garbage before an IPv6 IP-literal to be effectively ignored, meaning inputs that should have been rejected were accepted. The Go team issued fixes in Go 1.26.1 and Go 1.25.8; vendors and downstream distributions are already packaging advisories and updates. (groups.google.com)

Cartoon Go gopher beside a code window showing URL.Parse of example.com with check and cross icons.Background / Overview​

The Go standard library package net/url is the canonical place in Go programs for parsing, validating, and manipulating URLs. Because it is used pervasively — in web servers, HTTP clients, proxies, SDKs, command-line tools, and many cloud-native components — a parsing bug in net/url has a broad impact surface.
CVE-2026-25679 is described as “Incorrect parsing of IPv6 host literals in net/url.” In short, url.Parse did not strictly require an IPv6 literal (the familiar square-bracketed form like [2001:db8::1]) to appear at the start of the host subcomponent, permitting malformed inputs where arbitrary text could precede the IP-literal and still be parsed as if the host were a valid IPv6 literal. The Go project concluded this behavior was incorrect and has changed net/url.Parse to reject IPv6 literals that are not at the start of the host subcomponent. (groups.google.com)
Multiple independent vulnerability databases and vendor advisories list the CVE and the affected versions: Go versions prior to 1.25.8 (for the 1.25.x stream) and prior to 1.26.1 (for the 1.26.x stream) are vulnerable; the fixes are included in the point releases named above. Distributions such as Ubuntu and SUSE have created CVE records for the issue as they map upstream Go releases into distro packages.

Why this parsing bug matters​

URL parsing is deceptively important. Many security controls rely on consistent URL semantics across components:
  • Access/allow-lists and host-based gating often check the parsed host or hostname and make authorization decisions based on that canonical value.
  • SSRF protections and private-network filters rely on accurate detection of IPs (IPv4 or IPv6) to prevent requests to internal resources.
  • Proxy/no_proxy matching, reverse-proxy routing, and load balancer rules use host parsing to decide whether and how to forward a request.
  • Security filters that canonicalize hosts might run on one language/runtime while the actual backend runs on another — mismatches in parsing rules create windows for bypass.
Because net/url.Parse could accept malformed host strings by ignoring extraneous pre-bracket garbage, an attacker might craft an authority component that looks harmless to one validator but is interpreted differently by Go-based code that uses url.Parse (or vice versa). That mismatch is the classic recipe for SSRF bypasses, host-based access control bypasses, and surprising proxy selection results. (groups.google.com)

Technical analysis​

What the bug is, precisely​

Per the Go project’s description, the parser treated leading non-host characters before an IPv6 IP-literal as ignorable, allowing strings such as domain-like text immediately followed by a bracketed IPv6 literal to be parsed in a way that should have been rejected. The canonical expectation (per RFC 3986 and related URI grammar rules) is that when an IP-literal appears it should occupy the host field starting at the beginning of the host subcomponent; junk before that should make the whole authority invalid. The fix changes the parser to enforce that constraint. (groups.google.com)
A real-world reporter who disclosed the issue to the Go team explained the practical example: strings like example.com[::1] (domain-like characters immediately followed by an IPv6 literal) were accepted erroneously by url.Parse, which effectively ignored the garbage preceding the bracketed literal. This is the kind of input that should have been rejected. The issue credit is recorded to Masaki Hara (Wantedly) in the Go announcement.

Functions and code paths affected​

The published CVE / upstream metadata identifies a set of entry points and routines that relied on the vulnerable parsing behavior, including:
  • parseHost
  • JoinPath
  • Parse
  • ParseRequestURI
  • URL.Parse
  • URL.UnmarshalBinary
That list matters because it shows the bug is not limited to a single convenience entrypoint — the lower-level parsing primitives and serialization/deserialization paths are involved, increasing the number of call sites that can be impacted in user code and libraries.

Root cause and fix approach​

This is fundamentally an input validation / syntactic correctness problem: the parser accepted syntactically incorrect host components. The fix enforces stricter validation in the host subcomponent path so that an IPv6 IP-literal must appear at the start of the host string (or the host must otherwise be valid). The Go team released the corrected behavior as part of security point releases and documented it in the official release announcement for Go 1.26.1 and 1.25.8. (groups.google.com)

Realistic attack and abuse scenarios​

While CVE descriptions avoid giving adversaries a fresh recipe, defenders must model the ways this class of bug can be weaponized in practice. The most significant scenarios include:
  • SSRF and internal network discovery: If an application constructs outgoing requests using user-supplied URLs and relies on url.Parse to normalize or block private IPs, an attacker could supply a crafted authority that is parsed as an internal IPv6 address by one component but bypasses pre-checks performed earlier by a different parser or filter.
  • Host-based allow-list bypasses: Suppose a web application accepts callbacks only from allowed hosts (by checking the parsed hostname). If an upstream edge component or a pre-validation library uses a different parser, differences in host canonicalization can allow an attacker to send requests that appear to be from an allowed host to one component but are routed or interpreted as a different host by a Go-based backend.
  • Proxy/no_proxy mismatches and routing confusion: Tools and libraries that implement proxy bypass rules (no_proxy-style matching) need consistent host parsing. A malformed host that is accepted by Go code could trip rules that would otherwise have routed traffic differently or prevented connection to internal addresses.
  • Supply-chain and binary distribution impact: Many projects and services ship statically-linked Go binaries or containers with Go runtimes. A vulnerable Go standard library inside a produced binary cannot be patched without recompilation; attackers can target services that do not rebuild often. (groups.google.com)
These attack patterns are not purely theoretical: past parsing mismatches between languages (for example, between Python and Go URL parsers) have led to SSRF and host-based authorization bypasses. The essential problem is semantic inconsistency between components that share a protocol boundary.

Who is affected​

  • Any Go application or library that uses net/url.Parse, or that relies on the net/url package's host parsing behavior, and that uses Go versions older than 1.25.8 (1.25 series) or 1.26.1 (1.26 series) is potentially affected. This includes server-side code, CLI tools that process URLs, Go-based HTTP clients, proxies, and any software that serializes/deserializes URLs via URL.UnmarshalBinary or similar routines.
  • Distributions and packaged runtimes that shipped older Go binaries in their ecosystems (for example, vendor-provided images and OS packages) are impacted until they update the embedded Go runtime or rebuild with a fixed Go. Ubuntu, SUSE and other downstream trackers have already created advisory entries mapping the CVE to the distro package timelines. Administrators should check their distribution advisories and package indexes for updates.
  • Cloud services and SaaS vendors that incorporate third-party Go binaries, container images, or SDKs — especially if they accept or normalize user-supplied URLs — should consider themselves at risk until they have inventory and rebuilds completed.
Note: trying to determine whether a given compiled binary is affected purely by inspection can be difficult. The only reliable remediation is to rebuild binaries against a fixed Go toolchain or upgrade the Go runtime and libraries used to produce the artifact.

Detection: how to find vulnerable components in your environment​

No single detection technique will catch every case, but the following are practical, prioritized steps for incident responders and development teams:
  • Check local Go toolchains:
  • Run go version on build systems and CI runners; if a builder uses Go older than 1.25.8 or 1.26.1, mark it for upgrade.
  • Inspect dependency manifests and module trees:
  • Use go list -m all or scan go.mod / go.sum to find modules pinned to older toolchains or modules that vendor the standard library.
  • Scan package managers and OS images:
  • Query your distribution or image catalogs for packaged Go versions (e.g., Ubuntu, SUSE advisories). If a distro package ships an older Go, plan rebuilds or package updates.
  • For compiled artifacts:
  • When possible, correlate build metadata (e.g., embedded buildinfo, go.buildid, or other runtime tags) to identify the Go toolchain used. If that’s not available, treat statically built Go binaries as suspect and favor rebuilds.
  • Instrument runtime checks:
  • Add runtime validation that explicitly rejects malformed host subcomponents and enforces strict canonicalization before making sensitive routing or access decisions.
  • Log and hunt for suspicious patterns:
  • Hunt for incoming request hosts that include bracketed IPv6 parts preceded by unexpected characters (for example, strings resembling example.com[::1] or any authority with a bracketed IPv6 literal preceded by non-standard characters). These patterns are suspicious because well-formed hostnames do not combine domain names and bracketed IPv6 literals.
Where detection is incomplete, prioritize mitigation by patching and rebuilding rather than relying on uncertain telemetry.

Mitigation and remediation: concrete, prioritized steps​

  • Patch and rebuild: upgrade your build systems and CI to use Go 1.26.1 (or later) or Go 1.25.8 (or later for the 1.25.x stream). Rebuild all Go binaries and redeploy. This is the only guaranteed fix for compiled artifacts. (groups.google.com)
  • Update system packages and container images: apply distro updates where packages are provided (for example, Ubuntu and SUSE advisories) or replace base images with ones built using fixed Go versions. If a vendor provides a rebuild or repackaging, apply those updates promptly.
  • Harden URL validation at the application level:
  • Do not rely on a single parser’s default behavior when making authorization or network-policy decisions.
  • Implement strict host canonicalization and validation (whitelisting) where possible, and ensure that validation logic is the last check before a sensitive action, not the first check that other components can bypass.
  • Add targeted unit tests: create test cases that assert invalid inputs (e.g., domain + bracketed IPv6) are rejected. Run those tests in CI to prevent regressions. The Wantedly disclosure provides representative examples (e.g., example.com[::1]) that can be used to build negative tests.
  • Review proxy and no_proxy logic: verify that your proxy-selection logic canonicalizes hosts consistently, and do not trust edge filters alone to prevent internal calls if your application will ultimately perform its own URL parsing.
  • Monitor vendor and upstream advisories: the Go project and downstream vendors issued coordinated announcements. Subscribe to vendor security mailing lists or update feeds to avoid blind spots. (groups.google.com)

Vendor response and timeline​

  • The Go project publicly announced Go 1.26.1 and Go 1.25.8 as security point releases that include fixes for five CVEs, including CVE-2026-25679, in early March 2026. The announcement explicitly mentions the net/url fix and attributes the report to an external researcher. (groups.google.com)
  • The issue is tracked in the Go issue tracker as issue #77578; the upstream change(s) were landed through internal CLs and surfaced in the release artifacts. Public vulnerability metadata (OSV, OpenCVE, distro advisories) was created to map affected versions and the fixed releases. (go.dev)
  • Microsoft’s Security Response Center maintains an entry for the CVE at the URL you provided, but the public MSRC web interface requires client-side rendering (JavaScript) to view the page. If you tried to open the MSRC page directly via a headless fetch it returns a “You need to enable JavaScript to run this app” response, so defenders should view the MSRC advisory in a browser or rely on vendor-fed advisories to ensure they have Microsoft’s mapping for this CVE inside Microsoft product families. (I attempted to retrieve the MSRC page programmatically and encountered that rendering restriction.) (msrc.microsoft.com)
  • Downstream vendors including Ubuntu and SUSE have already catalogued the CVE and are mapping the fixed releases into their packaging workflows; downstream patch availability timelines will vary by distribution and package policy.

Risks and limitations of the available information​

  • The core technical narrative — that net/url.Parse accepted malformed host strings by ignoring preceding garbage before an IPv6 literal — is well-attested in the Go team announcement, the Go issue tracker, the OSV/CVE metadata, and the public disclosure from the reporter. The details of exploitability in production depend heavily on application architecture, how URLs flow through parsing/validation boundaries, and what additional safeguards are present (e.g., an upstream edge proxy that strips or rejects malformed host headers). Where an application performs its own canonicalization before calling net/url.Parse, the practical attackability may be lower. (groups.google.com)
  • The MSRC page you linked to is published and likely maps Microsoft product families to the CVE; however, programmatic retrieval of that page returned a JavaScript-required response. I recommend viewing the MSRC advisory in a browser to confirm Microsoft’s product mappings and any Microsoft-owned product guidance. Until that is validated in-browser, treat any MSRC claim you rely on as unverified by programmatic fetch. (msrc.microsoft.com)
  • For binary artifacts where build metadata is missing or obscured, determining whether a specific runtime is affected may be non-trivial. The conservative operational stance — rebuild with a patched Go toolchain and redeploy — is the safest path where accurate inventory is hard to obtain.

Practical checklist for engineering teams (quick-action list)​

  • Immediately update build servers and CI agents to Go 1.26.1 (or Go 1.25.8 if you’re on the 1.25.x line). Rebuild and redeploy all Go binaries. (groups.google.com)
  • Replace or rebuild base container images that include older Go runtimes. Regenerate images and redeploy.
  • Run unit-tests that assert malformed host strings are rejected (use examples such as domain+bracketed-IPv6 patterns in negative tests).
  • Add runtime canonicalization and host validation for any code path that makes auth or routing decisions based on parsed hostnames. Do not rely on third-party parsers without revalidating inputs. (groups.google.com)
  • Inventory third-party services, SDKs, plugins, and CI artifacts for statically linked Go binaries and plan rebuilds where necessary.
  • Monitor vendor advisories and subscribe to distro security feeds; apply distro or vendor-supplied patches as they become available.

Final analysis and takeaways​

CVE-2026-25679 is another reminder that parsing rules are security rules. When components disagree about how to interpret inputs — especially inputs as security-sensitive as hostnames and IPs — attackers can exploit the ambiguity. The vulnerability itself is modest in scope (a parsing rule in a widely used standard library), yet the consequences are outsized because of the role URL parsing plays in access control, routing, and SSRF defenses.
The positive aspects here are clear: the Go project responded with a focused fix, documented it publicly, and released point updates in a coordinated fashion; downstream vulnerability databases and distributions have catalogued the CVE; and developers have actionable remediation steps (upgrade toolchains, rebuild, and add defensive checks). (groups.google.com)
But the risk vector highlighted by this CVE is systemic: the software supply chain and the long tail of prebuilt binaries make it expensive and slow to fully eradicate such defects from production ecosystems. Any organization that relies on third-party Go binaries — including many cloud-native vendors and internal DevOps teams — should treat this as a “patch-and-validate” event: upgrade, rebuild, and validate behavior under realistic request flows.
If there’s one durable lesson, it is this: treat URL parsing as a security boundary. Canonicalize and validate close to the decision point, and do not assume that an upstream component’s notion of “valid” will match yours.

In short: CVE-2026-25679 is a legitimate, fixed parsing bug in Go’s net/url that deserves immediate attention from teams that build or ship Go binaries or that rely on Go-based URL parsing for security-sensitive decisions. Upgrade buildchains to Go 1.26.1 or Go 1.25.8, rebuild artifacts, and add strict URL/host validation to close parsing-related attack windows. (groups.google.com)

Source: MSRC Security Update Guide - Microsoft Security Response Center
 

Back
Top