Prevent Direct Access To files ASP Web.Config - asp.net

Strange question but hopefully its possible.
we have files in the root of our site (/files) these are uploaded through the main cms side of the website (/admin) and to be accessed by people who have access to the (/school) directory.
At the moment, if you have the direct link URL EDIT TO THE FILE you can gain access to the file
the files folder has its own web.config file with some rules, is there a way i can add some of my own authentication within the web.config to only allow requests that come from the School folder to have access to the files?
In my head i would have a piece of VB code that does something like this:
If (Request.UrlReferrer <> Nothing) Then
If Page.Request.UrlReferrer.ToString.Contains("/School/") = True Then
???
End If
Else
Response.Redirect("index.aspx")
End If
I've tested this in a simple page and it seems to work okay.

Well, I would assume that the users who can use school folder are memembers of a secuirty role called School (or some such).
thus, any user not a member of school can't use the pages (or files) in the school folder.
Since you want the SAME restricitons for the folder files, then use the same web.config to secure the files folder.
That will mean only users who can use the shools folders will also be the same group of people that only use the files folder.
Now the above will not stop members of securty role "school" from typing in any valid URL to the files folder. So, if you want to prevent this, then I would suggest that for all files up-loaded, you create a folder inside of files folder based on their PK row in the membership table (Memebership.ProviderKey).
Then what you would do is turn off all role groups rights to the files folder. I perfer not EVER allowing a direct URL to files.
Remember, only IIS respects the IIS security settings and provider for a web based URL. Code behind is 100% free to load, read, write, use, play with ANY file via code behind. Code behind uses plain jane FULL path names - and those path names and file names used by code behind does NOT care nor use IIS security settings. Only web based URL's dish out by IIS respect and use the IIS security settings you have for the schools folder. So, copy the web.config for schools over to files, and you are done.
But, code behind? it does not care nor use those settings at all.
So, code behind does NOT use nor respect nor care about IIS security settings. IIS role membership ONLY applies to the asp.net pages and web based URL's. But, code behind is a 100% free to get and grab any file on the system - even files outside of the wwwroot path name of the web site.
So, as a 2nd level and better security?
I would not allow ANY URL's to the files folder.
You then display a grid or list of files on the web page, and code behind for the download button can then go read/get the file (you can use TransMitFile to download that file)
So, best approach is to not allow ANY valid URL's to the files folder.
However, for now, since you only want people who can use the schools folder also be the SAME people that can use the files folder? Then just use the same web.config for both folders - only those people with role of "school" will thus have use and rights to the files folder.
From the information you provided, then you don't really need any code changes - only to take the security settings from the school folder web.config, and copy that to the files folder, and you should be done.
Now, it is possible that the schools folder is not secured by using IIS security and roles - but then again, that would a epic face plant and horrible design choice.

Related

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.

How might i setup my ASP.NET project to find my files?

edit I do not want to redirect pages, specific files etc. I would like to change the path where images, videos and other media are stored from the root source directory to the directory of my choosing. In this case c:/dev/prjfiles/prjname/public (c:/dev/prjfiles/prjname/ is my working directory) and i except when my html does img src="/pic.png" it will find the image in c:/dev/prjfiles/prjname/publi/pic.png. I need a working solution, i tried looking at how to set virtual directories and etc. I cant figure it out. Thus the bounty. I am generating the html, i am not writing asp:image runat="server" etc i am pulling data from a DB and outputing the html. The part that is still a WIP is the code that handles POST request. The html already exist but i cant have hundreds of files in site.com/here pollution my source directory (c:/dev/trunk/thisprj/thisprj/where my .aspx files are and i do not wish 500 .png/gif/jpg here)
I dont know how asp.net environments are usually set up. I am assuming i have a root path that is not available from the web, a bin/ where i may put my asp.net dll and a public where i stick in any files i want.
I would like to have my project files seperated from everything else. My JS, css and image files are in prjfiles/prjname/public with my sqlite db in prjfiles/prjname/ and extra binaries in prjfiles/prjname/bin.
The problem comes when i run my app and try to load an image. Such as /cssimg/error.png. My project does not find resource in my /public folder and i have no idea how to make it find them. How can i set my project up so it does?
NOTE: I set the working directory path so its at prjfiles/prjname/. In code i write ./bin/extrabin.exe and db.sqlite3 which access the files properly.
You might want to watch the getting started videos for ASP.NET
http://www.asp.net/get-started/
EDIT: More info added
As #Murph suggests, your assumptions are incorrect.
IIS takes care of blocking HTTP access to any important files and folders like your *.aspx.cs, and *.cs in the App_Code, any DLLs, anything under the App_Data directory and the web.config.
Content files, such as *.html, *.css, *.js, .gif, .jpg, .png are all served in the normal manner.
In this way, there is no need for a "public" folder.
I dont know how asp.net environments are usually set up. I am assuming i have a root path that is not available from the web, a bin/ where i may put my asp.net dll and a public where i stick in any files i want.
This is wrong assumption!
You have a root folder, which IS available in public. You set IIS or ASP.NEt Development Server to this folder.
(optional, but always needed) You have a web.config file in this root folder for configuration
You have a bin folder for your assemblies (each page or user control "include" compiles to a class)
(optional) You have App_Data as default folder for file-based DBs and/or other data files (say XML storage, ..)
(optional) You have an App_theme folder for styling and images. Read about ASP.NET themes.
(optional) You can add App_Code folder if you want to add classes to be compiled by the server.
You can create folders for scripts, etc...
Normally for complex logic, etc.. you create in a separate project outside the root and reference the result assembly in the bin folder.
Seriously, you cannot do ASP.NET work without an IDE or a manual. Visual Web Developer 2008 Express IDE is free and http://asp.net has tons of resources for getting started.
I don't know if I got the question right, but maybe you could try the <BASE> HTML tag.
HTML <base> Tag
"Specify a default URL and a default target for all links on a page"
There's a nice and simple example at W3Schools, check it out.
The negative side is that you need to put a <BASE> tag in each page you want.
It sounds like you should be able to create a virtual directory to do what you're asking -- but it's a very non-standard setup.
Keep in mind that IIS will prevent users from downloading DLLs and other project-level files, so you usually don't need to partition them off in a separate layer.
For example, just have a cssimg folder at the top level of your project, and skip the whole public folder thing.
I see where you're coming from. ASP.NET projects are set up a little differently from how you're treating them, but you can make them work like you want.
The root of an ASP.NET project IS publicly accessible. When you created your WebSite within Visual Studio, it created a default.aspx page right on the root. Are you hosting in IIS? If so, it's set up to serve up default.aspx by default. But I digress.
Here's how to make it work like you want (mostly):
Create a WebSite, then right-click the site and add a folder named "prjfiles". Right-click that folder and make another named "public". Create another subfolder of that one called "cssimg".
Now, if you want to use the image you mentioned, you'd reference it like this: "~/prjfiles/public/cssimg/error.png" (pathing starting with the root) or "./cssimg/error.png" if you're coming from a page in the public folder (relative pathing).
Really, though, you're doing too much work. Here's how to make it work with less effort:
Create your WebSite, right-click the project and add a folder called "cssimg".
Treat the root as you would the "public" folder- put your pages right there on the root or in subfolders, as needed. You can reference that same image file like this now: "./cssimg/error.png" (relative) or "~/cssimg/error.png" (start from root)
There's also another way to tell the engine where to look for resources, but it's for your css files. Inside the "head" tag, you can add a "style" element (with type="text/css") and inside that you can add something like this: #import '<%= ResolveUrl("~/prjfiles/public/cssimg/styles.css") %>';
Good luck!
If I correctly understood your problem, you're trying to find files which aren't physically stored on a filesystem folder, or stay on a different folder. You can deal with this problems by implementing a UrlRewrite mechanism.
I suggest you to read URL Rewriting in ASP.NET and, after, to take a look into this implementation: A Complete URL Rewriting Solution for ASP.NET 2.0.
If I understand all this correctly (please comment with any correction) right now all your files are together in the root directory and you use <img src="/img.png" /> and it works.
If this is the case, make another directory in the directory the images are in, say call that directory images and put the image files there. now use <img src="/images/img.png" />.
Done.

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.

ASP.NET: external custom config file in a virtual directory - how to?

I know that there at least two approaches to leverage the web.config file:
using the configSource attribute which was introduced in .NET 2.0 - here is a good blog entry about it.
The file attribute of the appSettings tag which lets you point to an external file with a relative path. Described in the MSDN documentation on the appSettings element.
Now, my problem is that both approaches work well only for physical paths. But I need to address a config file which is in a virtual directory.
Which other method could I use to put my config resources in a virtual directory?
Note: I want to do it this way, because I have multiple instances of my web application on the same server (and that on many servers). To keep deployment easy and clean, I want to keep one directory for all the files (aspx, ascx, images, css, js etc.) and point the web apps in IIS for different customers (=domains, https etc.) to this single directory. In every IIS web I would have a virtual directory called "custom" which points to a different folder for each web.
Update: I'd like to point out that this virtual directory "custom" is not suited to contain an inherited web.config - that web.config would be valid only for the custom folder which doesn't contain aspx/ascx files.
I have the same scenario and after reading you post I realised that asp.net won't let you do this for various security reasons.
Therefore I turned to the OS to find an equivalent to the Linux soft link function which in turn led me to the Junction utility from sysinternals. This can create a directory that is actually any other directory on that volume and asp.net can't tell the difference and so happy loads the config sections that are not actually in a subdirectory of you website. Works for me :)
Virtual Directories can be set as applications, and you can just place another web.config there.
It will inherit any changes from the parent config, and you can add custom settings in it.
I was looking to do the same thing but it did not work, so I decided to do the opposite, as you know the web.config can be inherited, so I pointed IIS to a folder containing the client config (connection string, file path etc) files and the website files i put them on a virtual directory with the rest of the webconfig (where it load dll and other application files needed)
So basically i can use the website files to multple clients and the clients with their own Database connection string and other specific client settings.

Resources