flawopen.com/Path Traversal/Node.js path.join()
Verhindert Node.js path.join() Path Traversal?
Nein. path.join() normalisiert Pfadsegmente, verhindert aber nicht, dass .. das vorgesehene Verzeichnis verlässt. Lösen Sie den Kandidaten relativ zur Basis auf und prüfen Sie, ob der relative Pfad darin bleibt. Diese lexikalische Prüfung schließt Dateisystem-Symlinks nicht ein.
const filePath = path.join( BASE_DIR, userFilename ); // userFilename = "../../etc/passwd" // still escapes BASE_DIR
const base = path.resolve(BASE_DIR);
const resolved = path.resolve(base, userFilename);
const relative = path.relative(base, resolved);
if (
relative === '' ||
relative === '..' ||
relative.startsWith('..' + path.sep) ||
path.isAbsolute(relative)
) {
throw new Error("Invalid path");
}
Warum path.join() allein nicht hilft
path.join() verbindet Segmente mit dem plattformspezifischen Trennzeichen und normalisiert das Ergebnis. Die Normalisierung lehnt .. nicht ab, da es in vielen Pfaden gültig ist. ../../etc/passwd kann auch nach dem Join außerhalb der Basis liegen; join() prüft keine Eingrenzung.
FAQ
path.normalize() löst ..- und .-Segmente im String auf, prüft aber nicht, ob das Ergebnis innerhalb einer erlaubten Basis bleibt. Vergleichen Sie path.relative(base, resolved) und lehnen Sie ein leeres Ergebnis ab, wenn eine Datei erwartet wird, ebenso .., ein Präfix .. plus path.sep und ein absolut relatives Ergebnis.
Nein. path.resolve() und path.relative() vergleichen Pfadstrings und folgen keinen Dateisystem-Symlinks. Kann ein Angreifer Symlinks unter der Basis erstellen oder ersetzen, prüfen Sie das reale Ziel und verhindern Sie eine Race-Condition zwischen Prüfung und Zugriff. Beschränken Sie Schreibrechte im Verzeichnisbaum, wenn möglich.