Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: hopefully addressed some of the comments

Java-based web applications that accept file uploads must ensure that an attacker cannot upload or transfer malicious files. If a restricted file containing code is executed by the target system, it can result in misuse of privilegescompromise various application layer defenses. For example, an application that permits HTML files to be uploaded could allow malicious code to be executed—an attacker can submit a valid HTML file with a cross-site-scripting payload that will execute in the absence of an output-escaping routine. For this reason, many applications restrict the type of files that can be uploaded.

It may also be possible to upload files with dangerous extensions such as .exe and .sh which could cause arbitrary code execution on server-side applications. An application that restricts only the Content-Type field in the HTTP header could be vulnerable to such an attack.

For providing file upload functionality, a typical Java Server Pages (JSP) page consists of code such as

...

Code Block
<action name="doUpload" class="com.example.UploadAction">
  <interceptor-ref name="fileUploadupload">
    <param name="maximumSize"> 10240 </param>
    <param name="allowedTypes"> text/plain,image/JPEG,text/html </param>
  </interceptor-ref>        
</action>

The code for file upload appears in the Upload UploadAction class:

Code Block
bgColor#ffcccc
langjava
public class UploadUploadAction extends ActionSupport {
  private File uploadedFile;
  // setter and getter for uploadedFile
  
  public String execute() {
    try {
      // File path and file name are hardcoded for illustration
      File fileToCreate = new File("filepath", "filename");
      // Copy temporary file content to this file
      FileUtils.copyFile(uploadedFile, fileToCreate);
      return "SUCCESS";
    } catch (ExceptionThrowable e) {
      e.printStackTrace();
      addActionError(e.getMessage());
      return "ERROR";
    }
  }
} 

...

The file upload must succeed only when the content type matches the content actually present within the file. For example, a file with an image header must contain only an image and must lack executable code. This compliant solution uses the Apache Tika library to detect and extract metadata and structured text content from documents using existing parser libraries. The checkMetaData() method must be called before invoking invoking code in execute() that is responsible for uploading the file.

Code Block
bgColor#ccccff
langjava
public class UploadAction extends ActionSupport {
  private File uploadedFile;
  // setter and getter for uploadedFile
  
  public String execute() {
    try {
      // File path and file name are hardcoded for illustration
      File fileToCreate = new File("filepath", "filename");

      boolean textPlain = checkMetaData(uploadedFile, "text/plain");
      boolean img = checkMetaData(uploadedFile, "image/JPEG");
      boolean textHtml = checkMetaData(uploadedFile, "text/html");

	  if(!textPlain || !img || !textHtml) {
	    return "ERROR";
      }		

	  // Copy temporary file content to this file
      FileUtils.copyFile(uploadedFile, fileToCreate);
      return "SUCCESS";
    } catch (Throwable e) {
      addActionError(e.getMessage());
      return "ERROR";
    }
  }

  public static boolean checkMetaData(File f, String getContentType) {
    try (InputStream is = new FileInputStream(f)) {
      ContentHandler contenthandler = new BodyContentHandler();
      Metadata metadata = new Metadata();
      metadata.set(Metadata.RESOURCE_NAME_KEY, f.getName());
      Parser parser = new AutoDetectParser();
      try {
        parser.parse(is, contenthandler, metadata, new ParseContext());
      } catch (SAXException | TikaException e) {
        // Handle error
        return false;
      }
      
      if (metadata.get(Metadata.CONTENT_TYPE).equalsIgnoreCase(getContentType)) {
        return true;
      } else {
        return false;
      }
    } catch (IOException e) {
      // Handle error
      return false;
    }
  }
}

The AutoDetectParser selects the best available parser on the basis of the content type of the file to be parsed.

...