How can we prevent files that have changed the extension from being uploaded? - c#

I have a program that allow to user upload a file.
Suppose the user is only allowed to upload the psd file (or any other file that is specified by admin user). If user changes the file extension from .exe to psd, can upload it.
How can we prevent files that have changed the extension from being uploaded?

You could check for ContentType header, but that could be tampered by someone with enough knowledge to do so.
Like MrTux pointed out, the best way would be to read the file header and check if it's complying to the file format you want to check against.
It would be easy to decide if you have information on how users are currently uploading files. If it's your own system or if users compose their own http post requests.

Related

secure and hide url and folder from direct download pdf in mvc5

I am developing application for Online Book Purchases
I am giving download PDF Format book after paid money so i want secure my PDF from direct download.
Question:
1) How could I hide folder URL at the time of download PDF
2) Any security code which not allow user directly access folder or PDF
3) When click on download it will directly download PDF instead of open in browser then download
There are a million ways to solve this problem, so I'll just shoot from the hip and throw out a few ideas that might help you.
Recommendation
Firstly, you aren't going to want to explicitly expose any files or folders within your application. Let your application serve them for you, if you even want to serve them at all directly. There are quite a few things that you could consider:
E-mail - Instead of serving the file directly on the website, e-mail the user a copy of the requested file after they have gone through the payment process.
Leverage GUIDs - If you do elect to have a link to the file, make it user-specific. Store all of the users that have paid for a given file in a database and assign IDs (using GUIDs) to them, then when the user requests the file, verify that their account has the appropriate ID or check it against the database to ensure they have permission to access it.
A potential workflow might go something like this:
User selects item to purchase/download.
User goes through payment processing.
After payment is verified, store the transaction in a database (e.g. assign a unique identifier indicating that user can access that particular file(s) OR store something on the user's account indicating all of the resources on your site they have access to)
Alternative: Just e-mail the user a copy of the requested file (or a link to download it on your site using the previous step)
If you do choose to have a link for the user to download the file explicitly, make sure you don't expose the file itself but provide an endpoint that handles determining access and ultimately serving the file like this:
// You could consider writing a custom attribute that would store which files a given
// user had access to (via claims, etc.) but make sure the endpoint requires authentication
[Authorize]
public FileResult DownloadFile(Guid fileId)
{
// Here you could explicitly check in your database to ensure the user had access
// to the requested file, otherwise revoke the request
if (CanAccessFile(context.UserId, fileId))
{
// If they can access the file, then serve it from the appropriate location
return File(...);
}
}
Likewise, you could also support scenarios where simply having access to the link would allow the user to download the file by passing in the file being requested along with a token:
// You wouldn't necessarily need authentication here because the token and
// requested file should be enough
public FileResult DownloadFileWithToken(Guid downloadToken, Guid fileId)
{
// Here you would just check your database to ensure that the token was
// valid for the specific file and if so, allow the user to download it
}
Your Questions
1) How could I hide folder URL at the time of download PDF?
Don't expose the file directly such that a user could access it.
2) Any security code which not allow user directly access folder or PDF?
Again - don't allow direct access to any folders or files. If you are serving these files after a payment is made, then there's no reason for your to explicitly expose them on the site/application.
3) When click on download it will directly download PDF instead of open in browser then download?
You can accomplish this behavior (regardless of how you elect to handle this process) via an HTML download attribute:
<a href="path" download>Download</a>
You can put all of PDF files to a folder, and that folder is placed in the root path.
_ Your project
|_ wwwroot
|_ PDF_folder
|__ file_01.pdf
|__ file_02.pdf
By using this way, user cannot access to the file via URL.
example.com/pdf_folder/file_01.pdf, this path will response 404 status code.
Because there is no directly link that user can access, you don't need any security code in this action.
You can try to return a File when user makes a new request:
public ActionResult Download()
{
// code goes here...
return File(...);
}

Check if the original content of files is not a script or exe content

I am working on file upload and download web App using .net mvc C# APIs and I have read this answer to consider some file security points and I have two questions:
According to the Filetypes point particularly this statement
It's best if the application uses some real content discovery to find
out if the uploaded file is actually an allowed filetype.
I want to check if the user uploads an .exe, .dll or "html containing js code"
file as renamed text file but i don't know how to do that.
According to Content sniffing point, I have added
X-Content-Type-Options: nosniff
To my api web.config file flowing this Answer
but when i upload html page including java script code it uploads and download without any interruption, so how to prevent my app from uploading and downloading these kinds of files.
There are plenty of ideas here (theoretical and practical):
https://security.stackexchange.com/questions/160129/c-malicious-file-upload-to-server
https://www.computerweekly.com/answer/File-upload-security-best-practices-Block-a-malicious-file-upload
I personally would suggest to white-list the extensions that will be allowed to upload, instead of black-listing potentially dangerous extensions.

Web File Properties

Is it possible to get file properties of a web file. ie: PDF file and get the date and time the PDF file was modified. Thanks.
You're probably looking for the HttpWebResponse.LastModified property.
No, you can't. It's not a file, it's a resource.
When you request it from the server you get a response back. In this case the server uses a file as source for the resource, but it could just as well be something that is just created on the fly. You only get the information that the server chooses to put in the HTML header.
You might however be able to get some more information if the server returns directory information. Then you could request the folder and get a listing back, from which you could parse some information. Note however that it's not certain that the server actually uses the files when you request something from the directory, it could still return something completely different. Also, the directory listing is also a resource, so there is no guarantee that it's relevant either.

IIS Virtual Folder URL encryption

We have a c# asp.net web application that, amongst other things, allows users to download previously uploaded files such as PDF's, Word docs etc. The asp.net app is served up via an IIS6 server and the file resources live on a different server.
When the user requests a file (i.e. click a button on the web form), we stream the file back to their browser, changing the ContentType appropriately.
This seemed a good way to avoid going down the IIS virtual folder route to serve up the file resources - which we had concerns about due to the potential for users to hack the URL. i.e. with a URL like https://mydomain/myresource/clientid/myreport.docx, a savvy user could have a good stab at guessing alternative cvlientid's and document names.
The trouble with streaming a Word document to the browser is that when the browser throws it at Word, Word treats it as a brand new doc, which means the original document's properties & margin info is lost.
Our users store metadata information in the Word doc properties, so this solution is not acceptable to them.
Serving up via IIS virtual folders solves that problem, but introduces the URL security problem.
So my questions are ...
Does anyone know how we can use URL encryption/decryption (or obfuscation) with IIS Virtual folders?
Or does anyone know of any open source projects that do a similar job.
Or does anyone have any sugestions on how to go about writing our own implementation of Virtual folders but with encrypted URLs?
Many thanks in advance.
ps. our web app is delivered over https
Sorry guys, in my question, I have made some incorrect assumptions.
What am I trying to do is persist the properties stored on a word document when they are delivered from server (using either Response.TransmitFile or via a virtual folder) to a client browser.
I set up a test scenario with an IIS virtual folder and dropped a docx file (that I know contains info in the title & subject properties) in my virtual folder's physical path.
I pointed my browser at the virtual folder alias and the browser popped up its message to either open or save the doc.
If I choose to save it, the saved docx still has the properties intact.
If I choose to open it fist and then save it from Word, the saved docx has lost the properties.
So I think I need to post a different question!
You may find that the ClaimsAuthorizationManager class in "Windows Identity Foundation" does what you want. You get to implement whatever logic you like to determine who can download what without using "directory security".

Save a WAV file to disk

This is a web service call which I wrote that is intended to receive a WAV file via a POST and store it in the web-app server's local file system (IIS). Is there a simple method to store the file and if so would someone be so kind as to provide a C# example?
You'll need to have write access to the directory you want to save to.
Make a FileUpload control, then call its SaveAs method in a postback.
If you're writing a REST service, use the following code:
Request.Files[0].SaveAs(/* some file path */);
Either way, be aware of the security issues - make sure the filename has a .wav extension and don't trust the file to be correct.

Categories

Resources