Restrict download for general files in Web.Config - asp.net

I need to restrict client access to some specific files. I would like to do it in my web.config instead of relying on who manages the IIS.
I know it is possible to restrict access to file types (for example, all XML files), as seen here: How to restrict download of specified file types
However, how to specify exact file(s)? For example, I would need to block direct access to the file at ~/test/mytest.xml
Keep in mind that another copy of this file, located at ~/secondtest/mytest.xml should still be available to the client.
The only option is in IIS? I can't control it in the web.config?
Thanks!

You can directly specify the file name like following in web.config.
<system.web>
<httpHandlers>
<add path="test/mytest.xml" verb="*" type="System.Web.HttpForbiddenHandler"/>
</httpHandlers>
</system.web>
For IIS7 onwards use following.
<system.webServer>
<handlers>
<add path="test/mytest.xml" verb="*" type="System.Web.HttpForbiddenHandler" name="XML"/>
</handlers>
</system.webServer>

You can restrict access from logged in, anon, specific roles, etc to paths and/or files in your web.config as such:
<location path="filename or path">
<system.web>
<authorization>
<deny users="*" />
</authorization>
</system.web>
</location>
You might also need to put the following in your config:
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>

Related

How to make IIS authorize requests based on Windows user name or group membership?

I have a legacy web app hosted using PHP by IIS. Access to some of the directories of that app is restricted using the following configuration in web.config of the root directory. That makes the Windows username available as REMOTE_USER, so that the app can map that username into an individual database to check authorization. This works and MUST NOT be changed.
<location path="lsgprog/bibliothek/adm">
<system.webServer>
<security>
<authentication>
<anonymousAuthentication enabled="false" />
<windowsAuthentication enabled="true" />
</authentication>
</security>
</system.webServer>
</location>
Access to some other directories is restricted as well and as well using credentials provided by Windows. So those other directories have anonymousAuthentication disabled and windowsAuthentication enabled as well. The difference is 1. that those settings are made in the GUI of IIS and 2. that authorization is actually checked against the file system. This means that the directories simply have read access only for some special groups of users, those groups and users are maintained by some Active Directory and because the app uses Windows auth, things simply work. Users authenticate at their Windows, open Internet Explorer, request the restricted parts of the site, IIS gets the username, group membership etc., checks access to the restricted directories in the file system and grants or denies it.
All of that is configured manually using the GUI of IIS and I want to migrate that to web.config. Enabling Windows auth for some directories is already documented above, what I'm missing is how to allow/deny access to users and groups, which is the file system part. I've already found the element authorization, which pretty much looks like what I want, but whatever I try doesn't work.
<location path="lsgprog/vfristen">
<system.webServer>
<security>
<authentication>
<anonymousAuthentication enabled="false" />
<windowsAuthentication enabled="true" />
</authentication>
</security>
</system.webServer>
<system.web>
<authorization>
<deny users="*"
roles="*"
verbs="GET,HEAD,POST" />
</authorization>
</system.web>
</location>
My expectation was that the above is enough to DENY access to all users, but that doesn't work and any approach based on ALLOW doesn't as well. I hoped that users and roles could simply be mapped against the username and group names of the currently requesting user. What I don't want is form based authorization or converting directories to "apps" or anything that needs to be done outside of web.config.
So, is what I'm trying to do possible at all and if so, how? Thanks!
In this scenario there are multiple options, first - try and add a web.config file to the folder that needs to have its' own permissions e.g. under lsgprog/vfristen, the minimum web.config example which will deny all users access:
<?xml version="1.0"?>
<configuration>
<system.web>
<authorization>
<deny users="*" />
</authorization>
</system.web>
</configuration>
Why does it work - IIS looks at each folder structure for web.config files, in this case the child will overwrite the parent but only the nodes that are inside the child - meaning it will preserve all other settings from the parent (root) web.config:
Make application and directory-specific configuration settings in an ASP.NET application
Although the documentation above is for ASP.NET it applies at the IIS level as well.
Second option to try - since the question mentioned the root of the project is lsgprog then this setting in web.config:
<location path="lsgprog/vfristen">
Should be changed to (remove the root folder of the project from the path):
<location path="vfristen">
Finally third option which could also work is overwriting it at the Machine.config level as mentioned in the above document:
Use the location element in the Machine.config file
When the allowOverride attribute is false, the Web.config files in the web application directories can't override the settings that you specified in the element. This is a useful setting in environments where you must restrict application developers in how they configure a web application. The following example shows a part of a Machine.config file that requires authentication to access the MyApp application on the default Web site and that can't be overridden by settings in a Web.config file:
Machine.config
<configuration>
<location path="Default Web Site/MyApp" allowOverride="false">
<system.web>
<authorization>
<allow users="?" />
</authorization>
</system.web>
</location>
</configuration>
You could try to add the below code in your site web.config file:
<location path="foldername">
<system.webServer>
<security>
<authentication>
<anonymousAuthentication enabled="false" />
<windowsAuthentication enabled="true" />
</authentication>
</security>
</system.webServer>
</location>
<location path="foldername/page1.php">
<system.webServer>
<security>
<authorization>
<remove users="*" roles="" verbs="" />
<add accessType="Allow" roles="DOMAIN\ADGROUP" />
<add accessType="Deny" users="*" />
</authorization>
</security>
</system.webServer>
</location>
Edit: need to install the URL Authorization in iis to make this rule work.
https://learn.microsoft.com/en-us/iis/manage/configuring-security/understanding-iis-url-authorization

How do I prevent unauthenticated access to .csv file in sub folder using forms authentication

I have an ASP.NET application that uses forms authentication and allows users to have some non-ASP.NET files like .txt or .csv created in a subfolder for download. While access to the subfolder for browsing is correctly blocked if the user is not signed in, viewing/downloading .txt or .csv files is possible without being signed in. How do I ensure that only logged in user are able to download any files from that subfolder (without additional login)?
My last try was this (found in some other posting) in web.config, to try to force ASP.NET to also handle .csv and .txt files and include them in its forms authentication:
<system.webServer>
<modules>
<remove name="UrlAuthorization" />
<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" />
</modules>
...
If I remember correctly, this should do the trick:
<location path="Folder/">
<system.web>
<authorization>
<allow roles="YOURROLE" />
<deny users="*"/>
</authorization>
</system.web>
</location>
In order for this to work I think application must be running in integrated mode or at least introduce the file types in mime settings.
This in the main web.config finally did it for me, without the need for any other changes. It forces all file types to be processed by ASP.NET, including CSV files, so all files are now protected by forms authentication. I just hope though that this does not have any unwanted side effects, as this solution is more global than what I hoped for, not just to protect one specific file type in one subfolder. Comments welcome.
<system.webServer>
<modules>
<remove name="FormsAuthenticationModule" />
<add name="FormsAuthenticationModule" type="System.Web.Security.FormsAuthenticationModule" />
<remove name="UrlAuthorization" />
<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" />
<remove name="DefaultAuthentication" />
<add name="DefaultAuthentication" type="System.Web.Security.DefaultAuthenticationModule" />
</modules>
</system.webServer>
Source: https://learn.microsoft.com/en-us/iis/application-frameworks/building-and-running-aspnet-applications/how-to-take-advantage-of-the-iis-integrated-pipeline

ASP.NET Identity - protecting a directory from unauthenticated users

I am using ASP.NET 4.5 OWIN Identity and attempting to block access to a directory for all but authenticated users. The directory contains raw files, so it isnt possible to wrap them in the ASP LoggedInTemplate tag.
When I try and prevent access to the directory to anonymous users, it fails.
I have tried adding the following to the main Web.config file:
<system.web>
<authorization>
<deny users="?" />
</authorization>
</system.web>
<location path="/docs">
<system.web>
<authorization>
<deny users="?" />
</authorization>
</system.web>
</location>
Doing this gives server 500 errors and highlight the location path="/docs" line as the source of the error. This is a hosted solution, so options for changing the IIS server config to allow overrides arent available to me, though that does seem one potential solution for anyone experiencing this issue.
I have now removed the above from the main web.config and added a separate web.config file in the directory that I want to protect. The new web.config contains this:
<?xml version="1.0"?>
<configuration>
<system.web>
<authorization>
<deny users="?" />
</authorization>
</system.web>
</configuration>
This gives no errors, but allows unauthenticated users access to the folder, which is what I am trying to prevent.
Any ideas or pointers to any article that describes how to resolve this would be much appreciated.
The solution to this for my environment was to use the web.config file in the sub directory, but to add a custom handler definition for the file types in question.
<?xml version="1.0"?>
<configuration>
<system.web>
<authorization>
<deny users="?" />
</authorization>
</system.web>
<system.webServer>
<handlers>
<add name="PDFHandler" verb="*"
path="*.pdf"
type="System.Web.StaticFileHandler"
resourceType="Unspecified" />
</handlers>
</system.webServer>
</configuration>
The web server then allows authenticated users only to access the files in the sub directory.
This article led my to the solution: http://www.primaryobjects.com/CMS/Article112

ASP.NET MVC 5 Identity & Securing Folders

Well, I'm at a loss. I've looked everywhere and I'm still getting errors. I have a folder with a couple of pdf files stored in it. The folder is called "docs" and it's in the root directory of my project. I placed a web.config file in the folder with the following code...
<system.web>
<authorization>
<deny users="?" />
</authorization>
</system.web>
I also tried placing the code in my root web.config file using the following code...
<location path="/docs">
<system.web>
<authorization>
<deny users="?" />
</authorization>
</system.web>
</location>
Both of these code blocks produce a 500 server error. Unfortunately, I don't have access to the detailed server error since I'm on shared hosting. Any ideas?
Edit: Sorry... That's what I get for posting a question a 1am. I want to secure the folder so that only those users who are logged in and authorized can access it and download files.
I had a similar problem (see here). The solution was to add the web.config to the directory but also to add a handler directive to it. This worked for me.
<?xml version="1.0"?>
<configuration>
<system.web>
<authorization>
<deny users="?" />
</authorization>
</system.web>
<system.webServer>
<handlers>
<add name="PDFHandler" verb="*"
path="*.pdf"
type="System.Web.StaticFileHandler"
resourceType="Unspecified" />
</handlers>
</system.webServer>
</configuration>
I want to secure the folder so that only those users who are logged
in and authorized can access it and download files.
If you just want to restrict downloads to logged-in and authenticated users, then GlenBee’s solution is by far the simplest and most effective one.
If you need to restrict access by role and/or claim, you have two choices:
If you are comfortable with security by obscurity, you can control access to the page that has the links to the files. The files are stored within the wwwroot, so that all you need to do is link to them on a page that does the role/claim filtering. The downside is that anyone can guess the file paths and names, and gain access to them without having the correct role/claim (although you should still secure the file directory for only authenticated users as per GlenBee’s solution).
If you need to ensure that, without exception, no-one can access the files except those people authorized to do so by virtue of their role/claim (or some other requirement, such as direct ownership), you will have to protect not just the page with the links (filtering for role/claim/ownership), but also create a file handler that passes the files off to the user to be downloaded (filestream, etc.), and to have the files themselves stored outside of wwwroot so they cannot be accessible via plain HTTP. This ‘file hand-off script’ ensures that the user being handed the file actually has the role/claim/ownership required, instead of just being able to blindly guess the path to the file; and storing the file outside of wwwroot ensures that only the script can grab the file in the first place.
I am doing the same thing, here is the contents of the web.config that I placed in the folder:
<configuration>
<system.web>
<authorization>
<deny users="?" />
</authorization>
</system.web>
</configuration>
And with the errors:
A simple solution I do is turn on health monitoring and have it email me errors, this is in my root web.config:
<system.web>
<healthMonitoring enabled="true">
<eventMappings>
<clear/>
<!-- Log ALL error events -->
<add name="All Errors" type="System.Web.Management.WebBaseErrorEvent, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" startEventCode="0" endEventCode="2147483647"/>
<!-- Log application startup/shutdown events -->
<!--<add name="Application Events" type="System.Web.Management.WebApplicationLifetimeEvent" startEventCode="0" endEventCode="2147483647"/>-->
</eventMappings>
<providers>
<clear/>
<!-- Provide any customized SqlWebEventProvider information here (such as a different connection string name value -->
<add name="SqlWebEventProvider" connectionStringName="ConnectionString" maxEventDetailsLength="1073741823" buffer="false" type="System.Web.Management.SqlWebEventProvider"/>
<add name="EmailWebEventProvider" buffer="false" type="System.Web.Management.SimpleMailWebEventProvider" from="website#example.com" to="webmaster#example.com" subjectPrefix="Website Error: "/>
</providers>
<rules>
<clear/>
<add name="All Errors Default" eventName="All Errors" provider="SqlWebEventProvider" profile="Default" minInstances="1" maxLimit="Infinite" minInterval="00:00:00"/>
<!--<add name="Application Events Default" eventName="Application Events" provider="SqlWebEventProvider" profile="Default" minInstances="1" maxLimit="Infinite" minInterval="00:00:00"/>-->
<add name="All Errors To E-Mail" eventName="All Errors" provider="EmailWebEventProvider" profile="Default" minInstances="1" maxLimit="Infinite" minInterval="00:00:00"/>
</rules>
</healthMonitoring>
</system.web>
<system.net>
<mailSettings>
<smtp from="no_reply#example.com">
<network host="mail.example.com" userName="website#example.com" password="P#$$w0rd"/>
</smtp>
</mailSettings>
</system.net>

Restrict File Access From URL

I have a site developed in ASP.NET which is hosted.Now in my site there is folder known as "upload" in which some .rar files are saved for private use.When I directly type the url, the file gets downloaded.
Say suppose the file is at "http://www.mathew.com/uploads/mine.rar",if i type the url in the browser and hit enter,it downloads the file even though directory listing is not there.
I want to restrict this..How can I achieve it.
Thanks,
Mathew
You can restrict that by authorization. Put a web.config file in this folder with:
<configuration>
<system.web>
<authorization>
<deny users="*"/>
</authorization>
</system.web>
</configuration>
EDIT :
This won't work since rar files are not handled by asp.net, so in addition you need to add a handler for asp.net treat rar files like aspx files:
For classic mode:
<system.web>
<httpHandlers>
<add verb="*" path="*.rar" type="System.Web.UI.PageHandlerFactory" />
</httpHandlers>
</system.web>
For integrated mode (default for iis 7.5 and VS 2012)
<system.webServer>
<handlers>
<add name="rar" path="*.rar" verb="*" type="System.Web.UI.PageHandlerFactory"/>
</handlers>
</system.webServer>

Resources