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.
设想一家酒店的房卡扫描锁原本只允许开启二楼的客房。如果客人在门禁键盘上输入 '../../master-safe',有缺陷的门锁就会跳出当前楼道,直接打开酒店经理办公室的主保险箱。
Web Application SecurityCWE-918.CWE-918CWE-918):Standard Common Weakness Enumeration classification for path-traversal-swift.Defense-in-Depth应用程序接口通过 HTTP 参数接收用户指定的文件名、报告路径或静态资源标识。
攻击者在文件名参数中注入相对路径遍历符号(如 '../', '..%2f')或绝对路径覆盖。
后端直接将不可信输入与基础目录拼接,未进行规范化绝对路径解析(Canonicalization)与边界校验。
系统运行时打开并回传敏感配置文件(如 /etc/passwd、源码凭证、环境变量密钥),造成数据外泄。
// 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。