Using the WebPermission Setting in ASP.NET Partial Trust

One of the permissions defined in ASP.NET's Medium and High partial trust files is System.Net.WebPermission. This is probably one of the most confusing permissions for developers to use due to the interaction between ASP.NET's <trust /> element and the settings for this permission. The default declaration for System.Net.WebPermission looks like this:

<IPermission
 class="WebPermission"
         version="1">
              <ConnectAccess>
                   <URI uri="$OriginHost$"/>
              </ConnectAccess>
</IPermission>

Although a WebPermission can be used to define both outbound and inbound connection permissions, normally, you use WebPermission to define one or more network endpoints that your code can connect to. The default declaration shown previously defines a single connection permission that allows partially trusted code the right to make a connection to the network address defined by the <URI /> element.

However, the definition for this element has the string replacement token: $OriginHost$. This definition is used conjunction with the <trust /> element, which includes an attribute called originHost and its value is used as the replacement value for $OriginHost$. For example, if you define the following <trust /> element in your web.config:

<trust level="Medium" originUrl="http://www.microsoft.com/"/>

. . . when ASP.NET processes the trust policy file, it will result in a web permission that grants connect access to http://www.microsoft.com/. Although the attribute is called originUrl, the reality is that the value you put in this attribute does not have to be your web server's domain name or host name. You can set a value that corresponds to your web farm's domain name if, for example, you make Web Service calls to other machines in your environment. However, you can just as easily use a value that points at any arbitrary network endpoint as was just shown. One subtle and extremely frustrating behavior to note here is that you need to have a trailing / at the end of the network address defined in the originUrl attribute. Also, when you write code that actually uses System.Net classes to connect to this endpoint, you also need to remember to use a trailing / character.

With the <trust /> level setting shown previously, the following code allows you to make an HTTP request to the Microsoft home page and process the response:

HttpWebRequest wr = 
(HttpWebRequest)WebRequest.Create("http://www.microsoft.com/");
HttpWebResponse resp = 
(HttpWebResponse)wr.GetResponse();Response.Write(resp.Headers.ToString());

Because the WebPermission class also supports regular expression based definitions of network endpoints, you can define originUrl using a regular expression. The reason regular expression based URLs are useful is that the WebPermission class is very precise in terms of what it allows. Defining a permission that allows access to only www.microsoft.com means that your code can access only that specific URL. If you happened to be curious about new games coming out, and created an HttpWebRequest for www.microsoft.com/games/default.aspx, then a SecurityException occurs.

You can rectify this by instead defining originUrl to allow requests to any arbitrary page located underneath www.microsoft.com.

<trust level="Medium" originUrl="http://www\.microsoft\.com/.*"/>

Notice the trailing .* at the end of the originUrl attribute. Now the System.Net.WebPermission class will interpret the URL as a regular expression; the trailing .* allows any characters to occur after the trailing slash. With that change, the following code will work without throwing any security exceptions:

HttpWebRequest wr = (HttpWebRequest)WebRequest.Create("
     http://www.microsoft.com/games/default.aspx");

Although the examples shown all exercise the HttpWebRequest class directly, the most likely use you will find for a custom WebPermission is in partial trust ASP.NET applications that call into Web Services. Without defining one or more WebPermissions, your Web Service calls will fail with less than enlightening security errors.

Because your web application may need to connect to multiple Web Service endpoints, potentially located under different DNS namespaces, you can define an <IPermission /> element in your custom policy file with multiple nested <URI /> entries. As an example, the following code programmatically constructs a WebPermission with two different endpoints, and then writes out the Xml representation of the permission:

WebPermission wp = 
new WebPermission();Regex r = new Regex(@"http://www\.microsoft\.com/.*");
wp.AddPermission(NetworkAccess.Connect,r);r = 
 new Regex(@"http://www\.google\.com/.*");
wp.AddPermission(NetworkAccess.Connect, r);SecurityElement se = wp.ToXml();
Response.Write(Server.HtmlEncode(se.ToString()));

The resulting XML, looks like this (note: in this sample the class attribute has been changed to use the short name for referencing the WebPermission class. Since WebPermission is already defined in ASP.NET partial trust configuration files, you can use the short name in the class attribute rather than listing the full strong named definition of the WebPermission type):

<IPermission class="WebPermission" version="1">
   <ConnectAccess>
      <URI uri="http://www\.microsoft\.com/.*"/> 
      <URI uri="http://www\.google\.com/.*"/> 
   </ConnectAccess> 
</IPermission>

The $OriginHost$ replacement token is no longer being used in this sample. Realistically, after you understand how to define a WebPermission in your policy file, the originUrl attribute isn't really needed anymore. Instead, you can just build up multiple <URI /> elements as needed inside of your policy file. With the previous changes applied to ASP.NET's medium trust configuration file, you can now write code that connects to any page located underneath www.microsoft.com or www.google.com.

HttpWebRequest wr =
(HttpWebRequest)WebRequest.Create("
     http://www.microsoft.com/games/default.aspx");
HttpWebResponse resp = (HttpWebResponse)wr.GetResponse();...
resp.Close();wr = 
(HttpWebRequest)WebRequest.Create("http://www.google.com/microsoft");
resp = (HttpWebResponse)wr.GetResponse();

Although not covered here, the companion classes to HttpWebRequest/HttpWebResponse are the various System.Net.Socket* classes. As with the Http classes, the socket classes have their own permission: SocketPermission. Just like WebPermission, SocketPermission allows the definition of network endpoints for both socket connect and socket receive operations.

This article is adapted from Professional ASP.NET 2.0 Security, Membership, and Role Management by Stefan Schackow (Wrox, 2006, ISBN: 0-7645-9698-5), from chapter 3 "A Matter of Trust." Reprinted with the publisher's permission.



About the Author

Stefan Schackow

Stefan Schackow currently works as a program manager at Microsoft on the ASP.NET product team. He has worked extensively with the new application services delivered in ASP.NET 2.0, including Membership and Role Manager. Prior to joining the ASP.NET product team, he worked in Microsoft's consulting services designing web and database applications for various enterprise clients.

Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Organizations today are under tremendous pressure to deliver a higher quality of products and services at lower costs, and to do so using existing resources. Any expenditure companies do make to help them achieve this goal is expected to deliver a measurable, hard-dollar ROI — and to deliver it quickly. The Internet of Things (IoT) is creating new opportunities for companies to enhance their products, gain business insights and differentiate their offerings. This whitepaper defines an ROI model for …

  • Speed. Agility. Flexibility. There are the big drivers behind most organizations' move to the cloud for their test/dev environments. Freed from the shackles of physical, on-premises infrastructures means test/dev teams can be incredibly fast, both in standing up and tearing down test beds. They can manage version control and they can share work between teams faster ever than below. Read this white paper to learn how your business can respond faster to the rapidly changing needs of customers with a cloud-based …

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date