Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2023-38497

CVE-2023-38497: Rust-lang Cargo Privilege Escalation Flaw

CVE-2023-38497 is a privilege escalation vulnerability in Rust-lang Cargo that allows local users to modify source code during crate extraction. This article covers technical details, affected versions, and mitigation.

Published:

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:

  1. An attacker publishes a malicious crate to crates.io (or a private registry) containing files with world-writable permissions
  2. A victim developer adds the crate as a dependency and runs cargo build or cargo fetch
  3. Cargo extracts the crate to ~/.cargo/registry/src/ preserving the world-writable permissions
  4. The local attacker modifies the extracted source files
  5. 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:

rust
/// 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
bash
# 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.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.