Path Traversal in HTTP Servlet File Operations

High Risk Path Traversal
javapath-traversalservletfile-accessdirectory-traversal

What it is

Path traversal vulnerabilities occur when HTTP request parameters are used to construct file paths without proper validation, allowing attackers to access files outside intended directories using sequences like '../../../etc/passwd' to escape the base directory and read sensitive files.

import javax.servlet.http.*;
import java.io.*;
import java.nio.file.*;

@WebServlet("/download")
public class FileServlet extends HttpServlet {
    
    private static final String BASE_DIR = "/app/files/";
    
    protected void doGet(HttpServletRequest request, 
                        HttpServletResponse response) 
            throws IOException {
        
        String filename = request.getParameter("file");
        
        // VULNERABLE: direct concatenation allows traversal
        String filePath = BASE_DIR + filename;
        File file = new File(filePath);
        
        if (file.exists()) {
            Files.copy(file.toPath(), response.getOutputStream());
        }
    }
}

// Attack: /download?file=../../../etc/passwd
import javax.servlet.http.*;
import java.io.*;
import java.nio.file.*;

@WebServlet("/download")
public class SecureFileServlet extends HttpServlet {
    
    private static final String BASE_DIR = "/app/files/";
    
    protected void doGet(HttpServletRequest request, 
                        HttpServletResponse response) 
            throws IOException {
        
        String filename = request.getParameter("file");
        
        // SECURE: validate path stays within base directory
        Path basePath = Paths.get(BASE_DIR)
            .toAbsolutePath().normalize();
        Path filePath = basePath.resolve(filename).normalize();
        
        // Reject if path escapes base directory
        if (!filePath.startsWith(basePath)) {
            response.sendError(400, "Invalid path");
            return;
        }
        
        File file = filePath.toFile();
        if (file.exists() && file.isFile()) {
            Files.copy(filePath, response.getOutputStream());
        }
    }
}

💡 Why This Fix Works

The vulnerable code concatenates user input directly into file paths, allowing attackers to use '../' sequences to access files outside the intended directory. The secure version uses the Path API to normalize paths and validates that the resolved path remains within the base directory using startsWith().

Why it happens

Using string concatenation to combine base directory with user input.

Root causes

Direct Path Concatenation

Using string concatenation to combine base directory with user input.

Missing Path Normalization

Not normalizing paths before validation, allowing traversal sequences.

No Base Directory Validation

Not verifying resolved paths remain within the intended base directory.

Fixes

1

Use Path API with Normalization

Use Path.resolve() and normalize() for safe path construction.

2

Validate Against Base Directory

Check that normalized path starts with base directory using startsWith().

3

Sanitize Filenames

Reject filenames containing path separators or traversal sequences.

Detect This Vulnerability in Your Code

Sourcery automatically identifies path traversal in http servlet file operations and many other security issues in your codebase.