Friends of OpenJDK Today

Mitigating Path Traversal Vulnerabilities in Java

March 24, 2023

Author(s)

  • Avatar photo
    Brian Vermeer

    Java Champions & Developer Advocate and Software Engineer for Snyk. Passionate about Java, (Pure) Functional Programming, and Cybersecurity. Co-leading the Virtual JUG, NLJUG and DevSecCon community. Brian is also an ... Learn more

Path traversal is a type of security vulnerability that can occur when a web application or service allows an attacker to access server files or directories that are outside the intended directory structure.

This can lead to the unauthorized reading or modification of sensitive data.

In the context of file uploads, a path traversal vulnerability can occur when an application fails to properly validate the file path specified by the user, which can allow the attacker to upload a malicious file with a filename that gives them access to restricted files on the server.

Preventing path traversal in file uploads is crucial for the security of Java applications, as it helps to protect sensitive data and prevent unauthorized access to restricted files and directories.

In this article, we'll explore path traversal in file uploads in more detail and show you how to prevent this vulnerability in Java applications with Snyk Code.

Whether you're a developer or simply interested in learning more about security in Java, this post will provide you with information and insights to help keep your Java applications secure.

Understanding path traversal in file uploads

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. 

Take the example below from a Spring Boot application using Thymeleaf.

@PostMapping("/uploadimage")
public String uploadImage (Model model, @RequestParam("image") MultipartFile file) throws IOException {
   var name = file.getOriginalFilename().replace(" ", "_");
   var fileNameAndPath = Paths.get(UPLOAD_DIRECTORY, name);
   Files.write(fileNameAndPath, file.getBytes());
   model.addAttribute("msg", "Uploaded images: " + name);
   return "person/upload";
}

Web forms are a very common to upload images. When uploading, we use the originalFilename from the incoming MultipartFile.

If we intercept and inspect the HTTP post call, we see that filename is just metadata in this HTTP request shown on line 24.

blog-mitigating-path-traversal-jsession-id

With the right tools, it is easy to change the filename to anything we want! When we change the filename to ../../../../../../../etc/passwd, our code will upload the file to images/profiles/../../../../../../../etc/passwd.

The path will be traversed to the root, and the file will be overwriting /etc/passwd.

How Snyk Code detects path traversal.

Snyk Code is a real-time SAST tool that helps Java developers identify vulnerabilities in their applications — including path traversal in file uploads. The tool uses a static analysis based on an advanced machine learning model to scan your code and identify potential security risks.

Regarding path traversal, Snyk Code can help you identify places in your code where user-specified file paths are used and proper validation is not in place. For example, when connecting my GitHub repository to Snyk, Snyk Code found the path traversal issue for me in the Web UI.

blog-mitigating-path-traversal-snyk-code-ui

Next, I’m using the Snyk plugin for IntelliJ IDEA with Snyk Code enabled. Scanning on my local machine during development already pinpointed the path traversal problem in my file upload.

Additionally, it also gave me some suggestions for possible mitigation actions.

By using Snyk Code, you can proactively identify and fix these path traversal vulnerabilities before they are exploited, helping to ensure the security of your application and the data it handles. 

In summary, Snyk Code helps Java developers identify path traversal vulnerabilities in file uploads by scanning their code and identifying areas where proper validation is not in place.

This can help ensure the security of your application and protect against potential attacks.

Mitigating path traversal in file uploads

The easiest way to fix a path traversal vulnerability is to avoid using the file.getOriginalFilename(). If you generate a name yourself, you have absolute control over the location the file gets stored because it is influenced by user input.

However, if you want to preserve the original file's name, we need to check if the location where the file gets stored is where we want it to be. Snyk Code (see the IDE plugin example) already hinted that we can normalize the path.

Let's change our previous example to check if the normalized path at least starts with our intended upload folder. This way, we prevent path traversal issues.

@PostMapping("/uploadimage")
public String uploadImage (Model model, @RequestParam("image") MultipartFile file) throws IOException {
   var name = file.getOriginalFilename().replace(" ", "_");
   var fileNameAndPath = Paths.get(UPLOAD_DIRECTORY, name);

   if (!fileNameAndPath.normalize().startsWith(UPLOAD_DIRECTORY)) {
        throw new IOException("Could not upload file: " + name);
   }

   Files.write(fileNameAndPath, file.getBytes());
   model.addAttribute("msg", "Uploaded images: " + name);
   return "person/upload";
}

Preventing path traversal vulnerabilities is essential.

Path traversal vulnerabilities are a serious threat to the security of Java web applications, and are currently among the top security issues Snyk finds in Java code.

Developers need to be aware of and understand how to prevent them.

By implementing proper validation and using tools like Snyk Code to identify potential vulnerabilities, developers can help ensure the security of their applications and protect against the risks of path traversal attacks.

It's vital to remember that security is an ongoing process, and staying aware and proactive in identifying and mitigating vulnerabilities is key to maintaining the security of your Java applications.

Related Articles

View All
  • 8 Best Practices to Prevent SQL Injection Attacks

    SQL injection is one of the most dangerous vulnerabilities for online applications. It occurs when a user adds untrusted data to a database query. For instance, when filling in a web form. If SQL injection is possible, smart attackers can create user input to steal valuable data, bypass authentication, or corrupt the records in your database.

    There are different types of SQL injection attacks, but in general, they all have a similar cause. The untrusted data that the user enters is concatenated with the query string. Therefore the user’s input can alter the query’s original intent.

    Read More
    Avatar photo
    April 15, 2021
  • 5 Tips to Create Secure Docker Images for Java Applications

    Docker is the most widely used way to containerize your application. With Docker Hub, it is easy to create and pull pre-created images.

    Read More
    Avatar photo
    December 25, 2020
  • Are Java Security Updates Important?

    Recently, I was in discussion with a Java user at a bank about the possibilities of using Azul Platform Core to run a range of applications. 

    Security is a very serious concern when sensitive data is in use, and potentially huge sums of money could be stolen.

    I was, therefore, somewhat taken aback when the user said, “We’re not worried about installing Java updates as our core banking services are behind a firewall.”

    Read More
    August 03, 2024

Author(s)

  • Avatar photo
    Brian Vermeer

    Java Champions & Developer Advocate and Software Engineer for Snyk. Passionate about Java, (Pure) Functional Programming, and Cybersecurity. Co-leading the Virtual JUG, NLJUG and DevSecCon community. Brian is also an ... Learn more

Comments (0)

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

Highlight your code snippets using [code lang="language name"] shortcode. Just insert your code between opening and closing tag: [code lang="java"] code [/code]. Or specify another language.

Save my name, email, and website in this browser for the next time I comment.

Subscribe to foojay updates:

https://foojay.io/feed/
Copied to the clipboard