ASP.NET Trust Levels
Let's take a look at what all this means for a specific application with potential security problems. I'll use a sample application in this article that initially runs with Full trust and make it more secure by using partial trust. Along the way I'll explore some of the issues you might face with your own applications.
The sample application is a straightforward file-based ASP.NET application. Its single page does two potentially dangerous things: reads a file and interacts with an environment variable on the server. Figure 2
shows how it reads the eula.txt
file that Microsoft installs on most Windows systems at C:\WINDOWS\system32\. Microsoft doesn't want anyone to have any excuse for not being aware of the terms of the Windows end user license agreement, so the security settings on this text file allow members of the Users and Administrators groups to read the file, as shown in Figure 3
. And since the application runs with Full trust, the CLR doesn't do any permission checking.
|Figure 2: The sample application for this article performs a couple of potentially dangerous actions. Here it reads the contents of a text file in the Windows System32 directory.||
|Figure 3: Microsoft allows just about everyone who can log into Windows read access to eula.txt, as shown in this properties dialog box for the file. In particular, members of the Users group can read the file.||
But now imagine that as the developer of the application I make a crucial security mistake. In order to make the application a bit more flexible, I've allowed the user to type in the name of the file to display. The code behind the Get Contents button, shown below, concatenates the name with the path of the System32 directory.
string path = @"C:\WINDOWS\system32\";
using (StreamReader reader =
new StreamReader(path + FileNameTextBox.Text))
string content = reader.ReadToEnd();
ResultsLabel.Text = content;
Can you see the problem? A clever user could navigate up the file hierarchy, such as by entering ..\..\boot.ini
as the file name. This is commonly called a traversal
attack, since the user is traversing the drive's directory structure. The application will display the contents of the boot.ini
file, located in the root of the C:
drive. There isn't anything particularly interesting in that file on my computer, but it's certainly not something that I want just any user to be able to see. Traversal attacks can expose sensitive files through your web application.
|Figure 4: The sample application also works with the PATH environment variable, displaying the current value and adding and removing a path.|
Another dangerous thing the application does is to read and write the value of the PATH
environmental variable, shown in Figure 4
. Here, the user can view the current value by clicking the Get Path button and add a new path by entering it in the text box and clicking the Add Path button. The code for reading the path simply uses the Environment class to get the value of the PATH
The code for adding to the PATH
value is a bit more involved than the above snippet, but only because it includes some rudimentary checking for semicolon delimiters and to make sure that the path isn't already part of the PATH
value. The code for removing the path is similar, except that it silently does nothing if the path in the text box is not part of the PATH
variable. The code for both button Click
event procedures is in Listing 1
, with the statements that read and write to the PATH
Okay, okay. Thanks to the magic of the .NET Framework, the code for reading files and working with environment variables is not terribly interesting, and you aren't likely to put these features into a production application except for maybe an administrative tool. But it makes a useful example for talking about partial trust ASP.NET applications. The code in the sample application runs without problem under the default Full trust because the CLR turns off permission checking when the code runs, and permissions for both actions are allowed by Windows when you run the application on the local machine. This sample scenario shows how an attacker who gets control of your application, such as through clever cross-site scripting, could get some access to Windows resources that they have no business having. You can limit access to resources like these using code access security and thereby protect those resources. But to do that you need to impose partial trust on the application so that the CLR checks and enforces permissions. That's what I'll show you how to do.
I need to note one more thing about the sample application. To keep things simple, the principles I'm demonstrating assume that you run it on the local machine in Visual Studio. That way the process identity, using the Cassini development web server, is your own identity. Presumably you're at least a member of the Users group (and, alas, more likely the Administrators group), so you can read eula.txt
and the PATH
variable. If you deploy this application to a web server, the default ASP.NET process identity may not have those permissions. I went for a simple example that ably demonstrates partial trust techniques rather than something more complicated that would require using IIS. My focus here is on partial trust techniques.
Before I get into the details of how to make this application partial trust, I need to explore how ASP.NET enables partial trust deep in the core configuration files of .NET.