-----
Overview
*In June 2024, a significant security vulnerability (CVE-2024-35186) was disclosed in gitoxide, a fast, pure Rust implementation of Git. This vulnerability impacts the core gix-worktree-state component and exposes users to serious risks, including the potential to corrupt files outside the intended repository directory — a classic path traversal flaw.*
In this long read, we’ll break down what happened, why it’s dangerous, how attackers can exploit it, and what you need to do to stay safe. Technical code snippets and links to original references are included so you get the full picture.
What Is gitoxide?
gitoxide is an open-source Git implementation written in Rust, often praised for efficiency and safety. Its users include developers seeking a robust replacement for the original C-based Git implementations.
What Is gix-worktree-state?
The gix-worktree-state is a subcomponent responsible for managing and checking out files into the working directory when you clone or check out a repository. This module should always make sure any file paths in a repository stay within the repository — or “working tree” — directory.
Technical Summary
ID: CVE-2024-35186
Component: gitoxide, specifically gix-worktree-state
Impact: Files can be written anywhere writable by the application during checkout, not just the repository folder.
Exploit Mechanism
When cloning a repository, git-based tools like gitoxide read file paths from the repository’s index or tree and write those files into the local working directory. This is supposed to be strictly within the working tree.
In versions of gitoxide before v.36., gix-worktree-state failed to adequately check if file paths in the repository stayed within this folder. That means malicious repositories can use paths like ../../outside.txt to write files outside the intended checkout, potentially overwriting sensitive data or dropping additional files on the filesystem.
Suppose a malicious actor creates a repository with the following tree
tree
|-- README.md
|-- ../evil.txt
|-- subdir/../../steal.txt
When a victim clones this repository using a vulnerable gitoxide-based tool, these files may be written at:
- <REPO>/README.md
- <PARENT_DIR>/evil.txt
- <REPO>/subdir/../../steal.txt → resolves to <REPO>/steal.txt, but if crafted badly, could go higher
Or, more dangerously, to any directory the current user has write access to.
Result: The attacker writes files wherever he wants, not just inside your repo.
A crafted Git blob might contain
tree 41269bab202b3bf8822e1c89b71451e1d2ffcc8c
100644 blob 5874beb436e1bde868b7107dd7aaadf8c021072e ../../tmp/hacked.txt
If unchecked, gix-worktree-state will write out hacked.txt in /tmp/.
Here’s a simplified ("pseudo-Rust") example of what went wrong
use std::fs::File;
use std::path::Path;
fn checkout_entry(repo_dir: &str, path_in_repo: &str, data: &[u8]) {
let complete_path = Path::new(repo_dir).join(path_in_repo);
// BAD: No check that complete_path is INSIDE repo_dir!
let mut file = File::create(&complete_path).unwrap();
file.write_all(data).unwrap();
}
The fix involves checking that complete_path does not, after canonicalization, leave repo_dir
use std::fs::File;
use std::path::{Path, PathBuf};
fn checkout_entry(repo_dir: &str, path_in_repo: &str, data: &[u8]) {
let repo_path = Path::new(repo_dir).canonicalize().unwrap();
let complete_path = repo_path.join(path_in_repo).canonicalize().unwrap();
// FIX: Check that complete_path starts_with repo_path
if !complete_path.starts_with(&repo_path) {
panic!("Refused to write outside of the working tree!");
}
let mut file = File::create(&complete_path).unwrap();
file.write_all(data).unwrap();
}
Attack Scenarios
- Overwriting system/user files if the repo is cloned as root or with sufficient privileges.
Denial of Service (DoS) by corrupting system or user data.
Note: No direct remote code execution, but files dropped outside the repo might later be executed accidentally.
The Fix
This vulnerability is fixed in gitoxide v.36., released June 5, 2024.
> "Paths are now strictly verified to be within the repository worktree before any file operations are executed."
> — Upstream commit message
Upgrade immediately if you use gitoxide as a library or tool in your production or CI/CD pipelines.
References
- CVE Report on NVD
- gitoxide commit diff (.36.)
- Upstream Issue Tracker
- Official Release Changelog
Upgrade all gitoxide-based applications or dependencies to at least version .36..
2. If you maintain your own Git tools using the gix-worktree-state, audit your code for similar path traversal checks.
3. Don't clone untrusted repositories with any Git client, but beware that this bug made even cloned *trusted* repos more dangerous.
Conclusion
*CVE-2024-35186 is a sobering reminder that file path validation is critical, even in modern, memory-safe languages like Rust. Always make sure file operations are confined to intended directories!*
Be safe, and keep your tools up to date.
*Written June 2024. For the latest security news, follow the gitoxide repo and RustSec. If you found this helpful, share with your dev team!*
Timeline
Published on: 05/23/2024 09:15:09 UTC
Last modified on: 06/04/2024 17:34:36 UTC