Path Traversal via File Upload in Java: What You Need to Know

File uploads are a common feature in many web applications, but they can be a serious security risk if not handled properly. One of the lesser-known (but highly dangerous) vulnerabilities is Path Traversal via File Upload. It’s a variation of an insecure file upload, which directly contributes to Broken Access Control, the #1 security risk in the OWASP Top 10 (2021).

If you’re working with Java, especially on web projects, this is something you definitely want to understand and guard against.

Understanding Path Traversal via File Upload

What is Path Traversal?

Path Traversal (also known as Directory Traversal) is a security vulnerability that occurs when an application improperly processes user-supplied input for file paths. Attackers exploit this by inserting special directory characters like ../ to navigate beyond the intended directory structure.

Path Traversal via File Upload

When a Java web application allows users to upload files, it typically:

  1. Receives the file from the client.
  2. Determines where to store it.
  3. Writes it to disk.

If the file’s name or path is not properly validated, an attacker could upload files outside the intended directory, potentially overwriting critical system files or executing malicious scripts.

Example: Vulnerable Java File Upload Code

public void uploadFile(HttpServletRequest request) throws IOException {
    Part filePart = request.getPart("file");
    String fileName = Paths.get(filePart.getSubmittedFileName()).getFileName().toString();
    String uploadDir = "/var/www/uploads/";

    File file = new File(uploadDir + fileName);
    filePart.write(file.getAbsolutePath());
}

What’s Wrong Here?

  • Lack of input validation: The fileName comes directly from filePart.getSubmittedFileName(), which an attacker can manipulate.
  • Directly concatenating file paths: This allows attackers to use ../ to traverse directories.

Exploiting Path Traversal via File Upload in Java

Let’s say an application allows users to upload files stored in a server’s directory, such as /var/www/uploads/. If an attacker uploads a file named:

Imagine an application that allows users to upload profile pictures. The application stores the profile pictures in a directory on the server, such as /images/profiles/. If the application fails to validate the file name specified by the user properly, an attacker could upload a malicious file with a file name like ../../etc/passwd. This would allow the attacker to access sensitive system files outside the intended directory structure. 

../../../etc/passwd

The application would resolve the path as:

/var/www/uploads/../../../etc/passwd

Since ../ moves up the directory, the file ends up in /var/www/uploads/../../../etc/passwd. If the server isn’t sanitizing the filename, Java will happily navigate directories and write the file where the attacker wants.

How to Prevent Path Traversal in File Uploads

1. Avoid Direct Use of User-Supplied File Names

Instead of saving files with user-provided names, generate a random filename:

import java.util.UUID;

public String generateSafeFileName(String originalFileName) {
    String extension = originalFileName.substring(originalFileName.lastIndexOf("."));
    return UUID.randomUUID().toString() + extension;
}

If you need the name for some reason, sanitize the filename to strip any path components. Never trust user input.

String fileName = Paths.get(filePart.getSubmittedFileName()).getFileName().toString();
fileName = fileName.replaceAll("[^a-zA-Z0-9\\.\\-]", "_"); // basic sanitization

2. Enforce a Safe Upload Directory

Use java.nio.file APIs to enforce that the file remains within your upload directory:

Path uploadPath = Paths.get(uploadDir);
Path resolvedPath = uploadPath.resolve(fileName).normalize();

if (!resolvedPath.startsWith(uploadPath)) {
    throw new SecurityException("Invalid file path!");
}

Further, you should consider if one of the following points meets your business/security requirements

  • Store the uploaded file on a different server
    • This segregates the duty of your application and the host handling the uploaded files
  • Store uploaded files in a non-public folder outside of the webroot folder (e.g., /opt/app/uploads/).
  • Set restrictive file permissions (e.g., chmod 700).

3. Validate the File

Check MIME types and file signatures. Don’t just rely on file extensions.

String mimeType = Files.probeContentType(resolvedPath);
if (!allowedMimeTypes.contains(mimeType)) {
    throw new SecurityException("Invalid file type!");
}

Further, you should consider the following points

  • Set a filename length limit.
  • Restrict the allowed characters.
  • Set a file size limit

4. Use Security Libraries and keep your application up to date

Java security libraries like Apache Commons FileUpload or OWASP Java Encoder can help mitigate risks by handling file uploads securely.

As always, it’s a good idea to keep the libraries of your application updated to mitigate the attack vector for attackers.

Conclusion

Path Traversal via File Upload is one of those sneaky vulnerabilities that can easily slip under the radar. In Java, sanitising, validating, and controlling where and how files are stored is crucial. A few extra lines of code could save you from a massive security breach.

Check out also my other posts, e.g. SQL Injection in Java

👉 Feel free to get in touch with me for a personal consultation or hands-on support. Let’s make your application bulletproof together!

Stay safe, code smart! 😎

chevron_left
chevron_right

Leave a comment

Your email address will not be published. Required fields are marked *

Comment
Name
Email
Website

This site uses Akismet to reduce spam. Learn how your comment data is processed.