M_06/ A01:2021 — Broken Access Control
Path Traversal
The server joins a base directory with the filename you supply. If you can sneak ../ in, you can step out of /uploads into sensitive system files.
Filename input
Path resolution
base = /var/www/uploads raw input = ../../etc/passwd url-decoded= ../../etc/passwd resolved = /var/etc/passwd
/
etc
passwd
shadow
var
www
uploads
image.jpg
✗ Escaped upload directory — sensitive file would be read.
Vulnerable
const fs = require('fs');
fs.readFile('/var/www/uploads/' + req.query.f);Secure
const path = require('path');
const base = '/var/www/uploads';
const resolved = path.resolve(base, req.query.f);
if (!resolved.startsWith(base + path.sep))
return res.sendStatus(400);
fs.readFile(resolved);