The below are all the prescribed best practices when deciding to upload a file in a web application. The below are list of implemented approaches:
A few points:
A few points:
- Extension whitelistng: Obvious and the first line of defense was to white listing of extensions. A simple but easily by-passable approach. Good to have this approach.
- File header type checking: This helps prevents the above bypass. Even if the request is captured and tampered to include a restricted file (say exe), the application will check the file header (the magic nos) of the file and reject it. Suppose an application only accepts .pdf files and expects %pdf header, but when we try uploading an exe which has a header MZ, the file will not be uploaded. In this case even though you try replacing the MZ with %pdf, the file will get uploaded but the resultant file would be treated as a pdf and not an exe, so becomes useless.
- Content type: The content type decides how to treat/ render this file once uploaded. The application restricts the type of Content Type in the request. Any attempt to change the content type to something which is not whitelisted will not let the application upload the file at all.
- Anti Null-Byte: Sometimes in php based application, it's possible to by pass the extension restrictions by inserting the NULL bytes in the file name, so that the application check the last extension which is valid but while reading the file name once it's uploaded it discards the anything after the null byte and effectively uploading a php file. The application concerned was even filtering the file names and did not allow any special characters in the file name.
- Size of the file: Another effective approach is to check the file size is only within the prescribed limit. There's no use of allowing a file with size of 100 MB if it just meant to be profile pic upload. Another good to have approach.
- Random file names: The files getting uploaded were being assigned a different random name. so it's hard to guess the file name which needs to be accessed. The original file name is discarded.
- File contents scanning: The file was being checked for any seemingly malicious codes before uploading. Our attempt to upload an innocent looking file with an embedded script was unsuccessful.
- Exiftool: We tried exiftool to alter a file header and insert an script and upload the modified image file. The file gets uploaded as all the above check get passed, but the code would not execute since the application can not invoke the headers. It just renders the file.
A mix of above approaches seems to be pretty solid when trying to thwart malicious file upload.