CVE-2023-38497 Overview
CVE-2023-38497 is an Insecure Permissions vulnerability in Rust's Cargo package manager that affects how crate archives are extracted on UNIX-like systems. Cargo prior to version 0.72.2, bundled with Rust prior to version 1.71.1, did not respect the system umask when extracting crate archives. This oversight allows malicious crate authors to include files with world-writable permissions, which local attackers can then exploit to modify source code before compilation.
Critical Impact
Local attackers can exploit this vulnerability to modify source code in cached crate extractions, potentially injecting malicious code that gets compiled and executed by other users on the same system.
Affected Products
- Rust-lang Cargo versions prior to 0.72.2
- Rust versions prior to 1.71.1
- Fedora 38 (affected via bundled Cargo packages)
Discovery Timeline
- August 4, 2023 - CVE-2023-38497 published to NVD
- November 21, 2024 - Last updated in NVD database
Technical Details for CVE-2023-38497
Vulnerability Analysis
The vulnerability stems from Cargo's failure to apply the user's umask when extracting files from crate archives. On UNIX-like systems, the umask is a bitmask that determines the default permission bits that should be cleared when creating new files. By ignoring the umask, Cargo preserves whatever permissions are set in the source archive, including potentially dangerous world-writable permissions (0o777 or 0o666).
This creates a local privilege escalation scenario where a malicious crate author could craft a crate containing source files with overly permissive permissions. When a developer downloads and extracts such a crate, another local user on the same multi-user system could modify the extracted source code before it gets compiled. The modified code would then execute with the privileges of the original user who ran the build.
The vulnerability is tracked under CWE-278 (Insecure Preserved Inherited Permissions) and CWE-732 (Incorrect Permission Assignment for Critical Resource).
Root Cause
The root cause lies in Cargo's archive extraction logic in src/cargo/sources/registry/mod.rs. The extraction process did not query or apply the current user's umask value when writing files to the local cache directory (~/.cargo). This meant that file permissions embedded in crate archives were used directly, bypassing the system's intended permission restrictions.
Attack Vector
This is a local attack vector requiring the attacker to have local user access on the same system as the victim. The attack flow involves:
- An attacker publishes a malicious crate to crates.io (or a private registry) containing files with world-writable permissions
- A victim developer adds the crate as a dependency and runs cargo build or cargo fetch
- Cargo extracts the crate to ~/.cargo/registry/src/ preserving the world-writable permissions
- The local attacker modifies the extracted source files
- When the victim runs subsequent builds, the modified malicious code gets compiled and executed
The patch introduces a get_umask() function that properly retrieves and applies the system umask:
/// Get the current [`umask`] value.
///
/// [`umask`]: https://man7.org/linux/man-pages/man2/umask.2.html
#[cfg(unix)]
pub fn get_umask() -> u32 {
use std::sync::OnceLock;
static UMASK: OnceLock<libc::mode_t> = OnceLock::new();
// SAFETY: Syscalls are unsafe. Calling `umask` twice is even unsafer for
// multithreading program, since it doesn't provide a way to retrive the
// value without modifications. We use a static `OnceLock` here to ensure
// it only gets call once during the entire program lifetime.
*UMASK.get_or_init(|| unsafe {
let umask = libc::umask(0o022);
libc::umask(umask);
umask
}) as u32 // it is u16 on macos
}
Source: GitHub Cargo Commit Change
Detection Methods for CVE-2023-38497
Indicators of Compromise
- Files in ~/.cargo/registry/src/ with world-writable permissions (-rw-rw-rw- or -rwxrwxrwx)
- Unexpected modifications to source files in cached crate directories
- Discrepancies between crate source hashes and registry-published hashes
- File ownership changes in the Cargo cache directory
Detection Strategies
- Run find ~/.cargo -type f -perm -0002 to identify world-writable files in the Cargo cache
- Compare modification timestamps of cached crate files against their original download times
- Monitor file system events on the ~/.cargo/registry/src/ directory for unexpected write operations
- Audit Cargo version (cargo --version) across development environments to identify vulnerable installations
Monitoring Recommendations
- Implement file integrity monitoring (FIM) on developer workstations targeting the ~/.cargo directory
- Set up alerts for permission changes in Cargo cache directories on shared development servers
- Regularly audit installed Cargo/Rust versions in CI/CD pipelines and development environments
- Monitor for unusual build behavior or unexpected binary changes in compiled artifacts
How to Mitigate CVE-2023-38497
Immediate Actions Required
- Upgrade Rust to version 1.71.1 or later, which includes Cargo 0.72.2 with the security fix
- Run cargo build or cargo fetch after upgrading to trigger automatic purging of vulnerable cached extractions
- Restrict permissions on the ~/.cargo directory to prevent other local users from accessing it
- Audit existing crate caches for files with world-writable permissions
Patch Information
The vulnerability has been addressed in Cargo version 0.72.2, bundled with Rust 1.71.1. The fix implements proper umask handling during archive extraction and includes an automatic cache purge mechanism that removes potentially compromised cached extractions from older Cargo versions.
Detailed patch information is available in the GitHub Security Advisory GHSA-j3xp-wfr4-hx87 and the corresponding GitHub Cargo Pull Request.
Fedora users should apply the relevant package updates announced via the Fedora Package Announcement.
Workarounds
- Set restrictive permissions on the Cargo directory: chmod 700 ~/.cargo
- Remove existing cached crates: rm -rf ~/.cargo/registry/src/
- On shared systems, ensure the user's home directory is not accessible by other users
- Consider using containerized build environments to isolate development dependencies
# Configuration example
# Secure Cargo directory permissions
chmod 700 ~/.cargo
# Remove potentially compromised cache
rm -rf ~/.cargo/registry/src/
# Verify Cargo version after upgrade
cargo --version # Should show 0.72.2 or later
# Scan for world-writable files in Cargo cache
find ~/.cargo -type f -perm -0002 -ls
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

