SV.DATA.FILE

A potentially harmful file could be uploaded and automatically processed

Vulnerability and risk

Files with certain extensions may be automatically processed under certain environments, allowing attackers to inject malicious files, if those files are not checked.

Mitigation and prevention

Implement the following practices:
  • Store uploaded files outside of the web root directory when possible.
  • Use randomly generated filenames for uploaded files.
  • Ensure that only one extension is used in the filename. Consider the possibility of cross-site scripting if you allow the upload of.htm files.
  • On case-insensitive systems ensure that case-insensitive evaluation of the file extension is performed.
  • Check for the correct MIME type of the file before uploading it, but do not exclusively rely on the MIME type.
  • When possible, ensure that only files with allowed extensions can be directly accessed from the upload directory. For example, restrict access to any PHP/ASP files within a directory if it should only contain images.

Vulnerable code example 1

Copy
  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream()));
    String pLine = br.readLine();
    String filename = pLine.substring(pLine.lastIndexOf("\\"), pLine.lastIndexOf("\""));
    BufferedWriter bw = new BufferedWriter(new FileWriter(UPLOAD_DIRECTORY_STRING + filename, true));  // <- Defect detected here because of a new file been created with tainted name
   
    for (String line; (line=br.readLine())!=null; ) {
      if (line.indexOf(boundary) == -1) {
        bw.write(line);
        bw.newLine();
        bw.flush();
      }
   }
    bw.close();
  }

In this example, Klocwork reports an SV.DATA.FILE defect at line 14, indicating, "A potentially harmful file could be uploaded and automatically processed." Both the contents and the name of the file are accepted from the request, which allows an attacker to specify the file extension, and depending on that, it may be automatically processed. Some dangerous file extensions include .exe, .py, .php."

Fixed code example 1

Copy
 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream()));
    String pLine = br.readLine();
    String filename = UUID.randomUUID().toString();
    BufferedWriter bw = new BufferedWriter(new FileWriter(UPLOAD_DIRECTORY_STRING + filename, true));
     
    for (String line; (line=br.readLine())!=null; ) {
        if (line.indexOf(boundary) == -1) {
            bw.write(line);
            bw.newLine();
            bw.flush();
        }
    }
    bw.close();
 }

A simple way to overcome the SV.DATA.FILE defect is to assign filenames without extensions. Klocwork no longer reports a defect because the filename will be set to a randomly generated UUID.

Vulnerable code example 2

Copy
 public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
   //get the file chosen by the user
   Part filePart = request.getPart("fileToUpload");
  
   //get the InputStream to store the file somewhere
   InputStream fileInputStream = filePart.getInputStream();
  
   //for example, you can copy the uploaded file to the server
   File fileToSave = new File("fileName.exe");
   Files.copy(fileInputStream, fileToSave.toPath(), StandardCopyOption.REPLACE_EXISTING); // Detect defect here because: filename is dangerous and content is from user request
 }

In this example, Klocwork reports an SV.DATA.FILE defect at line 20, indicating, "A potentially harmful file could be uploaded and automatically processed." The code copies the file contents from the request directly into an executable file. This request may be automatically processed or may be intentionally run later on, and the file's extension could be modified or removed.

Fixed code example 2

Copy
 public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
     //get   the file chosen by the user
     Part filePart = request.getPart("fileToUpload");
  
     //get the InputStream to store the file somewhere
     InputStream fileInputStream = filePart.getInputStream();
  
     //for example, you can copy the uploaded file to the server
     File fileToSave = new File(UUID.randomUUID().toString());
     Files.copy(fileInputStream, fileToSave.toPath(), StandardCopyOption.REPLACE_EXISTING);
 }

Klocwork no longer reports a defect because, again, the easiest solution is to give the file a generated name with no extension.

Related checkers

Security training

Application security training materials provided by Secure Code Warrior.

Extension

This checker can be extended through the Klocwork knowledge base. See Tuning Java analysis for more information.