flawopen.com/path-traversal/Swift
How file path operations in Swift/Vapor allow traversal escapes, and how to enforce boundaries using standardizedFileURL and standardized paths.
Stellen Sie sich ein Hotelschloss vor, das eigentlich nur Zimmer im zweiten Stock öffnen soll. Wenn ein Gast am Tastenfeld '../../master-safe' eingibt, verlässt das Schloss den Flur und öffnet den Haupttresor des Hotelmanagers.
Web Application SecurityCWE-918 betroffen ist.CWE-918Defense-in-DepthEin Endpunkt akzeptiert Dateinamen oder Ressourcenbezeichner direkt über einen HTTP-Anfrageparameter.
Der Angreifer schleust relative Pfadsequenzen wie '../', '..%2f' oder absolute Pfadüberschreibungen ein.
Das Backend verbindet die Eingabe mit dem Basispfad, ohne kanonische Pfade aufzulösen oder Grenzen zu prüfen.
Das System öffnet und übermittelt vertrauliche Systemdateien (z. B. /etc/passwd oder Konfigurationsgeheimnisse).
// VULNERABLE: PathBuf::join allows directory traversal
use std::fs;
use std::path::PathBuf;
fn read_user_file(filename: &str) -> Result<Vec<u8>, std::io::Error> {
let base_dir = PathBuf::from("/var/app/public/files");
// Attacker input: "../../etc/passwd"
let target = base_dir.join(filename);
// Reads arbitrary system files!
fs::read(target)
}
// HARDENED: Canonicalize path and assert directory prefix
use std::fs;
use std::path::{Path, PathBuf};
use std::io::{Error, ErrorKind};
fn read_user_file(filename: &str) -> Result<Vec<u8>, Error> {
let base_dir = Path::new("/var/app/public/files").canonicalize()?;
// 1. Join and canonicalize target path (resolves .. and symlinks)
let target = base_dir.join(filename);
let resolved = target.canonicalize()?;
// 2. Strict boundary check: resolved must start with base_dir
if !resolved.starts_with(&base_dir) {
return Err(Error::new(ErrorKind::PermissionDenied, "Path traversal attempt detected"));
}
if !resolved.is_file() {
return Err(Error::new(ErrorKind::NotFound, "File not found"));
}
fs::read(resolved)
}
resolved.is_file() before reading.