Path traversal vulnerability - asp.net

The concept of path traversal is new to me need some guidance please.
In my project I have following line of code:
uploadimg.SaveAs(Server.MapPath("tempfiles/" + fUIName));
FileUpload1.SaveAs(Server.MapPath("tempfiles/" + fSIName));
Is this code is vulnerable to PathTraversal vulnerability.
Can any one help me understanding the concept of path traversal and how to remove/avoid it.
Thanks!
Edit 1:
It is also mentioned that I am storing files in tempfiles folder temporary. After the purpose of saving the file fulfilled I am deleting the files from tempfiles. So can I skip this vulnerability?
Please guide.
Thanks!

The path traversal is means that some one upload a file to your site and can access it direct from the URL (if he knows the path, or can find it from some other page).
Eg, lets say that you upload a pdf file named file.pdf at tempfiles/
Then you probably show it on some page as http://example.com/tempfiles/file.pdf
Now the attacker knows where the file is uploaded, and then its upload to you some other file, maybe an html with fraud, maybe some server browser in an aspx page etc... and direct call it from the url.
Solutions
You can upload all the files to a secure folder like App_Data that you can not direct access it.
You can upload it to a folder that you change the permissions and again you can not direct access it. (see here how you can do that How to set correct file permissions for ASP.NET on IIS)
You can limit the extensions for what you upload and let only images for example, and put that on that directory to avoid anyone to run anything there.
<configuration>
<system.web>
<authorization>
<deny users="*" />
</authorization>
</system.web>
</configuration>
Now, if you upload pdf to a directory that the user can not access direct from the url, you need to create a handler that return the uploaded files. The handler must knows if the user is allowed to view the file, if the file is safe, if the file come direct from the site.
some simple examples.
file download by calling .ashx page and Alternate image display in asp.net
And one last solution is to check the reference and make sure that is comming from your site and its not a direct call from the url using this HttpContext.Current.Request.UrlReferrer.Host. Meaning that the user is uploading an image, but its allowed to view it only if its come the request from a page of your site using some link.

Related

Disallow some file extension from being browsed

I m using Asp.net mvc to get my web site and it is used to show some files uploaded by the admin.
There is a directory (Upload) and admin puts the files on it.
Now the thing i want to know is that no one can access the file by just browsing the url below.
'www.mysite.com/Upload/somePdfFiles.pdf'
Now i want to disallow 'pdf' extension to be downloaded.
Alternatively, i m going to design a page and i m going to get the file path by query string,session etc so that i can download the file by myself. In this page i m going to check some privilege.
So how to disallow 'pdf' extension to be browsed.
I don't think that's possible - you can't differentiate between viewing and downloading because ultimately the actual file content is sent down to the browser and that content is accessible by either saving a document, or by directly accessing the HTTP content with an HTTP client or an HTTP Proxy that can capture the downloaded data.
You can deny access to files in a number of ways so that they are not accessible at all, but you can't make a file 'read-only'. To deny access you can disable access to certain extensions using either IIS filtering, explicit Location exclusion (in web.config) or mapping the extension of choice to the HttpForbiddenHandler.
Whether you view a file as a document in browser or downloaded is determined via HTTP headers. If you don't explicitly specify a Content-Disposition: attachment; filename=<filename> in your headers, the browser will try to open the downloaded content inside of the Web browser using appropriate viewer. For PDF this usually means it'll show in the built in PDF viewer or installed PDF extension. But even if people use the viewer they can always save the document from the viewer so you can't make that content read only.
See HttpForbiddenHandler Class and use in your httpHandlers settings.
e.g.
Restrict links/direct requests to PDF files in /files folder only (403)
<system.webServer>
<handlers>
<!-- If you want to restrict all links
<add verb="*" name="RestrictPDFGlobal" path="*.pdf" type="System.Web.HttpForbiddenHandler"/>
-->
<add verb="*" name="RestrictPDF" path="/files/*.pdf" type="System.Web.HttpForbiddenHandler"/>
</handlers>
</system.webServer>
Alternatively, i m going to design a page and i m going to get the
file path by query string,session etc so that i can download the file
by myself. In this page i m going to check some privilege.
You could do that (interesting note below) by privileged access - e.g. [Authorize] attribute
Sample, improve as needed:
in Home Controller:
[Authorize]
public FilePathResult DownloadPdf()
{
var cd = new System.Net.Mime.ContentDisposition
{
FileName = "foo.pdf"
};
Response.AppendHeader("Content-Disposition", cd.ToString());
return File("~/files/foo.pdf", "application/pdf");
}
View:
<p>#Html.ActionLink("PDF Download", "DownloadPdf", "Home")</p>
Note:
The interesting thing here (I don't know the answer), is why the restriction set in config "allows" this approach (where we "manually" return it via Controller -> Action vs a "direct" request like in a link).
Hth

Web-enabled file storage and security implications of giving delete permission to IIS_IUSRS

I've had this question for many years, and did research every time that this issue arose, but could never find a definite answer. Somehow the mighty Internet, MSDN, community forums, are either silent or vague on this. Out of thousands of development-related uncertainties, this is the only one that remained elusive.
To the point: in order to enable users to upload and manage images (and other files) used in their blog posts, in a shared hosting environment, I can either consider SQL Server binary data types (performance implications), or the file system. To use the latter, the necessary permissions need to be set for the IIS_IUSRS role on the storage directory : create/write, read and delete. My question - if I do this, what are the security implications? Could someone somehow take advantage of this, bypass the ASP.NET request pipeline and manipulate the files inside the folder without making a request to the corresponding ASP.NET handler (which checks rights, validates uploads, etc.)?
I've developed several systems that allowed file uploads and this has always bothered me. Now, hopefully, someone will be able to put my mind at ease and, ideally, explain the mechanics behind the process.
UPDATE
After viewing the latest answers (many thanks), another formulation of the question:
Is it in any way possible for a client to somehow bypass the request pipeline and create/delete files inside a directory that allows it (assuming the person knows the directory structure)? Or only the code that handles the request can do it? Any potential exploits?
The main problem is to been able to upload a script, an aspx page, in this directory with the photo files, and runs it.
Here is one case: I've been hacked. Evil aspx file uploaded called AspxSpy. They're still trying. Help me trap them‼
The solution to that is to add this extra web.config file on the directories that allow to upload files and not permit to run any aspx page. Also double check to allow only extensions that you permit and not allow to change that on the file name, if they have the opportunity to make rename.
<configuration>
<system.web>
<authorization>
<deny users="*" />
</authorization>
</system.web>
</configuration>
Also on the directories that you allow to upload files, do not permit to run any other script like simple asp, or php or exe, or anything.
general speaking
All your pages have permissions to run and manipulate many things on the server. What you give now is the ability of write on some directories, also by using some aspx page. The asp.net now have one more extra permission to write files there, on the photo folder. Also note here, that you asp.net page have this control, not the user. What you do there with your code can write on this directories, so must be carefuller there to double check where you write and not allow any other directories, not allow the user to manipulate the directory that can be written to.
So this is the weak link. To been able to upload more script that can take control of the server, at least the part that can be access by the asp.net user of this pool.
Having done this before, I'd make two recommendations:
First, do not store the uploaded files in the same directory structure as your application code (if possible). Make it a well-defined external location, and locked down explicitly to only the user the application is running as. This makes it harder for a malicious upload to be injected into your application as nothing in the web server, or ASP.NET itself, knows how to access the file (only your application).
If that is absolutely not possible to do so, be sure to make sure no external user can access the storage folder using standard ASP.NET authorization and only allow writes by your application user to this folder, nothing else.
Second, do not store the uploaded files with their original names and file extensions; Keep that meta-data separate. Just consider the file a raw binary blob of data. This is good for a couple reasons. First, it prevents inadvertent execution of the file on the server, be it by someone accessing the file system directly, the web server, or ASP.NET. Second, it makes it much more difficult for an attacker to exploit a malicious upload as they should never be able to guess the name, or path, of the file on the server.

web.config ignoring certain files from requiring authentication

In my asp.net web application, I have a folder in which I have a few html and jpeg files. some of these files do not need a user to login while the others do. How do I exclude the files that are free for view to be displayed without logging in while still maintaining the user to login for viewing other files in the same folder using just the config file. I wasnt able to find something relevant in the config file or maybe I overlooked it. If anyone knows please reply.
Thanks.
I've tried to answer this as well as I can but the sentence:
How do I exclude the files that are free for view to be displayed without logging in while still maintaining the user to login for viewing other files in the same folder using just the config file.
..is a bit confusing!
The files that need to be authenticated are the ones that are handled by the asp.net handler such as .aspx files. jpegs and other static files bypass this so can be viewed without authentication. The handler aspnet_isapi only handles certain files but you can configure it to handle more file extensions (or all files) by configuring extension mappings in IIS.
Personally, I would put all files I wanted to be unprotected in a folder with permissions to allow anyone to view that folder, set the aspnet_isapi handler to handle all files and then protect your other folders according to your application's needs.
Depending on what you want to do (as your question isn't that clear), you may or may not be able to achieve what you want just from the config file but hopefully this answer will give you the information you need to make your own conclusions on that.

ASP.NET Web.config question

The server is IIS7.
Is there a way to disable web.config files in subfolders?
I am asking because, I have a folder on the web server that is for uploads. When someone uploads files, a new folder is created for the user's session and the files they upload go in the folder.
So the path to uploads would be like this:
~/uploads/3F2504E0-4F89-11D3-9A0C-0305E82C3301/somefile.txt
In the ~/uploads/ directory there is a web.config file that removes all http handlers except the static file handler and adds a wildcard mime type. So every file that a user uploads will only ever be served statically.
If a user uploads a web.config file, I want to disallow any of the settings in that file from being applied.
How can I do this?
EDIT
Could I just make the upload folder an application that is a member of an application pool configured to run in Classic mode instead of Integrated Pipeline mode? That way it wouldn't even care about a web.config file.
EDIT 2
Is there another type of webserver I could install for serving all files statically? I could just access the files through a different port. Is there some software that I can be sure wont run any scripts and is safe.
I simply wouldn't allow them to upload a file with that name. In fact, I normally wouldn't trust any filename that the user gave me... makes a great candidate for an injection-style attack.
Ok I have a different angle on this...
What if your uploads folder was not part of the website and instead part of the file system? This way ASP.NET is not processing requests to the folder and thus web.config wouldn't be loaded by the ASP.NET runtime.
You'd have to give your app pool's account read/write access to the file system where these files are stored, but I think it better fits what you're trying to accomplish.
Obviously it could be done in code.
If the folders always exist, you could pre-populate with a web.config with no (significant) content and an ACL to ensure it cannot be overwritten, but looking at the path it I suspect you create the upload folders dynamically which means this would not work.
I don't believe there is a way to tell IIS not to use a web.config (but I could be wrong). Personally, I would add a check to my save code and rename the file.
Why not just check the filename first to prevent the user from uploading a file named web.config? You're probably going to want to check for other things too before allowing the upload - files that are too big, etc.

Uploading files to my site

I have an ASP.NET application. I want users to be able to upload documents. Where in the file system should I store those documents? Users should be able to upload them and see the hyperlinks to them on the site, but UserA should not be able to see UserB's documents, but the administrator role should be able to see all of them.
I'm assuming I don't want to upload them to a folder with my web application because then the web server can serve them up directly. I don't want to store the file in the database, but I can store file paths in the database.
Somebody please give me some best practices. Thanks!
Depending on the size of the files, one options would be to store the files outside the web root so no one could hot-link to them, then, as has been suggested, produce a page that takes some arguments and Response.WriteFile() from said directory.
If the files are large you might want to use Response.TransmitFile to save on some memory on the server.
From an implemenetation point of view, I would probably store the real name of the file in the database to avoid naming collisions and save the files on disk renamed to something like a GUID or just an integer ID taken from the database table.
Then when you write the file to the output stream you can use a content disposition header to rename the file back to the original name.
HTH!
You probably want a folder structure with one folder per user. You could write your own CreateFolder() method that after creating the folder adds a web.config file with authorization rules, letting only the user and administrators access it. That way, users can only access their own files, but admins can access all.
EDIT: For clarification - I am assuming that you are using the ASP.NET Membership features (although not necessarily exactly as is), which lets you put individual web.config files in a directory with the nodes shown below to control access.
<configuration>
<system.web>
<authorization>
<allow roles="admin" />
<allow users="TomasLycken" />
<deny users="*" />
</authorization>
</system.web>
</configuration>
Another way of doing it, is to place all the files in one place, to which you statically allow no access to anyone, and then have a generic handler (.ashx) which serves the files after looking up url and permissions from the database. This is probably a cleaner approach, and it will also take less space seeing as you won't have tons of web.config files laying around...
Note: I purposely posted this as a separate answer, so you can mark the solution you prefer as your answer and ignore the other one.
You can create a virtual directory adjacent (as a sibling) to the root of your website in IIS this does a couple of things 1) it prevents users from accessing the files directly by guessing the file location, 2) you can point the virtual directory to any location you wish, 3) with directory browsing turned off you can prevent anyone from seeing the structure. You can then store the paths in a database further removing the actual structure from the clients.
I have implemented solution like this. I store files in the protected (via web.config section) folder within the website, but instead of real file names I used guids. I also had a database that mapped guids to real names and had some extra information like file size, type etc. In your case this information could also contain name of the user that uploaded the file.
To download the file I implemented HTTP handler that would get a guid parameter and based on the file type set appropriate HTTP header and write the content of the file into response. Before I write file to the response I also check permissions for the current user. Then I have a page that render a list of file names as hyperlinks that point to this HTTP handler with guid parameter that correspond to particular file in the protected folder.
For upload I used very nice SlickUpload control:
http://krystalware.com/Products/SlickUpload/

Resources