How to protect your resources like photos uploaded by the user - c#

I have some PDFs uploaded by the user and they are saved on hard drive. Those PDFs should actually only be visible by the user who uploaded. But at the moment it is not secure. If somebody guesses the name of the PDF, it can be viewed by anybody else too.
Eg: http://www.something.com/PDFs/abcghjiekm.PDF
This is a security threat. What I'd like to be able to do is have some kind of logic that processes the request to these PDFs and compare it with my DB to see if this PDF is actually belonging to the user who requested it. How can I do that?
Edit: I cannot use FileStream as my website is already up and running. I don't want to change all of the codebase and go into each and every aspx page to hunt where the PDFs are accessed.

You could handle PDF through an special HttpHandler in IIS instead of the StaticFile-Handler and check for Access-Rights.
IF you are using MVC a route like /PFDs/{file}.pdf with an Controller returning Content will do.

You could also use some sort of security-by-obscurity, which is less secure, but easier to implement. For example you could save the PDFs in a folder such as PDFs//abcghjiekm.PDF where the guid is the userId of the uploading user. This way guessing the right path for a given file is much harder.
I wouldn't recommend this method if you really need to protect private user data from unauthorized access, but if all that you're trying to achieve is some sort of error-protection (so that users wont access each-other files by mistake) this ought to do it.
If you need real security - I would recommend doing what Grumbler85 suggested.

I think you should use the FileStream, part of the Sql Server 2008 and above to store these files.
http://technet.microsoft.com/en-us/library/bb933993%28v=sql.105%29.aspx
Using it, the files area stored on disk, but in special place. And you have no problem i.e. when someone want to change any file.

Related

C# FileUpload with client feedback and keep files

I have a project in C# that needs to upload files in a page with a lot of others information.
Problems:
1 - File upload doesn't give any feedback for the user, so they can't know how long will takes (doesn't work with UploadProgress and UpdatePanel).
2 - Some validations I can't do with javascript (relationships for example), so if I get any error on the server side, FileUpload loses the file and the user needs to upload the whole file AGAIN.
3 - End user have a really poor link, so for 10mb will takes a long time (10mb is the maximum allowed).
Solutions (none of them works great):
1 - I can use a client side file upload with javascript (like uploadify) and get the percentage, but works as async method so I need to block the screen to don't allow the user to do another things. My worry is more about when I receive the file and save it, because I need to link this file with the other entity if not I will lose the bridge between the file and the entity. (Same happens with the AsyncFileUpload Control). This doesn't solve the problem number 2.
2 - Just do everything synchronous as FileUpload, when all the files arrive to the server, save the file and put all the informations that I need in HiddenFields, so if I get any error on the server side I can recover the file. The problem is that I can't give any feedback for the user while he uploads the file. This doesn't solve the problem number 1.
3 - Split all the files from the others entities (this will mess a lot the project) and upload file individually. The problem is that if I do that I need some mechanism to create the link between the file and the entity AND I can't allow to use the file more than once, so probably this will request a lot of resources to check it. This solves the problems listed but I think create another, complex for the user and a lot of new verifications for the system.
4 - Create 2 buttons, one button VALIDATE for validations on the server side (with no file uploads) and after this check, allow the user to click on the SAVE button. This doesn't solve the problem number 1.
Well, as you can see I'm thinking a lot about the problem but I can't find a really good solution. One that fits all my needs. Anyone have a idea?
PS: I have FileUploads inside repeaters as well, so the IDs are automatics.

Is it possible to do this in a C# ASP.NET Web Application?

I would like to write a Web Application that would have two buttons and directly from the browser would allow me to open two simple text files (using a File Open dialog box or something similar) and would then proceed to read in contents of those files and store them inside of a two strings. The key point here is that the exact files used to read from I don't known at runtime so it would be up to the user to select the files.
The goal is to be able to later compare those two strings but that part I already know how to do. My questions is this - is it even possible to do this inside of a Web Application (i.e. to call a File Open dialog box to allow the user to select files to read from) or would security limitations or some other Web Application related constraints prevent it from being done?
If it is possible, I would appreciate some sample code describing how to open files and how to read in contents of the selected files into strings. Othwerwise, I would like to know if it's not possible and I should consider doing a desktop application or try an entirely different way.
Thank you!
It is possible, but you would wind up having to upload both of the text files to the server and read the files into strings server-side.
All you would need to do is add two separate FileUpload controls to the page along with a button to post the files to the server.
If you don't want the page to refresh, you could always do the comparison via AJAX using the AsyncFileUpload control from the ASP.NET AJAX Toolkit.
Update
Reading the contents of the file should be relatively easy (as long as they are plain text):
var reader = new StreamReader(fileUploadControl.PostedFile.InputStream);
var contents = reader.ReadToEnd();
One way is to use the ASP.NET AJAX AsyncFileUpload control.
http://www.asp.net/ajax/ajaxcontroltoolkit/Samples/AsyncFileUpload/AsyncFileUpload.aspx
In order to access the files from the server-side code (C# code) you'll need the user to upload them. The standard way to do this (and, for security reasons, the only way upon which you should rely) is with a file input element. In ASP.NET, you can use the FileUpload control.
You would essentially give the user two of these controls with which they can upload the two files. Then you'd read their contents on the server, save them however you wish (as files, to a database, just in Session for temporary use, etc.) and perform your logic on that data. Then build your output (the comparison part, which you said you have already) to display on the page refresh.
Be mindful of concerns such as what to do if the user tries to upload non-text files, very large files, etc.
That is not possible alone with JS. You would have to build a file upload (and store session information) or use Silverlight and a Javascript-Bridge to your Web-Application.
Here's an example for a FileOpenDialog in Silverlight: http://www.silverlightexamples.net/post/Open-File-Dialog-in-Silverlight.aspx
Here's an exmaple for a file upload via C#/Webforms http://support.microsoft.com/kb/323246

uploading user profile pics - guidelines

I want users to be able to upload images for profile pictures.
Are there any guidlines as to how this should best be handled?
eg - where to save the images? and folder structure to use.
- make it difficult for users to browse through everyones profile pics?
thanks.
I don't mean to be a wet blanket if your into writing this yourself, but I would just use http://en.gravatar.com
But to answer your questions directly:
Are there any guidelines as to how this should best be handled? eg - where to save the images? and folder structure to use. - make it difficult for users to browse through everyones profile pics?
Generally this is going to depend greatly on the setup of server environment. Do you have multiple web servers? Do you have a database server you want to use? Do you have an images only domain you want to use? etc.
The simplest approach is to write them to the file system and use code to retrieve them. By not writing these files into your web directory you can be sure that users cannot use this to execute code or script on your server. Useing an ASPX page to return the image content also allows you to relocate the image store at any time.
As for preventing browsing, I would just use a unique image identifier generated for each user. BTW, I would not use the user's internal "ID" field; rather, create a new id just for images.
If it is only to display a single user's picture, I would recommend to implement Gravatar instead of your own approach. There are plenty of articles out there how to implemt Gravatar with ASP.NET MVC the best.
If you really want to have your own solution, I'd recommend to give all of the user's profile pictures a random file name (for example with a GUID "3F2504E0-4F89-11D3-9A0C-0305E82C3301.jpg").

Setting up user permissions for reading and writing document files in IIS7

I want to make a very simple CMS for my sites. So what I am thinking is this a user logs in and a list of their pages shows up. Now they change their ends and save it. My C# code would then write over the file/section.
So I don't think it would be to bad to do this however I am not sure about how it works with read and write premission and how to set it up.
Like I want the user to only be able to read and write to their files they own.
So if User A has Page1.html and Page2.html they can only read those files and write to those files they can touch User B's page3.html and Page4.html
So how would I setup this up?
Thanks
When you create your list of files, you will be reading that list from a database repository. Include in that code conditions that allow only those records for which the user has permission.
The most straightforward way to do this is to create a table with two columns: UserID and DocumentID. A presence of a record in the table indicates that the user has permission to that particular document. Add records to this table that give the user permissions to the appropriate documents.
Then, when you read the documents from the database, you can join this table to the documents table via the DocumentID, and filter the table by UserID. This will return only those records for which the user has permission. You can then use that set of records as the basis for the list of documents that you display to the user.
You could employ a cms the SharePoint way. You begin with a base file on the network. If a change to it is made then the page is stored in a database. each subsequent change is a db change and the application renders the last entry in the table for that page.
this does two things. first, you can see revisions and re-instate them. you can see a complete history of the page, who made the changes and when.
it also allows you to lock pages within the database and assign roles/users against the pages. you can then apply a decoration to the controller which checks rights and either renders the page or displays a access denied page and then log the attempted access to the page.
i know this sounds complex but can you foresee a time when after you've gone live with your cms that the client is going to want more from it? you need to implement a solution that's adaptable to needs.
if it's worth writing then it's worth writing well.

ASP.NET Uploaded File

I have an ASP.NET web application that uses jQuery on client side.
On one of the web forms I have a bunch of controls to fill, and an upload control.
User can run upload while filling other entries on the form.
When user saves the form, all data including file is stored into database .
The question is what to do with uploaded file while user fills the form?
I have two possible solutions, but don't know which of them is more optimal
Cache uploaded file, and later, while saving, retrieve it and store into database with all other data.
Save file in temporary folder, and then read it.
What is the best solution for this?
Thanks in advance.
I think the most appropriate solution will be storing uploaded file in cache.
Here is the code
var fileKey = Guid.NewGuid();
var fileStream = new Byte[Request.Files[0].ContentLength];
Request.Files[0].InputStream.Read(fileStream, 0, Request.Files[0].ContentLength);
Cache[fileKey.ToString()] = fileStream;
The fileKey GUID can be stored in ViewState, or sent as the response to client.
Later, when whole form will be saved, cached file can be retrieved and stored into database with other data.
The good thing about this method is that if user navigates from the page cached file will expire, thus avoiding resource flooding.
We can set expiration time using
Cache.Add(fileKey, fileStream, null, DateTime.UtcNow.AddMinutes(10), Cache.NoSlidingExpiration, CacheItemPriority.Default, null);
function.
How about:
3: Store it in the database but marked as in an incomplete state
This could be a separate table, or the same table with a status column.
I fail to see the difference between the 2 options: what do you mean by caching the file? Isn't it the same as saving to a temp folder?
AFAIK, most sites will not start uploading until the entire form is filled up (what if your user cancels, or browses away?). They then display an interim progress bar ("please wait while we're analyzing your data...").
As a general design rule, receiving partial data at any point in time may lead to inconstant data later. If you must do it in steps, change your form to a wizard.
Like other people mentioned - you can simply upload it. You can do it in many ways:
Upload the files in a temporary folder, and when they finally say save or complete - you can move the file from that temp folder to the other folder where you'd usually keep regular files.
One more thing that you can do, whenever the user clicks on upload button for temporary files, is that you can check you temp folder and clear other files which have stayed there for more than 1-2 days/weeks so that way you know for sure you are not wasting space.
Perhaps, you can also have a timer on
your website that regularly cleans up
this folder. I'd say this is more
efficient and you don't have to wait
for users to come in and click on
upload button to clean up your space.

Categories

Resources