.NET MVC 4: File Upload Validation - c#

I am implementing a file upload mechanism using .net MVC, where the file upload is a html input with type file, I am using the controller to save to file, the param the controller receives is a httppostedfilebase.
My question is what is the best way to validate the file upload? there is lots out there on stackoverflow and the web saying its best to mime sniff and check the file extension etc I am looking for a modern way t do this.
What I do so far:
check file size
save away from web root
save as a different name
What is the best way to validate the type of file, e.g. doc/docx/pdf/rtf/txt to try and avid mime spoofing and malicious files?
I am trying to avoid a magic number approach too

Related

How can we prevent files that have changed the extension from being uploaded?

I have a program that allow to user upload a file.
Suppose the user is only allowed to upload the psd file (or any other file that is specified by admin user). If user changes the file extension from .exe to psd, can upload it.
How can we prevent files that have changed the extension from being uploaded?
You could check for ContentType header, but that could be tampered by someone with enough knowledge to do so.
Like MrTux pointed out, the best way would be to read the file header and check if it's complying to the file format you want to check against.
It would be easy to decide if you have information on how users are currently uploading files. If it's your own system or if users compose their own http post requests.

Check if the original content of files is not a script or exe content

I am working on file upload and download web App using .net mvc C# APIs and I have read this answer to consider some file security points and I have two questions:
According to the Filetypes point particularly this statement
It's best if the application uses some real content discovery to find
out if the uploaded file is actually an allowed filetype.
I want to check if the user uploads an .exe, .dll or "html containing js code"
file as renamed text file but i don't know how to do that.
According to Content sniffing point, I have added
X-Content-Type-Options: nosniff
To my api web.config file flowing this Answer
but when i upload html page including java script code it uploads and download without any interruption, so how to prevent my app from uploading and downloading these kinds of files.
There are plenty of ideas here (theoretical and practical):
https://security.stackexchange.com/questions/160129/c-malicious-file-upload-to-server
https://www.computerweekly.com/answer/File-upload-security-best-practices-Block-a-malicious-file-upload
I personally would suggest to white-list the extensions that will be allowed to upload, instead of black-listing potentially dangerous extensions.

ASP.NET MVC5 file download security best practices?

We are building an ASP.NET MVC5 web app which includes serving file downloads.
Users are required to login using ASP.NET Identity framework.
The files are stored in the database (we are interfacing with a legacy application) and each file is identified by a standard integer primary key.
We plan to serve the files as follows:
The user requests a file using its ID eg. http://www.example.com/getFile?fileId=5
The controller then checks to see if the requesting user is allowed to access that file (using some complex business rules) and if successful streams the file to the user.
I have been researching best practices but am struggling to find specifics as most of what I've read deals with the scenario where the files are being read from physical paths and therefore the recommendation is to obfuscate the filename in the request.
We could obfuscate the file's ID but I don't see much point to that if the controller will validate the user's access to the file on each request.
Is our approach sufficient or should we be doing it another way, if so, what is the recommended way please?
Your approach is perfectly sufficient. If your authorisation rules in your controller adequately protect the files, then this should be all that you require.
The only information leak that is occurring is the use of what is presumably the primary key of the file in the database in the URL that is being used to request the file. This could potentially create a vulnerability if for example another part of your application is vulnerable to SQL injection attacks and an attacker makes use of the IDs in your URL to construct a SQL injection attack to fetch a file with a specific ID. Whether this is a risk in practice however depends on whether your application is also vulnerable to SQL injection attacks and most attackers would probably guess or brute force the IDs any way, so there may be little practical benefit to masking these even if you were vulnerable to SQL injection attacks - a better focus in that case would be to simply make sure that you're not.
I've once created something similar.
The user asked for a file, we validated if the user could access the file and then streamed it to their browser.
One thing we did though, is store the files outside of the web app folder. This made sure that the files couldn't get into Google by accident, and is also more secure, because malevolent users can't use the full path to the file to download the file directly.
You can obfuscate the file name quite easily. Take a look at this code for example:
public FileResult Download()
{
byte[] fileBytes = System.IO.File.ReadAllBytes(#"c:\folder\myfile.ext");
string fileName = "myfile.ext";
return File(fileBytes, System.Net.Mime.MediaTypeNames.Application.Octet, fileName);
}
in the variable "filename", you put the file that the user will get to see. This can be anything.
Hope this helps.

How to upload files using Yahoo uploader widget in asp.net

Many might have had experience using File Upload widget from Yahoo User Interface library. The docs and community all know how to receive the files on the server using another server technology other than ASP.NET. If anyone has indeed used the widget in their asp.net pages could you share the code on
How to receive the uploaded files Stream/Bytes to a file.
How to check Integrity of the File
How to check if file was received correctly.
Also i would love to do it in single page because doing so i would learn how to differentiate between a normal webpage request and the one caused my file upload widget
Yahoo Upload Widget can be Found here: https://developer.yahoo.com/yui/uploader/.
Have you tried looking at postedfiles collection though? The API looks like it does a standard post. If it does, the just use that collection.
If it doesn't, then you need to use the inputstream property on the request object to read the incoming bytes.
Using something like Fiddler or firebug will tell you how it's making the request. Look for the request type being multipart/mime
edit
Checking the file integrity & whether it was uploaded correctly are pretty much impossible. The only way I can think to do it is to have the user generate a hash of the file then upload the file & the hash & you check the hash is valid. ie not really practical.
All you're getting is a stream of bytes. you have to assume when the stream ends, it ended cleanly & you got all the file.
I answered my own question with code over here.
http://labs.deeptechtons.com/asp-net-tuts/how-to-upload-files-asynchronously-using-yahoo-uploader/

Save a WAV file to disk

This is a web service call which I wrote that is intended to receive a WAV file via a POST and store it in the web-app server's local file system (IIS). Is there a simple method to store the file and if so would someone be so kind as to provide a C# example?
You'll need to have write access to the directory you want to save to.
Make a FileUpload control, then call its SaveAs method in a postback.
If you're writing a REST service, use the following code:
Request.Files[0].SaveAs(/* some file path */);
Either way, be aware of the security issues - make sure the filename has a .wav extension and don't trust the file to be correct.

Categories

Resources