Lab 12: File path traversal in document viewer allowing system file disclosure
Fitur pembaca dokumen transaksi menggunakan penggabungan path file langsung tanpa memeriksa karakter navigasi direktori `../`.
Objective:
Gunakan karakter traversal `../../../../etc/passwd` atau `../../../../var/www/flag.txt` untuk keluar dari folder publik dan membaca file sistem rahasia.
Fitur pratinjau dokumen `/view?file=contract.pdf` membaca file dari folder lokal server menggunakan `fs.readFile(path.join(__dirname, 'files', req.query.file))`. Tanpa pembersihan karakter `../`, penyerang dapat menavigasi naik ke direktori root server dan membaca file konfigurasi sistem.
Path Traversal terjadi ketika karakter ../ diizinkan merusak struktur direktori. CodeBook menggunakan path.basename() dan validasi direktori absolut.
VULNERABLE CODE
// KODE RENTAN (Direct File Path Concatenation)
app.get('/view', (req, res) => {
const filename = req.query.file;
// DANGEROUS: Permintaan file disambung tanpa sanitasi '../'!
const filePath = path.join(__dirname, 'public/docs', filename);
fs.readFile(filePath, 'utf8', (err, data) => {
if (err) return res.status(404).send('File tidak ditemukan');
res.send(data);
});
});SECURE CODEBOOK IMPLEMENTATION
// KODE AMAN CODEBOOK STANDARD (path.basename & Directory Boundary Check)
app.get('/view', (req, res) => {
const filename = req.query.file;
// SAFE 1: Hapus semua karakter traversal jalur dengan path.basename
const safeFilename = path.basename(filename); // '..//..//etc/passwd' -> 'passwd'
const allowedDir = path.join(__dirname, 'public/docs');
const filePath = path.join(allowedDir, safeFilename);
// SAFE 2: Pastikan file berada di dalam folder yang diizinkan
if (!filePath.startsWith(allowedDir)) {
return res.status(403).send('Akses direktori ditolak!');
}
fs.readFile(filePath, 'utf8', (err, data) => {
if (err) return res.status(404).send('File tidak ditemukan');
res.send(data);
});
});