🔴 Critical: Path Traversal Vulnerability
Location
src/server.ts static file serving handler (~line 200)
Description
The HTTP server uses join(WEB_DIST, req.url) to resolve static files, but Node path.join() normalizes ../ sequences, allowing arbitrary file reads from the filesystem.
let filePath = req.url === "/" ? "/index.html" : req.url!;
const fullPath = join(WEB_DIST, filePath);
if (existsSync(fullPath)) {
res.writeHead(200, { "Content-Type": ... });
res.end(readFileSync(fullPath)); // arbitrary file read
}
Reproduction
curl http://localhost:9877/../../../etc/passwd
Verified locally:
node -e "const {join}=require('path'); console.log(join('/app/web/dist', '/../../../etc/passwd'))"
# => /etc/passwd
# existsSync('/etc/passwd') => true
Impact
Any local process (or remote, if port is exposed) can read arbitrary files the process has access to.
Fix
const fullPath = join(WEB_DIST, filePath);
if (!fullPath.startsWith(WEB_DIST)) {
res.writeHead(403);
res.end("Forbidden");
return;
}
Or use path.resolve() + prefix check.
🔴 Critical: Path Traversal Vulnerability
Location
src/server.tsstatic file serving handler (~line 200)Description
The HTTP server uses
join(WEB_DIST, req.url)to resolve static files, but Nodepath.join()normalizes../sequences, allowing arbitrary file reads from the filesystem.Reproduction
Verified locally:
Impact
Any local process (or remote, if port is exposed) can read arbitrary files the process has access to.
Fix
Or use
path.resolve()+ prefix check.