flawopen.com/path-traversal/Java

● CWE-918 · Tinggi
Riset Keamanan · FlawOpen

Path Traversal in Java

How unvalidated File constructors in Java allow traversal, and how to verify boundaries using getCanonicalFile and Path.startsWith.

💡 Penjelasan Sederhana (ELI5)

Bayangkan pembaca kartu kunci hotel yang hanya boleh membuka kamar di lantai dua. Jika seorang tamu mengetik '../../master-safe' pada tombol pintu, kunci yang rentan keluar ke lorong dan membuka brankas utama milik manajer.

Konsep Kunci & Istilah

Web Application Security
Komponen arsitektur utama yang terpengaruh oleh CWE-918.
CWE-918
Klasifikasi standar Common Weakness Enumeration (CWE) untuk path-traversal-java.
Defense-in-Depth
Verifikasi rekayasa berlapis dan isolasi batas waktu proses (runtime).

Alur Serangan Langkah demi Langkah

Step 1

Input Jalur Berkas Klien

Titik akhir menerima nama file atau pengenal sumber daya dari parameter permintaan HTTP.

Step 2

Injeksi Urutan Penelusuran Direktori

Penyerang menyisipkan urutan traversal seperti '../', '..%2f' atau jalur mutlak ke parameter file.

Step 3

Penerobosan Batas Direktori Dasar

Backend menggabungkan nama file tanpa kanonisasi jalur dan tanpa memastikan target tetap dalam folder aman.

Step 4

Pengungkapan Berkas Sensitif Sistem

Sistem membaca dan mengalirkan file sensitif (misal: /etc/passwd atau rahasia konfigurasi) ke klien.

Kode Sumber: Rentan vs Aman

✕ IMPLEMENTASI RENTAN
// VULNERABLE: Direct File instantiation with user parameter
import java.io.File;
import javax.servlet.http.*;

public class FileServlet extends HttpServlet {
    private static final File BASE_DIR = new File("/var/app/public/files");

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
        String filename = req.getParameter("file");
        // Attacker sends: ../../../../etc/passwd
        File target = new File(BASE_DIR, filename);

        // Directly serves arbitrary system file!
        serveFile(target, resp);
    }
}
✓ PERBAIKAN AMAN & KUAT
// HARDENED: Canonicalize file and enforce directory prefix check
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import javax.servlet.http.*;

public class FileServlet extends HttpServlet {
    private static final File BASE_DIR = new File("/var/app/public/files");

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        String filename = req.getParameter("file");
        if (filename == null || filename.isBlank()) {
            resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
            return;
        }

        // 1. Resolve canonical path (resolves .. and all symlinks)
        File target = new File(BASE_DIR, filename).getCanonicalFile();
        File canonicalBase = BASE_DIR.getCanonicalFile();

        // 2. Strict boundary check using Java NIO Path
        if (!target.toPath().startsWith(canonicalBase.toPath())) {
            resp.sendError(HttpServletResponse.SC_FORBIDDEN, "Path traversal detected");
            return;
        }

        if (!target.isFile()) {
            resp.sendError(HttpServletResponse.SC_NOT_FOUND);
            return;
        }
        serveFile(target, resp);
    }
}

Daftar Periksa Penguatan Sistem Rekayasa

References