6

I would like to have a whitelist of filetypes that users are authorized to upload to my IIS server (im using IIS v7.5).

What is the options that i have? For example, to restrict filesize to 5MB for a specific action in my controller, i added this section to my webconfig:

<location path="home/fileupload">
  <system.web>
    <!-- maxRequestLength is in kilobytes (KB) -->
    <httpRuntime maxRequestLength="5120" /> <!-- 5MB -->
  </system.web>
  <system.webServer>
    <security>
      <requestFiltering>
        <!-- maxAllowedContentLength is in bytes -->
        <requestLimits maxAllowedContentLength="5242880"/> <!-- 5MB -->
      </requestFiltering>
    </security>
  </system.webServer>
</location>

Is there an option in the webconfig to set a whitelist of allowed filetypes? Or is the only option is to validate the filetypes in code when the file is fully uploaded? What is the recommended technics? How can i be sure that the .docx, .pdf, .jpg, etc are really what they are?

Alexandre Jobin
  • 2,811
  • 4
  • 33
  • 43
  • Is there a reason to don't validate it at the client side? – Pablo Claus Aug 14 '12 at 01:40
  • 1
    because this is not all browsers that support this feature and also because everything should be validated server side anyway! – Alexandre Jobin Aug 14 '12 at 02:56
  • @AlexandreJobin how certain are you wanting to be that the file IS what the user is saying it is? – Jared Aug 18 '12 at 20:01
  • @Jared because the file that the user upload will be used by other persons. It's sure that for my needs, it is a little bit overkill what i ask. But since that i have to make a module to manage uploads, i said to my self that i will take the time to make it right at the first time and this module will be good for all our projects. What happen if a .exe file is renamed to .docx or .zip file and someone try to open it? Can it be dangerous? I don't know and i tried to securize everything :) – Alexandre Jobin Aug 19 '12 at 00:30
  • @AlexandreJobin See my updated answer below in that case – Jared Aug 19 '12 at 09:23
  • 1
    http://prideparrot.com/blog/archive/2012/8/uploading_and_returning_files – VJAI Aug 20 '12 at 05:30

3 Answers3

3

Since you are wanting server side you could use the files mime type.

THIS post shows how to determine the MIME type based on the files contents (instead of by the extension).

If you do want to limit the input to SPECIFIC file extension you could simply check the input name against what you want to accept. If this passes you could do an xref against the library in the post I linked to make sure the user didn't just change the file extension on you.

Doing this would provide a pretty good degree of certainty that the file is one that you want to accept!

EDIT: Based on comments so far.... Based on what you have said you are looking for this method should work quite nicely for you. My suggestion if you are simply wanting to limit it to the types of files listed in one of you comments... Do a simple check on the file extension. If that is valid then pass the file to the urlmon.dll listed in the link. Make sure it doesn't come back as an invalid type....aka Executable/java/zip/etc. If it isn't an invalid type then you will have a very high degree of certainty that it is a safe file!

Lastly, reading through the comments on that post it looks like the urlmon.dll might support all the file types you are wanting implicitly which would remove the need to check that it isn't an executable or something of that nature, but you would need to confirm the doc/docx/xsl/xslx do return a valid mime type.

Community
  • 1
  • 1
Jared
  • 5,840
  • 5
  • 49
  • 83
1

No, there is no web.config setting to restrict what gets uploaded. The only possible way to validate uploaded data is to actually validate that data in code.

Even if there were a setting, it would be useless anyway because it would be based on the Content-Type headers received from the client, which can be quite wrong.

In code, you can certainly look at the Content-Type header, but if you're trying to validate that the uploaded data is of a specific type, you're going to have to do so manually, based on what kind of data you are expecting. For an image, this is easy. For other file types, it can be a lot harder.

dodexahedron
  • 4,584
  • 1
  • 25
  • 37
  • So what would be your technic to validate the file? Do you know a good library that could validate the real type of the file? – Alexandre Jobin Aug 18 '12 at 13:16
  • It depends on the file. There is no magic solution to validate all types of files out there. What kind of file are you trying to work with? – dodexahedron Aug 18 '12 at 14:23
  • For my actual project, i need to validate pdf, doc, docx, xls, xlsx, images. I will not have any videos or audios. Only printable documents. – Alexandre Jobin Aug 19 '12 at 00:37
  • Any file type can be validated by trying to parse it as the given file type and then dealing with exceptions. Images can be validated by the first few bytes, which there are answers for here already. Here are some examples: http://stackoverflow.com/questions/210650/validate-image-from-file-in-c-sharp – dodexahedron Aug 20 '12 at 05:12
  • It's not the only way... But the one way is super involved, I just wrote one and I plan on blogging about it soon... But basically you have to write a Native Module in C++ and subscribe to OnAcquireRequestState (Native, not .Net). Then check if the HttpMethod is a post. Then use HttpRequest::ReadEntityBody to load the post data chunk by chunk into a complete buffer of chunks. The chunk count is in the HttpRawRequest... Then use a Mime Type parser to parse the post data for filenames. If there are bad files in there, return Request Finished and Set the Error Response... A lot more to it. – Ryan Mann Apr 07 '16 at 02:43
  • Fortunately, if your app pools support the CLR and everything you are targetting supports the CLR, then you can use a Native DLL in C++ with Mixed Mode CLR support... So you can use System.Net.Formatting for it's Mime Parsing and makes things WAY easier. Your app pools would all need to be running CLR 4. Then use preCondition = bitness32 or bitness64 and runtimeVersionv4.0 – Ryan Mann Apr 07 '16 at 02:45
0

Data Anotations is what you are looking for, here is a search that may help you, google data anotaions

Update

I think it validates off of file extensions. If you don't wan't to rely on file extensions, I think your best bet is to validate off of MIME types. This is more complex and varies from browser to browser, and can be faked (although this is more complex than faking an extension.)

A simple yet not free option is to use Telerik RadAsyncUpload.

You could write this code yourself (although I've never messed with it) this may get you started. (this post deals with the fact that you can't reliably detect mime types without IIS, but it should get you on your way.)

Hopefully this will get you going. As you know, you can restrict files by their size, validate by their extensions, and if you add validation by MIME types I think you have done all you can. I think this is all you can do to be safe and not to exclude valid files; although I have heard of hashing the file, and some other options; but these will most defiantly exclude legit files.

Also, as I mentioned, MIME types can be fakes and sent to your server, to be extra safe you should validate on both client side and server side.

Garrett Fogerlie
  • 4,450
  • 3
  • 37
  • 56
  • Will the Data Annotation check the validity of a file or simply check the files extension? – Jared Aug 18 '12 at 19:59
  • The RadAsyncUpload will filter on file extension so this is something i can do easly myself on server side and client side too. I was using the MVC version of their controls :) – Alexandre Jobin Aug 19 '12 at 00:35
  • @AlexandreJobin I believe there is the ability to filter on MIME type too. However I think it is on a higher price point. – Garrett Fogerlie Aug 19 '12 at 06:05