highUser input reaching your database or shell

Tar Archive Extracted Without a Filter

An archive is unpacked without checking where its entries point.

Why it matters

A tar file decides its own file names. One entry named ../../.ssh/authorized_keys or /etc/cron.d/job lands wherever it says, and a symlink entry followed by a file entry through that link does the same. If the archive came from an upload, a download or a user, the person who made it chooses what your server writes to disk.

What it looks like

This is the shape of code that triggers the rule. AI tools produce it because it works, and nothing tells them it is unsafe.

extractall on an uploaded archive
import tarfile
def unpack(upload_path, dest):
    with tarfile.open(upload_path) as tar:
        tar.extractall(dest)

The smallest fix

minimal patch
with tarfile.open(path) as tar:
    tar.extractall(dest, filter="data")   # Python 3.12+ (backported to 3.8.17, 3.9.17, 3.10.12, 3.11.4)

The better fix

If you have a few more minutes, this is the approach that holds up as the app grows.

safe alternative
# On older interpreters, check every member before extracting:
import os
def safe_extract(tar, dest):
    dest = os.path.realpath(dest)
    for m in tar.getmembers():
        target = os.path.realpath(os.path.join(dest, m.name))
        if not target.startswith(dest + os.sep) or m.issym() or m.islnk() or m.isdev():
            raise ValueError(f"unsafe archive member: {m.name}")
    tar.extractall(dest)

Let your AI tool fix it

When the scanner finds this in your project, it fills in the file and line for you. This is the prompt it gives you to paste into Claude Code, Cursor or whatever you use.

In [the file] at line [the line number] a tar archive is extracted without a filter: [the flagged code]. Pass filter="data" to extractall/extract so absolute paths, parent-directory components, links and device nodes are rejected. If the project must run on a Python without filter support, validate every member's resolved path against the destination first. Add a test with an archive containing "../escape.txt" and confirm extraction raises.

How to check the fix worked

1. Build a tar with an entry named "../escape.txt"; confirm extraction
   raises and the file is not created outside the destination.
2. Extract a normal archive and confirm the files appear.