Security risks of file upload-download systems - c#

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.

Related

Does WinRT have a storage option that persists even after uninstalling the application?

I am trying to put some files and folders in a place that my WinRT application could access and read files from. These files and folders must be locked and permanent even when I uninstall the application.
There are 4 main categories of folders that you have access to from a Windows Store Application:
/AppData/Local/<yourpackage>
Standard available libraries (Music, Pictures, Videos)
Libraries that require elevated permissions (Documents)
User-defined folders (through a FilePicker)
Typically you will store data specific to your application in the first kind and data for the user in a library or a user-defined folder.
When your application is uninstalled, its package folder under /AppData/Local is removed so there is nothing left there (note that this contains the directories which you get using ApplicationData.Current.Local and ApplicationData.Current.Roaming).
Therefore in order to save data persistent through installations you will have to save them in a different directory. Note however that in the case of option 4, the user might not decide to give you access to the folder he picked out the previous time or that he doesn't want to give the application access to the Documents library.
I think a more solid solution would be to save the data on a remote location so that the user can download it when he installs the application again, rather than relying on everything being saved at the user's device.
With regards to the locking: you could look into the DataProtectionProvider and see if that suits your needs.
To reiterate Jeroen's response:
To save data locally in a place that won't be deleted when the app is uninstalled, you must use the file picker to have the user choose a location.
Saving the data remotely is the only option that doesn't require user interaction.
It's possible to save data in the app's roaming settings, as those are retained for some period of time after the app is uninstalled. If the user has the app installed elsewhere, that data will be retained continuously. If there are no other installations, it will be retained for around a month.
I recently wrote a blog post addressing this exact scenario in more detail, including how to get a persistent user identity for any data your store remotely: http://www.kraigbrockschmidt.com/2014/07/31/persisting-data-after-uninstall/.

Passing a stream from silverlight to browser

I have a silverlight application that retrieves a file from Amazon s3. At this point I am using a SaveFileDialog to save it to disk.
I am looking for a better way of saving the file.I have looked into and implemented Isolated storage but ultimately decided to not use it because of all the restrictions.
Also, silverlight restricts saving a file outside isolated storage without the save file dialog, so I cannot save a file and then pass the file path to the browser. so this is not possible
HtmlPage.Window.Navigate(urlToFile, "_blank");
What are the options I have left now to pass this stream to a browser?
There is a feature in silverlight 4 where you can run it out of the browser. In this mode you have elevated permissions. The one that would be of most interest to you is
File system access. Trusted applications can access System.IO types
and related types that are otherwise unavailable to Silverlight. These
APIs provide direct read and write access to files in user folders on
the local computer. For more information, see How to: Access the Local
File System in Trusted Applications.
Outside of this, there is no other way to save a file to the users desktop without using the SaveFileDialog

File upload security Concern

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.

How and Where should I save uploaded User Profile (and related) pictures/videos/files?

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.

WebForm (INtranet) app - Prompt user the where to save file and use as default

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.

Categories