flawopen.com/path-traversal/Java

● CWE-918 · Hoch
Sicherheitsforschung · FlawOpen

Path Traversal in Java

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

💡 Einfache Erklärung (ELI5)

Stellen Sie sich ein Hotelschloss vor, das eigentlich nur Zimmer im zweiten Stock öffnen soll. Wenn ein Gast am Tastenfeld '../../master-safe' eingibt, verlässt das Schloss den Flur und öffnet den Haupttresor des Hotelmanagers.

Kernkonzepte & Begriffe

Web Application Security
Kernkomponente der Architektur, die von CWE-918 betroffen ist.
CWE-918
Standardmäßige Common Weakness Enumeration (CWE)-Klassifizierung für path-traversal-java.
Defense-in-Depth
Mehrschichtige technische Verifikation und Laufzeit-Grenzenisolation.

Schritt-für-Schritt Angriffsablauf

Step 1

Eingabe des Client-Dateipfads

Ein Endpunkt akzeptiert Dateinamen oder Ressourcenbezeichner direkt über einen HTTP-Anfrageparameter.

Step 2

Injektion von Verzeichnis-Traversierungssequenzen

Der Angreifer schleust relative Pfadsequenzen wie '../', '..%2f' oder absolute Pfadüberschreibungen ein.

Step 3

Umgehung der Verzeichnisgrenze

Das Backend verbindet die Eingabe mit dem Basispfad, ohne kanonische Pfade aufzulösen oder Grenzen zu prüfen.

Step 4

Unbefugtes Lesen oder Überschreiben von Dateien

Das System öffnet und übermittelt vertrauliche Systemdateien (z. B. /etc/passwd oder Konfigurationsgeheimnisse).

Quellcode: Verwundbar vs. Sicher

✕ VERWUNDBARE IMPLEMENTIERUNG
// 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);
    }
}
✓ GEHÄRTETER SICHERHEITS-PATCH
// 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);
    }
}

Checkliste für Engineering & Systemsicherheit

References