CODEBOOK
Website Platform Belajar Dan Edukasi
By Shadownex 2025-2026
← Kembali ke Katalog Lab
Path TraversalUNSOLVEDReward: +100 XP

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 `../`.

TARGET OBJECTIVE & BRIEFING

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.

PENTESTING METHODOLOGY
1. Buka fitur pratinjau dokumen di browser.
2. Perhatikan nilai parameter `file=contract.pdf`.
3. Ganti parameter menjadi: `/view?file=../../../../etc/passwd` atau `/view?file=../../../../var/www/flag.txt`.
4. Server membaca dan menampilkan isi file konfigurasi sensitif beserta Flag.
CODE SECURITY INSPECTION

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);
  });
});