Uploaded files represent a significant risk to applications. The first step in many attacks is to get some code to the system to be attacked. Then the attack only needs to find a way to get the code executed. Using a file upload helps the attacker accomplish the first step.
Source: Unrestricted File Upload Vulnerability explained at OWASP website
Guidelines
Rule #1 - Create a new file name
Rule #2 - Store the file outside of your document root
Rule #3 - Check the file size
Rule #4 - Extensions are meaningless
Rule #5 - Try a malware scan
Rule #6 - Keep tight control of permissions
Rule #7 - Authenticate file uploads
Rule #8 - Limit the number of uploaded files
Source: 8 Basic Rules to Implement Secure File Uploads posted at SANS Software Security AppSec Blog
The Plan
Follow the "8 Basic Rules to Implement Secure File Uploads" to build a solution to mitigate the "Unrestricted File Upload Vulnerability" using open source software and libraries.
The tools
There are many open source software and libraries to build a web app like this. These are my choices:
- Building & Deployment
The app will be developed in Java 8 using Maven as project dependency manager. - Web app
Spring Boot: the development rock-star.
Twitter Boostrap along with Tether and jQuery because I want to build a beauty UI.
WebJars to let Maven to manage Javascript libraries as it were Java dependencies. - Antivirus
ClamAv is the tool I chose for Rule #5 compliance along with a Java library named clamav-client. - Content-Type Detection
Apache Tika do the hard work to follow Rule #4. - Helper libraries
To follow the Rule #1 and the Dont't Reinvent the Wheel Principle, specially in file handling, I'm going to use Google Guava and Apache Commons-IO. - Testing
Java testing will be made with JUnit. To test ClamAV before its installation, I'll use Docker and its ClamAV Docker image.
Pseudocode
Final Code
git clone https://github.com/immontilla/file-uploading-web-app.git --branch v0.0 --single-branch
Conclusions
- It is possible to build a secure file uploading web app. There are information, guidelines, open source software and libraries freely available in the Internet to help you out.
- Javascript validation code at client-side is useless because it can be easily tampered.
- Server-side validations must include file extension, file size, and content type checking as well as virus scanning.
- HTML5 input type File element has an attribute named accept which is a helper and not a validation attribute.
- Rules 1, 3, 4, 5 are completely fulfilled.
- Rules 2 & 6 depends on yourself.
- Rules 7 and 8 are pending. I am planning to add Spring Security and Spring LDAP as maven dependencies to follow them.
