I am having a web form available to public, which has file upload capability. Now files are either saved on web server or sent out as attachment in an email. We are having restriction on size i.e 15MB and extensions of file being uploaded. Our SMTP server is on same web server. I have concern about security, as anyone can upload malicious files and can have impact on our production web server.
What are the risks I will be having by such file upload control available to public? Is there anyway someone can execute malicious script on web server by uploading malicious file.
I did some research and found out following points
If I sent out a file as an attachment in an email, this file will be stored for temporary period in Temporary ASP .Net folders, and once email is sent this will get deleted.
You can rename a file before saving them on file system.
You can save file on different location as your website
You can have some sort of real time virus check. I am not sure how you can do that. I was reading about some command line virus scan. But not sure if I really need that.
These are just few points, but I would like to know about any blind spots in file upload.
To answer your question about possible security vulnerabilities, yes you can definately create vulnerabilities in your application and for your users even if you don't save the file to the disk. But there are a few lines of defense you can take to validate.
The first is to obviously restrict the types of files that can be uploaded, you can do this with a white list and a check of the extension but don't stop there. You should also verify by looking at the contents of the file to ensure that it complies with the expected format. This can be critical as a bad guy can inject file headers into the file uploaded and use your system as a zombie for passing around his malware.
Second you should run a virus scan against the uploaded file, you can do this by using a command line to execute a local virus scanner. This is an easy thing to do with many virus scans including Trend Micro, and unless you're looking at a massive amount of file uploads then it should not be a huge tax on your server.
Ensure that you never pass paths as user submitted data (via GET or POST to download) as that can expose you to a path traversal attack. If your user needs to download the file from the browser you can create a database of where the records are stored and then create a controller or page that will fetch it based on the database record and the users access to that record, rather than provide a path which a user can control and use to get files from your server.
Ensure that the directory you will save to is not readable by the web server, this way they don't upload a malware script and then execute it from their browser via an HTTP
Ensure that you validate all user input against some anti-XSS library (Microsoft provides one http://www.microsoft.com/en-us/download/details.aspx?id=28589)
Hope that helps!
The best way is to upload them to /App_Data folder or to store them in a database as binary objects. App_Data is not readable through the web server, so this will protect you against execute and script access. An alternative to storing them in binary is to Base 64 encode them and store them in text (again either in the file system App_Data or database).
Create a proxy page to check the user has permissions to view/download the file and if so send a stream of the file to the HTTP response. This way users do not have direct access and cannot execute anything they shouldn't. You can also attach files using the SMTP classes from a stream reference.
If storing in the file system you could implement your own naming convention so that a request for the actual file is mapped to the stored version.
Virus scanning can be useful, but think of this as protecting other users that may have access to download the file rather than protecting your server.
Related
I know that there are many posts about these topic. But those posts usually talk about restricting the file types and sizes on so on. Hence non serves to my needs as my system does not have any constraints.
Let's say we have a web application, which accepts uploads from users logged in. These users are authenticated via Active Directory. Anonymous users are not allowed.
Users can upload any type of file to the system. Then users can preview the files uploaded via our multi purpose viewer. Right now we support some basic file types, like pictures, music, video, pdf files and office files. I decide for viewable types by checking a dictionary for viewable types, and if the type don't exist it won't be previewed but downloaded directly.
I am curious about the security risks I have, hence I will try to elaborate my system.
I have two different systems in terms of file keeping procedure:
An internet application where the storage is a structured file system where file names are changed with guids
An intranet application where the storage is an unstructured file system where files are directly on the network drive as the user uploaded them, and users can access the files via network drive too
For both applications the previewing strategy is the same.
All files are served from an action method which can only be accessed while authenticated. And logical path traversal for the uploaded files are allowed.
The non-office files are returned to the client, and shown in img, video and embed html tags.
On the other hand, the office files are first executed via interop libraries of the Microsoft Office, converted to pdf, then returned to the client, and again showed as a regular pdf.
I am wondering, through these processes am I compromising any security here on the server side? I know that user can upload malicious files, but is there any way user can harm my system upon writing or reading process of the files?
Update: I am scanning the file after I've taken it into the temp area by an antivirus. Then if it's ok, committing it into the premamant area.
I developing a web application using ASP.NET. The users can download an excel template from the site. Now, i want to check the integrity of the file to check whether the file is the same as that on server and it is not corrupted. I can get md5 hashcodes for the file on the server by identifying the path using server.mappath() method but how can i get the location of the downloaded file to generate and check the hashcodes.
how can i get the location of the downloaded file to generate and
check the hashcodes.
You can't. (and thats a good thing). Also, you shouldn't.
You can't access client's system resources through browser. You may use ActiveX (or others browser/OS specific) to do something like that but a better option would be to just provide the hash with each download and let the user verify the file integrity.
In a WebMatrix web site, where User Profiles are dynamically generated from the Database, where and how should I store user uploaded content?
I don't want this content to be publicly viewable unless the user has chosen make their profile, and uploaded content Publicly viewable.
But I can't just shove it all in a separate directory, since all you need to do is guess the location where such content is stored, and then browse the list of files in that dir. So, should I place it outside my \root directory (I don't think this is possible in some Shared hosting environments), or should I somehow insert this content into a database? (I'm trying to avoid this option as best as I can).
For content like Images and Videos, I was thinking that I should use a trusted Storage provider / image host type service where I would have API access used to store and retrieve these files, and then just store a link to the file uploaded to the file storage host in my database?
You could either
Store the extra files along the other user details in the database. (you probably want to discuss this with the db admins before implementing your storage like this)
Put the files on a fileshare your ASP.NET application has access to but that is not accessible from the web.
Turn of directory browsing and put the files there. "everyone" can't browse all files but it does mean that anyone that has a direct link can download that file without being logged in.
I would go with option 2: Put the files in a directory not directly accessible from the web and channel all downloads through your web app so that you control who can download what.
I have a WebForm application that generates a Crystal Report and streams it to the browser as a PDF.
My users would like the app (well, the Browser I suppose!) to always prompt them where to save the file (a network path) and then store that path (probalby in the SQL table that stores their profile info) and always use that path as the default on subsequent attempts.
I am pretty sure I know how to force the browser (IE) to always prompt them where to save the PDF or open it, and I can name the file (attachment), but how can I automatically populate that dialog box that appears (when thy choose to save the file) with a path? Is there some other way I can accomplish this (use a different mime type or something?)?
I suppose instead of streaming the file back, I can just prompt them for where they want to save and (with elevated permissions on the App Pool Identity) save it out to that path from the server. Since this is an Intranet application, the App Pool does already have some elevated permissions, because it must check certain network paths to see if files exist (it is also a Change/Revision app for CAD Math Data files).
How would you handle it?
You absolutely can not force the web browser to choose any particular location by default to save files, without third-party plugins (most of which I hope would also similarly prevent this sort of thing, which could be used for Evil)
So, if the server has access over the Intranet, that's how you'll have to do it.
I need to let a company push information up to my site.
The best way to explain what I am talking about is to explain how it is currently done with their previous website:
This company uploads a CSV file to an FTP set up by the website. The website then processes the CSV file and puts it into an SQL database so that it can be used by the website.
In this case, I am the website and I am working with the company. Both sides are willing to change what they do. So my question is...
What is the best way to accept batch information like this? Is there a more automated way that doesn't involve FTP? In the future I may have a lot of companies wanting to do this, and I'd hate to have to setup accounts for each one.
The project is C# ASP.NET MSSQL
Let me know if you need more information...
Set up a web service to accept incoming data. That way you can validate immediately and reject bad data before it ever gets into your system.
If you want to eliminate FTP, you could allow them to upload files to your site leveraging using FileUpload. Once the file is uploaded you can do your server side processing.
EDIT: From the OP's comment's it seems to be an automated process. That said, if their process generates the file, you could:
Allow them to continue their current process which would involve them generating their file and placing it somewhere where it could be accessed via a URI with authentication, you could access this file on a schedule and process it. From what it seems right now they generate a file and upload it to your FTP server, so there seems to a manual element to begin with.