CVE-2026-46383: Root-cause Tar Extraction Path Validation for Windows TarSlip
Summary
The patch addresses a Windows-specific TarSlip/arbitrary file overwrite issue in Microsoft APM by validating tar member names before extraction in both the legacy bundle probe and the unpacker. It adds explicit rejection of absolute Unix paths, Windows drive-qualified paths, Windows absolute paths, and traversal segments via shared path validation, plus regression tests for these cases. Based on the provided diff, the fix appears to correct the underlying trust boundary failure rather than only blocking a single payload shape.
Analysis
Vulnerability
CVE-2026-46383 is an arbitrary file overwrite issue in Microsoft APM before 0.13.0 on Windows during tar archive extraction. The vulnerable behavior is consistent with TarSlip: archive member names were trusted and passed into extraction logic without sufficient normalization and boundary enforcement, allowing crafted entries to escape the intended destination and overwrite attacker-chosen files when a user installs a malicious tarball. The advisory and CVE context are documented in the GHSA advisory, NVD record, and CVE record.
The patch diff shows two relevant vulnerable patterns. In src/apm_cli/bundle/local_bundle.py, the code performed a direct tar.extractall(tmp) during legacy bundle probing. In src/apm_cli/bundle/unpacker.py, the prior checks were too narrow, relying on conditions like member.name.startswith("/") or ".." in member.name. That approach is insufficient on Windows because drive-qualified and other absolute Windows path forms can bypass Unix-centric checks.
tar.extractall(tmp) # noqa: S202
if member.name.startswith("/") or ".." in member.name:
raise ValueError(f"Refusing to extract path-traversal entry: {member.name}")The root cause is incomplete validation of archive member paths across platform-specific path syntaxes before extraction. In particular, Windows absolute paths such as D:/evil/payload.txt and UNC-like forms such as //server/share/payload.txt were not comprehensively rejected by the earlier logic, enabling writes outside the extraction root.
Patch
The patch in commit 77d1dda8303c8d7ccb6148788a6274fdece98499 strengthens validation in both extraction-related paths.
First, the legacy bundle probe in local_bundle.py now validates each tar member name before calling extractall. It rejects:
- Unix absolute paths via
name.startswith("/") - Windows drive-qualified paths via
PureWindowsPath(name).drive - Windows absolute paths via
PureWindowsPath(name).is_absolute() - Traversal segments via shared
validate_path_segments(...)raisingPathTraversalError
name = member.name
if (
name.startswith("/")
or PureWindowsPath(name).drive
or PureWindowsPath(name).is_absolute()
):
return False
try:
validate_path_segments(name, context="tar member")
except PathTraversalError:
return False
tar.extractall(tmp) # noqa: S202 -- validated aboveSecond, the unpacker now imports PureWindowsPath and the shared path-security helpers, replacing the simplistic string check with the same broader validation model. This is important because it aligns both the preflight/probe path and the actual unpack path around the same security assumptions.
from pathlib import Path, PureWindowsPath
from ..utils.path_security import PathTraversalError, validate_path_segments
name = member.name
if (
name.startswith("/")
or PureWindowsPath(name).drive
or PureWindowsPath(name).is_absolute()
):
raise ValueError(f"Refusing to extract path-traversal entry: {name}")
try:
validate_path_segments(name, context="tar member")
except PathTraversalError:
raise ValueError(
f"Refusing to extract path-traversal entry: {name}"
) from NoneThe test file tests/unit/bundle/test_tar_windows_absolute_path.py adds regression coverage for Windows drive-letter paths, UNC-style paths, Unix absolute paths, dot-dot traversal, valid bundles, and a negative assertion that no file is created outside the temporary extraction area. This materially improves confidence that the issue is fixed in both code paths.
Review
Pros
- The patch addresses the actual trust boundary: tar member names are validated before extraction rather than relying on post hoc assumptions.
- It closes the Windows-specific gap by using
PureWindowsPathto detect drive-qualified and absolute Windows paths, which the previous Unix-oriented checks missed. - It centralizes traversal handling through
validate_path_segmentsandPathTraversalError, reducing the chance of divergent logic between components. - Both the legacy bundle probe and the unpacker are updated, which is important because the vulnerable extraction behavior existed in more than one path.
- The regression tests are directly aligned with the reported issue and include both exploit-shaped inputs and a safety property check that no outside file is created.
Cons
- The provided diff still uses
tar.extractall(tmp)after validation inlocal_bundle.py. While acceptable if validation is complete, this keeps security dependent on the correctness and future maintenance of the pre-validation loop. - The snippets do not show a final canonicalization-and-prefix check against the destination root after joining extraction paths. Such a check is often a stronger invariant than member-name validation alone.
- The review material does not show whether all tar entry types are constrained consistently in every path. One snippet references symlink/hardlink rejection, but the full surrounding logic is not visible here, so complete coverage cannot be confirmed from the excerpt alone.
- The tests focus on path forms relevant to this CVE, but the provided material does not demonstrate coverage for mixed separators, unusual Windows namespace prefixes, or encoded edge cases.
Verdict
Root-cause.
Based on the supplied commit and tests, the patch appears to fix the underlying flaw: insufficient cross-platform validation of tar member paths before extraction. The change is not merely blocking one payload string; it broadens validation to cover Unix absolute paths, Windows drive paths, Windows absolute paths, and traversal segments, and it applies that logic in both the legacy probe and unpacker. That is consistent with a root-cause remediation for the reported Windows TarSlip overwrite described by the GHSA advisory and NVD entry.
The main residual concern is architectural rather than immediate: continued use of extractall means future regressions are possible if validation logic drifts. A defense-in-depth improvement would be to compute each destination path explicitly, canonicalize it, verify it remains under the extraction root, and then extract/write entries individually. Still, from the evidence in the patch commit, this fix is technically sound and appropriately targeted to the vulnerability.
Recommended Labs
Try this vulnerability pattern yourself with hands-on labs.
- Slipstream.js
Most directly aligned with this CVE’s TarSlip-style archive extraction issue. It appears focused on file extraction/path traversal behavior leading to unsafe writes, which is the core defensive lesson behind arbitrary file overwrite during tarball handling.
- Untar.py
Strong hands-on defensive lab for learning how tar archive extraction can become unsafe when entry paths are not normalized and constrained. Even though it is in Python, the secure coding patterns transfer well to reviewing and patching tarball extraction flaws in other ecosystems.
- Badtar.py
A good follow-up after Untar.py because it is medium difficulty and likely reinforces defense-in-depth for tar extraction bugs, including safer path validation and prevention of overwrite outside the intended extraction directory.