On Windows, when the target of Root.Mkdir or Root.MkdirAll is a junction pointing to an empty location, the operation can create a directory at the junction target even when that target is located outside the root. This only applies to operations where the last path component is a junction (path/to/junction, but not path/junction/target).
Credentials provided via the new GOAUTH feature were not being properly segmented by domain, allowing a malicious server to request credentials they should not have access to. By default, unless otherwise set, this only affected credentials stored in the users .netrc file.
The go command may execute unexpected commands when operating in untrusted VCS repositories. This occurs when possibly dangerous VCS configuration is present in repositories. This can happen when a repository was fetched via one VCS (e.g. Git), but contains metadata for another VCS (e.g. Mercurial). Modules which are retrieved using the go command line, i.e. via "go get", are not affected.
Checksum database bypass for golang.org/toolchain in cmd/go
Memory limit bypass when parsing MIME headers in net/textproto, mime/multipart
Historically, we have been rather lax about malformed framing-related headers in our HTTP/2 implementation, as they cannot interfere with HTTP/2 framing. However, this makes it possible for our HTTP/2 implementation to forward responses containing such headers to an HTTP/1 client when acting as a reverse proxy. If the HTTP/1 client also does not behave strictly enough, this can result in response smuggling.
Cancelling a query (e.g. by cancelling the context passed to one of the query methods) during a call to the Scan method of the returned Rows can result in unexpected results if other queries are being made in parallel. This can result in a race condition that may overwrite the expected results with those of another query, causing the call to Scan to return either unexpected results from the other query or an error.
The go command may execute unexpected commands when operating in untrusted VCS repositories. This occurs when possibly dangerous VCS configuration is present in repositories. This can happen when a repository was fetched via one VCS (e.g. Git), but contains metadata for another VCS (e.g. Mercurial). Modules which are retrieved using the go command line, i.e. via "go get", are not affected.
On Unix systems, opening a file in an os.Root improperly follows symlinks to locations outside of the Root when the final path component of the a path is a symbolic link and the path ends in /. For example, 'root.Open("symlink/")' will open "symlink" even when "symlink" is a symbolic link pointing outside of the root.
When parsing a Range header containing a large number of small ranges, FileServer(FS), ServeContent, and ServeFile(FS) can consume an excessive amount of CPU.
A malicious GOPROXY was previously capable of forging up to two sumdb tiles that allow for a requested module to bypass the GOSUMDB check and persist attacker-controlled module content to a local Go module cache. This attack allows for a malicious GOPROXY to serve malicious module content that cannot be detected by evaluating the transparency log. All tiles are now correctly verified against their parents. In order to determine if you have been affected: rm -r go.sum go.work.sum vendor/ && go mod tidy
If the PATH environment variable contains paths which are executables (rather than just directories), passing certain strings to LookPath ("", ".", and ".."), can result in the binaries listed in the PATH being unexpectedly returned.
Arbitrary code execution during build on Darwin in cmd/go
A trusted template author may have previously written a valid template wherein the use of the 'yield' keyword would not be correctly escaped. We now ensure that valid keyword uses are escaped and non-keyword uses are not escaped.
CR/LF bytes were not rejected by HTTP client proxy tunnel headers or host.
Despite HTTP headers having a default limit of 1MB, the number of cookies that can be parsed does not have a limit. By sending a lot of very small cookies such as "a=;", an attacker can make an HTTP server allocate a large amount of structs, causing large memory consumption.
SSH Agent servers do not validate the size of messages when processing new identity requests, which may cause the program to panic if the message is malformed due to an out of bounds read.
Handshakes which used Encrypted Client Hello could be de-anonymized by a passive network observer due to a disclosure of pre-shared key identities in the unencrypted client hello.
Calling Parse on a "// +build" build tag line with deeply nested expressions can cause a panic due to stack exhaustion.
The HTTP client drops sensitive headers after following a cross-domain redirect. For example, a request to a.com/ containing an Authorization header which is redirected to b.com/ will not send that header to b.com.
In the event that the client received a subsequent same-domain redirect, however, the sensitive headers would be restored. For example, a chain of redirects from a.com/, to b.com/1, and finally to b.com/2 would incorrectly send the Authorization header to b.com/2.
The compiler is meant to unwrap pointers which are the operands of a memory move; a no-op interface conversion prevented the compiler from making the correct determination about non-overlapping moves, potentially leading to memory corruption at runtime.
The Dial and LookupPort functions panic on Windows when provided with an input containing a NUL (0).
The Migration Toolkit for Containers (MTC) enables you to migrate Kubernetes resources, persistent volume data, and internal container images between OpenShift Container Platform clusters, using the MTC web console or the Kubernetes API.Security Fix(es) from Bugzilla: webpack-dev-middleware: lack of URL validation may lead to file leak (CVE-2024-29180) golang: net/http: memory exhaustion in Request.ParseMultipartForm (CVE-2023-45290) golang: crypto/x509: Verify panics on certificates with an unknown public key algorithm (CVE-2024-24783) golang: net/mail: comments in display names are incorrectly handled (CVE-2024-24784) golang: html/template: errors returned from MarshalJSON methods may break template escaping (CVE-2024-24785) envoy: HTTP/2 CPU exhaustion due to CONTINUATION frame flood (CVE-2024-30255) For more details about the security issue(s), including the impact, a CVSS score, and other related information, refer to the CVE page(s) listed in the References section.
End of life: 2/10/2026, Latest version: 1.24.13
End of life: 8/19/2026, Latest version: 1.25.14
https://groups.google.com/g/golang-announce/c/0uYbvbPZRWU announces: We have just released Go versions 1.26.2 and 1.25.9, minor point releases.
These releases include 10 security fixes following the security policy:
os: Root.Chmod can follow symlinks out of the root on Linux
On Linux, if the target of Root.Chmod is replaced with a symlink while the chmod operation is in progress, Chmod could operate on the target of the symlink, even when the target lies outside the root.
The Linux fchmodat syscall silently ignores the ATSYMLINKNOFOLLOW flag, which Root.Chmod uses to avoid symlink traversal. Root.Chmod checks its target before acting and returns an error if the target is a symlink lying outside the root, so the impact is limited to cases where the target is replaced with a symlink between the check and operation.
On Linux, Root.Chmod now uses the fchmodat2 syscall when available, and an workaround using /proc/self/fd otherwise.
Thanks to Uuganbayar Lkhamsuren for reporting this issue.
This is CVE-2026-32282 and Go issue https://go.dev/issue/78293.
html/template: JS template literal context incorrectly tracked
Context was not properly tracked across template branches for JS template literals, leading to possibly incorrect escaping of content when branches were used.
Additionally template actions within JS template literals did not properly track the brace depth, leading to incorrect escaping being applied.
These issues could cause actions within JS template literals to be incorrectly or improperly escaped, leading to XSS vulnerabilities.
This only affects templates that use template actions within JS template literals.
This is CVE-2026-32289 and Go issue https://go.dev/issue/78331.
crypto/x509: excluded DNS constraints not properly applied to wildcard domains
When verifying a certificate chain containing excluded DNS constraints, these constraints are not correctly applied to wildcard DNS SANs which use a different case than the constraint.
For example, if a certificate contains the DNS name ".example.com" and the excluded DNS name "EXAMPLE.COM", the constraint will not be applied.
This only affects validation of otherwise trusted certificate chains, issued by a root CA in the VerifyOptions.Roots CertPool, or in the system certificate pool.
This issue only affects Go 1.26.
Thank you to Riyas from Saintgits College of Engineering, k1rnt, @1seal for reporting this issue.
This is CVE-2026-33810 and Go issue https://go.dev/issue/78332.
cmd/compile: no-op interface conversion bypasses overlap checking
Previously, the compiler failed to unwrap pointers contained within a no-op interface conversion leading to an incorrect determination of a non-overlapping move.
To prevent unsafe move operations, the compiler will now unwrap all such conversions before considering a move non-overlapping.
Thank you to Jakub Ciolek - https://ciolek.dev/ for reporting this issue.
This is CVE-2026-27144 and Go issue https://go.dev/issue/78371.
cmd/compile: possible memory corruption after bound check elimination
Previously, slices and arrays accessed using induction variables were sometimes incorrectly proved in-bound. If the induction variable used for indexing were to overflow or underflow, it could allow access to memory beyond the scope of the original slice or array.
To prevent this behavior, the compiler ensures that any mutated induction variable that overflows/underflows with respect to its loop condition is not used for bound check elimination.
Thank you to Jakub Ciolek - https://ciolek.dev/ for reporting this issue.
This is CVE-2026-27143 and Go issue https://go.dev/issue/78333.
archive/tar: unbounded allocation when parsing old format GNU sparse map
tar.Reader could allocate an unbounded amount of memory when reading a maliciously-crafted archive containing a large number of sparse regions encoded in the "old GNU sparse map" format.
We now limit both the number of old GNU sparse map extension blocks, and the total number of sparse file entries, regardless of encoding.
Thanks to Colin Walters (wal... () verbum org) who initially reported this issue. Thanks also to Uuganbayar Lkhamsuren (https://github.com/uug4na) and Jakub Ciolek who additionally reported this issue.
This is CVE-2026-32288 and Go issue https://go.dev/issue/78301.
crypto/tls: multiple key update handshake messages can cause connection to deadlock
If one side of the TLS connection sends multiple key update messages post-handshake in a single record, the connection can deadlock, causing uncontrolled consumption of resources. This can lead to a denial of service.
This only affects TLS 1.3.
Thank you to Jakub Ciolek - https://ciolek.dev/ for reporting this issue.
This is CVE-2026-32283 and Go issue https://go.dev/issue/78334.
cmd/go: trust layer bypass when using cgo and SWIG
A well-crafted SWIG source file could take advantage of a file-naming convention used inside the trust boundary of the cgo compiler. Doing so could result in arbitrary code execution during build time.
SWIG files are disallowed from using this convention.
Thank you to Juho Forsén of Mattermost for reporting this issue.
This is CVE-2026-27140 and Go issue https://go.dev/issue/78335.
crypto/x509: unexpected work during chain building
During chain building, the amount of work that is done is not correctly limited when a large number of intermediate certificates are passed in VerifyOptions.Intermediates, which can lead to a denial of service. This affects both direct users of crypto/x509 and users of crypto/tls.
Thank you to Jakub Ciolek - https://ciolek.dev/ for reporting this issue.
This is CVE-2026-32280 and Go issue https://go.dev/issue/78282.
crypto/x509: inefficient policy validation
Validating certificate chains which use policies is unexpectedly inefficient when certificates in the chain contain a very large number of policy mappings, possibly causing denial of service.
This only affects validation of otherwise trusted certificate chains, issued by a root CA in the VerifyOptions.Roots CertPool, or in the system certificate pool.
Thank you to Jakub Ciolek - https://ciolek.dev/ for reporting this issue.
This is CVE-2026-32281 and Go issue https://go.dev/issue/78281.
View the release notes for more information: https://go.dev/doc/devel/release#go1.26.2
You can download binary and source distributions from the Go website: https://go.dev/dl/
To compile from source using a Git clone, update to the release with git checkout go1.26.2 and build as usual.
Thanks to everyone who contributed to the releases.
Cheers, David and Junyang for the Go team
On Wed, Apr 08, 2026 at 04:24:34PM -0700, Alan Coopersmith wrote: https://groups.google.com/g/golang-announce/c/0uYbvbPZRWU announces: We have just released Go versions 1.26.2 and 1.25.9, minor point releases.
These releases include 10 security fixes following the security policy: This includes 2 issues in the compiler itself, which made some Go programs not memory safe: cmd/compile: no-op interface conversion bypasses overlap checking
Previously, the compiler failed to unwrap pointers contained within a no-op interface conversion leading to an incorrect determination of a non-overlapping move.
To prevent unsafe move operations, the compiler will now unwrap all such conversions before considering a move non-overlapping.
Thank you to Jakub Ciolek - https://ciolek.dev/ for reporting this issue.
This is CVE-2026-27144 and Go issue https://go.dev/issue/78371.
cmd/compile: possible memory corruption after bound check elimination
Previously, slices and arrays accessed using induction variables were sometimes incorrectly proved in-bound. If the induction variable used for indexing were to overflow or underflow, it could allow access to memory beyond the scope of the original slice or array.
To prevent this behavior, the compiler ensures that any mutated induction variable that overflows/underflows with respect to its loop condition is not used for bound check elimination.
Thank you to Jakub Ciolek - https://ciolek.dev/ for reporting this issue.
This is CVE-2026-27143 and Go issue https://go.dev/issue/78333. Jakub Ciolek who found these 2 issues (and had inadvertently introduced "the underlying issue behind the first bug [...] more than three years earlier") posted an excellent write-up about them here:
https://ciolek.dev/posts/when-the-compiler-lies
Here's my quick attempt at a plain text conversion: When the compiler lies: breaking memory safety in safe Go 0001 go / memory safety / compilers
Early in March, I reported two compiler bugs affecting Go releases up to 1.26.1 which broke the Go memory safety guarantees using only safe Go code.
This means the proof-of-concepts did not import unsafe, did not use CGO and did not rely on custom assembly nor data races. Using specially constructed code, I was able to turn both bugs into control-flow hijack, and with the loop bug I also got execution of injected instructions.
I’m not including the full end-to-end exploits, to allow the fixed releases to become more widely available. I’ll briefly describe the issues and show the problematic code patterns though. An interesting learning from this, perhaps obvious to some people, is that memory safety is a property of the whole toolchain, not only the language itself.
I found the bugs after I decided to have a closer look at the compiler. I had reported several denial-of-service issues in the standard library before. I have spent a few years contributing smaller patches to the compiler on-and-off so it was a codebase I understood reasonably well. In late November I found two errors in the devel version of the prove optimization pass (the step that infers limits and “proves” facts about SSA values, among others to perform bounds check elimination).
If you exclude the generated rewrite tables, prove is basically the second largest backend SSA optimization pass, behind only the register allocator itself. It also deals with arithmetic and signedness, two easy ways to shoot yourself in the foot. It turned out, the hunch was correct as there were more problems lurking in that area. This time in the release versions of Go.
BUG 1: A LOOP THAT WRAPPED AND THE COMPILER SWORE IT DIDN’T
CVE-2026-27143
The first problem existed in the prove/loopbce reasoning about induction variables and bound checks.
The triggering shape is surprisingly simple:
for i := int8(0); i <= int8(120); i += int8(10) { arr[i] = value }
Question to you: if i == 120 and you perform the iteration, then add 10 to it, what will you get? What’s the answer? 130? It turns out the answer is -126. int8 has eight bits, it wraps.
That’s literally the whole bug. The compiler believed something different though.
If you make prove emit debug data, these are the facts it inferred:
Induction variable: limits [0,120], increment 10 Proved IsInBounds
Once it takes those facts, it will confidently remove bound checking for array access if the array size fits within the induction variable limits. In this case, the index can become negative. With correct arrangement of surrounding code, we can make the program jump to an arbitrary address, change control flow or even inject instructions.
I must admit I could not believe this at first and reran the program many times on different machines and different versions of the compiler. Vulnerability hunting gives a large thrill when you finally confirm something is a real security bug. When I found it, I was really ecstatic, as bad as it sounds. That feeling would change soon, but more about that later.
BUG 2: A NO-OP CONVERSION THAT CHANGED NOTHING AND BROKE EVERYTHING
CVE-2026-27144
The second problem lived in another place, slightly later, in the SSA lowering phase. The compiler knows to be careful when copying from one part of an array into an overlapping nearby part. This is important for safety. It turns out, if you wrapped the source into a conversion that didn’t really change anything, the compiler forgot to do that.
type T [N][]uint64
// buggy shape p = T(q)
// control shape p = q
Those two lines should mean the same thing here. The conversion does not really matter, the overlap does. p and q can point at partially overlapping windows of the same underlying array. Once that is true, the compiler should use the careful copy path. If it does not do that, it can overwrite data it has not read yet. If you do that over simple data, you get a wrong result. If you do that over more complex composite values it gets more interesting. If you do that to slice values, later code still trusts the result. A harmless-looking assignment then turns into memory corruption.
TWO DISTINCT PROBLEMS, BUT REALLY THE SAME CAUSE
Those two bugs resided in two different parts of the compiler, but the root cause was the same. In the first case, the compiler erased the possibility of signed wrap. In the second one, it excluded the possibility of overlap.
Those were two different mechanisms of failure, but both caused by the same problem: counterfeit certainty. I guess that’s how compilers break, you can write some compiler code and it looks reasonable, there’s math and tests and everything seems correct. Things get reviewed by multiple people and merged, but it turns out you may accidentally upgrade “probably safe” into “proved safe” way too soon.
Then, once the compiler starts to generate and optimize code based on that promise, it will miscompile. Sometimes, like in those cases, you can make the code dance around it and break security boundaries.
THEN GIT BLAME GOT PERSONAL
As I was wrapping up the email to the Go security team, I sat down to write the last part of the advisory. I was still ecstatic about the find. The final part was to figure out when this was introduced. I did the routine thing and ran git blame.
It came back with my own name. That was not ideal and I did not like it. I got a sinking feeling in my stomach and went from feeling really smart to feeling really dumb, real fast.
It turns out that the underlying issue behind the first bug came from a CL I landed more than three years earlier.
I got over it by the next day and now see it as an amusing story, but it was quite an experience.
DISCLOSURE
I reported both issues back in March.
I must commend the Go security team as they are always excellent. Neal got back to me within 3 minutes of the first report and within 4 minutes of the second report. Mind you, those were sent days apart. Typically, the Go security advisories take up to a week to get a response. I guess seeing “memory corruption” and “compiler bug” in the same email thread speeds the process up.
I’ll publish the full minimized reproducers, deeper technical dive and more once the fixed releases become more broadly available.
LEARNINGS
The main learning for myself is that a memory-safe language is only as safe as the entire toolchain enforcing its invariants. Frontend, optimizer, lowering, runtime and code generation. All of those parts sit within the trust boundary. If parts of it start certifying wrong proofs and generating code on top of that, the source code can stay safe while the compiled program stops being memory-safe.
Every optimization is a security claim and most of the time those claims are true. In this case, those two were not.
STATUS
Disclosure in progress
Full end-to-end exploits and minimized reproducers are intentionally omitted until the fixed releases are more widely available.
AFFECTED
Two compiler bugs affecting release versions of Go up to 1.26.1. Alexander
On Fri, Apr 10, 2026 at 04:58:03AM +0200, Solar Designer wrote: On Wed, Apr 08, 2026 at 04:24:34PM -0700, Alan Coopersmith wrote: https://groups.google.com/g/golang-announce/c/0uYbvbPZRWU announces: We have just released Go versions 1.26.2 and 1.25.9, minor point releases.
These releases include 10 security fixes following the security policy: This includes 2 issues in the compiler itself, which made some Go programs not memory safe: ...
I did not see any Linux distribution advisories for compiled Go programs yet, but some projects using Go have released upates:
- https://rclone.org/changelog/#v1-73-4-2026-04-08 Update to go 1.25.9 to fix multiple CVEs
- https://github.com/grafana/grafana/releases/tag/v12.4.3 2026-04-14: Go: Update to 1.25.9
I looked at https://github.com/gopasspw/gopass and https://github.com/restic/restic, but they have not yet issued updated releases.
Perhaps the message did not spread wide enough. Or are many Go programs just not affected?
Matthias
Eli Schwartz <eschwartz () gentoo org> writes: On 4/17/26 6:30 AM, Matthias Ferdinand wrote: On Fri, Apr 10, 2026 at 04:58:03AM +0200, Solar Designer wrote: On Wed, Apr 08, 2026 at 04:24:34PM -0700, Alan Coopersmith wrote: https://groups.google.com/g/golang-announce/c/0uYbvbPZRWU announces: We have just released Go versions 1.26.2 and 1.25.9, minor point releases.
These releases include 10 security fixes following the security policy: This includes 2 issues in the compiler itself, which made some Go programs not memory safe: ...
I did not see any Linux distribution advisories for compiled Go programs yet, but some projects using Go have released upates:
- https://rclone.org/changelog/#v1-73-4-2026-04-08 Update to go 1.25.9 to fix multiple CVEs
- https://github.com/grafana/grafana/releases/tag/v12.4.3 2026-04-14: Go: Update to 1.25.9
I looked at https://github.com/gopasspw/gopass and https://github.com/restic/restic, but they have not yet issued updated releases.
Perhaps the message did not spread wide enough. Or are many Go programs just not affected? Updated releases don't really make sense, generically. The bug is in the compiler, not the package, so one would rebuild the existing release with a new compiler. Consider how you handle this if a package had a security vulnerability in the GCC version it was compiled in. Or, it depended on libarchive and libarchive had a security release. Do you tag a brand new version of rclone because the dependencies it was compiled against got updated? No. Well, given gomodules or rust crate locking, maybe, because those are "vendored libraries", but that is a bug in both of those languages. :)
If I look at rclone, I see they only updated go 1.25.9 in the CI workflow that builds precompiled binaries and attaches them as github releases assets. The actual rclone release was noteworthy more for fixing a denial of service that required pulling in a newer version of a vendored library. For serious issues, it may make sense for projects distributing binaries (provided they know it was built by a buggy compiler) in the same way they might do for a vulnerable OpenSSL DLL in their Windows offering.
But yes, I agree, it'd be pretty annoying if every Go piece of software issued a new release that was a no-op and was just there to nudge you to rebuild it. On the compiler side of things, Gentoo Linux policy is to offer a standard approach to rebuilding all packages that use golang:
$ emerge @golang-rebuild
which should be run after all golang updates that one suspects deserve a global rebuild. Likely all golang updates because Reasons(tm). This is just the name of the game when installing golang software -- the usual rule of thumb is to assume all golang releases contain CVEs that need fixing. It is regular like clockwork, so do people really need an invitation to do so? Right, the stdlib case is pretty common. Other distros should be bumping the build number and recompiling the package in place, using the same infrastructure otherwise used for things like rebuilding ten thousand packages against a new major edition of perl or python or ruby.
IIRC it is possible to determine which packages actually need rebuilding for any given CVE, but to do so you need to locally extract the entire recursive deps-included source code of every package, and run some arcane undocumented go .... invocation. Functionally, what you're doing is checking which programs link to an internal static library distributed with the go compiler. (This is not exactly correct, but it is a useful mental model.) sam