flawopen.com/Pfad-Traversal/Python os.path.join()
Verhindert Pythons os.path.join() Path Traversal?
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.
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.
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.
- ✓Lehne leere oder nicht als Zeichenkette vorliegende Eingaben ab.
- ✓Löse Basis und Kandidat auf; fordere
commonpath((base, candidate)) == base. LehneValueErrorund die Basis selbst ab, wenn eine Datei erwartet wird. - ✓Trenne Pfadbegrenzung von Autorisierung und erlaube nur nötige Dateien und Vorgänge.
- ✓Verhindere bei änderbaren Symlinks Prüf-/Nutzungsrennen mit plattformgerechten Deskriptor-APIs.
Häufige Fragen
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.
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.