Bug 16103 - safe_tarfile fallback validates archive links against cwd instead of extraction destination
Summary: safe_tarfile fallback validates archive links against cwd instead of extracti...
Status: NEW
Alias: None
Product: Samba 4.1 and newer
Classification: Unclassified
Component: Python (show other bugs)
Version: unspecified
Hardware: All All
: P5 normal (vote)
Target Milestone: ---
Assignee: Douglas Bagnall
QA Contact: Samba QA Contact
URL: https://gitlab.com/samba-team/samba/-...
Keywords:
Depends on:
Blocks:
 
Reported: 2026-06-13 00:17 UTC by Douglas Bagnall
Modified: 2026-08-26 02:03 UTC (History)
1 user (show)

See Also:


Attachments
Patch for master (3.32 KB, patch)
2026-07-17 00:25 UTC, Douglas Bagnall
no flags Details
Patch for master (16.11 KB, patch)
2026-08-19 03:09 UTC, Douglas Bagnall
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Douglas Bagnall 2026-06-13 00:17:56 UTC
Tridge writes:

A malicious or tampered Samba backup archive can cross from operator-supplied restore input into privileged filesystem writes on legacy Python runtimes because the safe_tarfile fallback validates links against the process cwd, not the extractall() destination.

- python/samba/safe_tarfile.py:30-49 selects tarfile.tar_filter when available.
- python/samba/safe_tarfile.py:84-88 rejects absolute names and member names containing ../.
- python/samba/safe_tarfile.py:57-60 calls _safetarfile_check() without the caller's extraction path before delegating to extractall().
- python/samba/safe_tarfile.py:80-82 uses realpath(...).startswith(basedir), which is not component-boundary containment.
- python/samba/safe_tarfile.py:90-105 checks symlink and hardlink targets relative to os.getcwd(), not the extraction destination.


**Attacker role:** Attacker who can supply or tamper with a domain backup, SYSVOL, or NTACL tar archive later restored by an operator.

**Entrypoint:** samba-tool domain backup restore opens backup_file and calls safe_tarfile.extractall(targetdir); ntacls.backup_restore() extracts nested tar data into a temporary tree.

**Trust boundary:** Untrusted archive metadata and payload cross into privileged restore-time filesystem operations and restored Samba service state.

**Controls and counterevidence:**
- Modern Python runtimes with tarfile.tar_filter use the safer standard-library branch.
- The fallback rejects absolute member names and member names containing ../.
- Exploitability requires a restore/import path that processes an untrusted or tampered archive under useful filesystem privileges.

**Exploit steps:**
- Prepare a backup or nested restore tar with member link metadata that passes cwd-based fallback checks but points outside the intended extraction root or into a prefix-sibling path.
- Cause an operator to restore the archive on a Python runtime where tarfile.tar_filter is unavailable.
- Let extractall() create the link or linked content in targetdir/tempdir after the preflight check has accepted the archive.
- Use subsequent restored files or copied NTACL payloads to create, overwrite, or tamper with files outside the intended restore tree.

- Additional evidence is available in the per-candidate attack-path report.

#### Reachability

The path is reachable under the attacker role and entry point documented above, with these limits considered:
- Modern Python runtimes with tarfile.tar_filter use the safer standard-library branch.
- The fallback rejects absolute member names and member names containing ../.
- Exploitability requires a restore/import path that processes an untrusted or tampered archive under useful filesystem privileges.

Attacker outcome: A malicious or tampered Samba backup archive can cross from operator-supplied restore input into privileged filesystem writes on legacy Python runtimes because the safe_tarfile fallback validates links against the process cwd, not the extractall() destination.

#### Severity

Final severity is **high**. This breaks a privileged integrity, authorization, filesystem, or remote daemon boundary with a concrete sink in repository code.

**Impact calibration:** Privileged file creation or overwrite during restore, restored-state tampering, and possible service configuration or database manipulation under restore privileges.

**Likelihood calibration:** Medium: restore of untrusted backups is an administrative workflow and the bug is legacy-Python conditional, but the repository still supports Python 3.6+ era deployments where the fallback can be active.

**Severity rationale:** Final severity is **high** because the repository evidence shows a real trust-boundary crossing and reachable sink, while the listed controls and deployment preconditions bound exploitability and blast radius.

Counterevidence and deployment limits considered: Modern Python runtimes with tarfile.tar_filter use the safer standard-library branch.; The fallback rejects absolute member names and member names containing ../.; Exploitability requires a restore/import path that processes an untrusted or tampered archive under useful filesystem privileges..

Additional runtime proof against a live Samba service or a default deployment configuration would raise confidence; evidence that the feature is unreachable, trusted-only, or fully mitigated in supported builds would lower severity.

#### Remediation

Make fallback extraction checks destination-root aware; pass the requested extraction path into the check, use commonpath/component containment, validate link targets relative to the member location under the extraction root, or require tarfile extraction filters. Add regression coverage that exercises the attacker-controlled input at the listed entry point and asserts the validation, authorization, containment, or size check occurs before the dangerous sink.


| Severity | high |
| Confidence | high |
Comment 1 Douglas Bagnall 2026-06-13 00:32:21 UTC
As with previous 'safe_tarfile' bugs, (see "see also") this is not a huge worry: if an attacker can manipulate the tarfile used to restore a domain, they can already create a legitimate tarfile in which they are domain admin.

It is also not an issue for recent versions of Python, where this fallback is not used.

Still, I am working on a solution.
Comment 2 Andreas Schneider 2026-06-15 07:15:51 UTC
If you're already domain admin, the question is if it is then already an exploit. The only reason could be the backup gets manipulated on a backup store and you break something and restore exactly that backup.
Comment 3 Douglas Bagnall 2026-07-17 00:25:30 UTC
Created attachment 19116 [details]
Patch for master
Comment 4 Douglas Bagnall 2026-07-17 00:26:46 UTC
We have never fixed safe_tarfile under embargo before, and I propose we don't this time either.
Comment 5 Douglas Bagnall 2026-08-19 03:09:59 UTC
Created attachment 19171 [details]
Patch for master
Comment 6 Douglas Bagnall 2026-08-26 02:03:24 UTC
For the record, another wrinkle has been found upstream, CVE-2026-19672:

https://www.openwall.com/lists/oss-security/2026/08/25/10

> The tarfile module's tar and data extraction filters created
> directories outside the destination for members whose name leaves the
> destination and returns to it, such as ../evil/../dest/sub/file. The
> containment check used the resolved path, but intermediate
> directories were created from the name as given.
> 
> Only empty directories are created outside the destination. Member contents
> are still extracted inside it. To return to the destination the
> member's name must contain the destination directory's own final
> component, so extraction into a secure randomised directory is not
> affected.

safe_tarfile is likely affected in just the same way, but we WONTFIX because it is vanishingly small risk.