I\'m developing an ASP.NET Web app and would like the user to be able to either upload an image from their local system, or pass in a URL to an image. The image can either b
You may use Infrastructure as a Service for handling images, for example our solution - Uploadcare:
https://uploadcare.com
If you apply any of the image operations to the uploaded image, it gets modified, and therefore any code that might be embedded within the file will be destroyed.
Are there any methods in C# (or external libraries) which can confirm that a file is a JPG/PNG, otherwise throw an error?
Maybe, but that doesn't really help in itself. You can easily make file that is both a valid image format and contains active HTML/script content for IE content-sniffing to stumble on. Or then there's the broken Java and Flash origin policies to worry about, which can have the same effect of scripting into your server's security context.
If you process the image (eg. crop, resize) and re-save that makes it very, very difficult to do content-smuggling attacks. However, you should always ensure that your server-side tools are up-to-date, as vulnerabilities in image processing libraries might expose you to server-side exploit.
If you can't do that, your best bet as a mitigation for all content-injection problems is to serve your images from a different [sub]domain which doesn't have access to any of the sensitive credentials (cookies, basic auth) of the main site.
If using a subdomain for this purpose such as images.example.com
, your main site should be accessible only through www.example.com
and not example.com
. Otherwise, content injected into images.example.com
can access cookies for example.com
in IE. example.com
should 301-redirect to www.example.com
to prevent unwanted cookie leakage in general.
Add the header X-Content-Type-Options: nosniff
to the response to block content-smuggling attacks from IE8. (Doesn't help with earlier versions, alas.)
Also:
Sanitising user-specified filenames is hard, especially if your app is likely running on a Windows server where the rules about usable filenames are complicated indeed. A good place to start is allowing only alphanumerics, and adding your own file extension and prefix. (A prefix is necessary to avoid the Windows reserved filenames, and the empty filename.)
Better: store the user-supplied filename in the database instead of using it as a real filename.
See this question for more discussion of file upload security problems.
Don't let the user determine the file name that will be used on your server. Use [generated guid].jpg instead and put the file name they used in a database table if you need it.
See #12 here: http://www.codinghorror.com/blog/2009/01/top-25-most-dangerous-programming-mistakes.html
External Control of File Name or Path When you use an outsider's input while constructing a filename, the resulting path could point outside of the intended directory. An attacker could combine multiple ".." or similar sequences to cause the operating system to navigate out of the restricted directory. Other file-related attacks are simplified by external control of a filename, such as symbolic link following, which causes your application to read or modify files that the attacker can't access directly. The same applies if your program is running with raised privileges and it accepts filenames as input. Similar rules apply to URLs and allowing an outsider to specify arbitrary URLs.
Be careful with the URL too, make sure it's an absolute, external URL so they can't use your own web server to copy a confidential file off your LAN out into an area they can access it since you'll be loading that URL from code running on your web server.
This is an absolute minefield. Something to take into consideration (not necessarily an exhaustive list, no guarantees, etc.).