FlawOpen

flawopen.com/Pfad-Traversal/Python os.path.join()

Verhindert Pythons os.path.join() Path Traversal?

CWE-22: Path TraversalReferenzseite
Kurzantwort

Nein. Stell dir die Basis als Raum vor: .. führt durch übergeordnete Räume; ein absoluter Pfad ist eine neue Adresse, durch die os.path.join() den Ausgangsraum verwirft. Löse den Endpfad auf und prüfe vor dem Öffnen, dass er im erlaubten Verzeichnis bleibt.

VULNERABLE
import os

base_dir = "/srv/uploads"
user_filename = "../../outside/demo.txt"
path = os.path.join(base_dir, user_filename)
# Relative traversal can leave the base.

path = os.path.join(base_dir, "/outside/demo.txt")
# An absolute segment discards base_dir.
SECURE — resolve and check containment
import os

def resolve_under_base(base_dir, user_filename):
    if not isinstance(user_filename, str) or not user_filename:
        raise ValueError("Invalid filename")

    base = os.path.realpath(base_dir)
    candidate = os.path.realpath(
        os.path.join(base, user_filename)
    )

    try:
        inside = os.path.commonpath((base, candidate)) == base
    except ValueError:  # e.g. different Windows drives
        inside = False

    if not inside or candidate == base:
        raise ValueError("Invalid filename")
    return candidate

Zwei Eigenschaften beim Zusammenfügen von Pfaden

.. kann einen relativen Pfad aus dem vorgesehenen Verzeichnis führen. Laut Python-Dokumentation verwirft os.path.join() vorherige Teile bei einem absoluten Pfad; Windows-Laufwerks- und Root-Regeln unterscheiden sich von POSIX. pathlib.Path(base) / user_input verhält sich ebenso. Zusammenfügen und Normalisieren sind keine Autorisierung.

Warum commonpath() sicherer als Textpräfixe ist

Löse vertrauenswürdige Basis und Kandidat vor dem Vergleich auf. os.path.commonpath() vergleicht Pfadteile statt Zeichenpräfixe und wirft bei inkompatiblen Wurzeln oder Laufwerken ValueError; lehne solche Fälle ab. realpath() löst beim Prüfen vorhandene Symlinks auf, verhindert aber keine Änderung vor dem Öffnen. Können Dritte den Baum ändern, nutze passende Deskriptorzugriffe und no-follow-Schutz.

Häufige Fragen

Verhält sich pathlib genauso?

Ja. Der Operator / von Path verwirft vorherige Teile, wenn der nächste Pfad absolut ist. Löse das Ergebnis auf und prüfe die erlaubte Basis.

Verhindert realpath() Race Conditions?

Nein. Es löst Symlinks zum Prüfzeitpunkt auf; ein anderer Prozess kann sie vor dem Öffnen ändern. Beschränke Schreibrechte oder nutze unterstützte descriptorrelative no-follow-Operationen.

Quellen

Siehe auch Path-Traversal (CWE-22): Funktionsweise und Schutz in jeder Sprache — flawopen.com Was ist eine Zip-Slip-Schwachstelle? Node.js path.join() verhindert Path Traversal nicht PHP include() und benutzergesteuerte Pfade