Go is known for its robust standard library, especially its file path manipulation packages. However, even tried-and-true libraries can hide critical security flaws. CVE-2022-29804 is one such vulnerability that affected many Go developers, making their applications susceptible to directory traversal attacks on Windows. If you use Go's path/filepath.Clean function and missed this advisory, read on to understand how simple path cleaning could have exposed your application's files, how it worked, and how to fix it.
What Is CVE-2022-29804?
CVE-2022-29804 describes an issue in Go's path/filepath.Clean function before versions 1.17.11 and 1.18.3 on Windows. Because of an incorrect conversion, certain invalid paths could be cleaned and converted to a valid, absolute path. This in turn could allow attackers to perform directory traversal — that is, to access directories and files outside of the intended root folder.
This issue only impacts Go applications running on Windows that depend on user-supplied paths and rely on the filepath.Clean function for path safety.
Official Security Advisory
- Go's security release notes
- GitHub security advisory
- NVD entry for CVE-2022-29804
Why Is Directory Traversal Dangerous?
Directory traversal bugs let attackers access files outside a designated directory. Even with path cleaning or validation, subtle bugs like this one can bypass those protections. Malicious users could steal configuration files, sensitive data, or even tamper with server operations by writing where they shouldn't.
Technical Breakdown: How Did This Happen?
Go's standard library provides the path/filepath.Clean function to canonicalize a path, removing .. (parent directory) and . (current directory), and converting things like backslashes and forward slashes.
In affected Go versions, cleaning certain malformed *relative* paths on Windows led to the function returning an *absolute* Windows path. For example, on Windows systems, filePath.Clean(" C:/windows\system32/.. ") would return the absolute root-based path rather than catching it as invalid. This could lead to traversing out of intended directories.
Let's see a simple code snippet demonstrating the issue
package main
import (
"fmt"
"path/filepath"
)
func main() {
input := "C:../Windows/System32"
cleaned := filepath.Clean(input)
fmt.Printf("Original Path: %q\n", input)
fmt.Printf("Cleaned Path: %q\n", cleaned)
}
Output (on Windows, vulnerable Go version)
Original Path: "C:../Windows/System32"
Cleaned Path: "C:\Windows\System32"
The cleaning here converts what would have been an invalid path into a valid, absolute one!
If you then joined this to a base directory, or compared it with a hardcoded "allowed" root, you could accidentally allow the cleaned path to reach outside your application's intended directory.
Exploit Scenario: How Could an Attacker Abuse This?
Suppose you run a Go web server allowing users to download files from C:\MyApp\files\. You try to sanitize user input like this:
safeRoot := "C:\\MyApp\\files"
userInput := "../Windows/System32/drivers/etc/hosts"
path := filepath.Clean(filepath.Join(safeRoot, userInput))
// Open or serve file "path"
On a vulnerable Go, if userInput is C:../Windows/System32/drivers/etc/hosts, after cleaning and joining, it can point directly to the system's hosts file:
// filepath.Join("C:\\MyApp\\files", "C:../Windows/System32/drivers/etc/hosts")
// On Windows, would resolve to: C:\Windows\System32\drivers\etc\hosts
Malicious users could thus access critical files well outside your intended directory.
Fix and Mitigation
Are you using Go 1.17.11 / 1.18.3 or later?
If not, update your Go installation immediately.
- Download the latest stable Go: https://go.dev/dl/
Workarounds
- Always check if resulting paths are within your allowed directory using absolute path comparison. Example:
root := "C:\\MyApp\\files"
user := userSuppliedPath
cleaned := filepath.Clean(user)
absPath := filepath.Join(root, cleaned)
absRoot, _ := filepath.Abs(root)
absRequest, _ := filepath.Abs(absPath)
if !strings.HasPrefix(absRequest, absRoot) {
// Potential traversal attempt!
return error
}
Key Takeaways
- CVE-2022-29804 is a serious bug in the way Go's filepath.Clean worked on Windows, enabling directory traversal.
- Always stay updated with security releases: Go's Security Releases
- Rely on defense-in-depth: combine path cleaning, strict whitelisting, and after-clean absolute path checks.
References
- Official Go Security Advisory (go.dev)
- National Vulnerability Database CVE-2022-29804
- Relevant Go commit and patch
Have you audited your Go applications for hidden directory traversal bugs? If not, now's the time to act!
Timeline
Published on: 08/10/2022 20:15:00 UTC
Last modified on: 08/15/2022 17:07:00 UTC