Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: added a proper nce/cs

Applications that must accept file uploads must ensure that an adversary cannot upload or transfer malicious files. If a restricted file containing code is executed by the target system, it can result in misuse of privileges. It may also be possible to upload files with dangerous extensions such as .exe and .sh which may cause arbitrary code execution on server-side applications.

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

Code Block
<s:form action="uploadAction" method="POST" enctype="multipart/form-data">
  <s:file name="uploadFile" label="Choose File" size="40" />
  <s:submit value="Upload" name="submit" />
</s:form>

 Many Java enterprise frameworks provide configuration settings intended to be used as a defense against arbitrary file upload. Unfortunately, most of them fail to provide adequate protection. Mitigation of this vulnerability involves checking file size, content type and file contents among other metadata attributes.

Noncompliant Code Example

This noncompliant code example shows some XML code from the interceptor upload action of a Struts 2 application. 

Code Block
bgColor#ffcccc
langjava
p

 

Noncompliant Code Example 

 

The interceptor code is responsible for allowing file uploads.

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

The code for file upload is present in the Upload class:

Code Block
bgColor#ffcccc
langjava
p

 

Noncompliant Code Example

 

Code Block
bgColor#ffcccc
langjava
p

 

Compliant Solution 

public class Upload 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 (Exception e) {
      e.printStackTrace();
      addActionError(e.getMessage());
      return "ERROR";
    }
  }
} 

The value of the parameter type maximumSize ensures that a particular Action does not receive a very large file. The allowedType parameter defines the type of files that are accepted.

However, this approach do not ensure that the uploaded file conforms to the security requirements as interceptor checks can be trivially bypassed. If an attacker uses a proxy tool to change the content type in the raw HTTP request in transit, the framework would not prevent the file's upload.

Compliant Solution 

The file upload must only succeed if the content type matches the content present within the file. For example, a file with an image header must only contain an image and not 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 [Apache Tika|http://tika.apache.org/index.html]. The checkMetaData() method must be called before invoking execute(). 

p
Code Block
bgColor#ccccff
langjava
public static boolean checkMetaData(File f, String getContentType) {
  InputStream is = null;
  try {
    is = new FileInputStream(f);
    ContentHandler contenthandler = new BodyContentHandler();
    Metadata metadata = new Metadata();
    metadata.set(Metadata.RESOURCE_NAME_KEY, f.getName());
    Parser parser = new AutoDetectParser();
    parser.parse(is, contenthandler, metadata, new ParseContext());
    
    if (metadata.get(Metadata.CONTENT_TYPE).equalsIgnoreCase(getContentType)) {
      return true;
    }
    else {
      return false;
    }
  } catch (Exception e) {
    e.printStackTrace();
    return false;
  } finally {
    if (is != null) {
      try {
        is.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }
}

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

Applicability

 

Bibliography

 

...