Plugging holes in the universe, what are you doing today? RSS 2.0
 Monday, March 06, 2006

If you host your ASP.NET 1.x website with a hosting company that allows the use of Microsoft Access databases and SQL Server and you host in a shared environment then take some time to consider how secure your SQL data is, or rather possibly isn't.

I have shared hosting accounts with a couple of very well known ASP.NET hosting companies. To  discover how secure the shared ASP.NET environments were I found that I was able to traverse out of my web folder to other users web directories and read their web.config files (and of course their SQL Server connection strings and other such goodies).

To use Access databases you generally utilise the data access classes in System.Data.OleDb. There's an unfortunate shortcoming about System.Data.OleDb which is that you need to be running ASP.NET under Full Trust to use it. The security impact of this in a shared hosting environment is that users can exploit this, as I did, to begin touring other customers website folders in search of secrets such as SQL connection strings.

In a shared hosting environment each website runs under it's own unique IUSR_<xxx> anonymous user account and ASP.NET is set to impersonate that account for each request that is handled by the site. The <identity/> impersonate attribute is set to 'true' in the server's machine.config file like this -

    <identity impersonate="true" userName="" password=""/> 


The web folder, which is the root of your website, also has at least the following NTFS permissions on it - read/write access for the IUSR_<xxx> account and Read access for the ASP.NET worker process account (NETWORK SERVICE if running Windows 2003 or ASPNET if running under Windows 2000). As you can see, the worker process account has read access to every site on the shared server. The reason for this is that ASP.NET needs to be able to monitor the web folders for file changes and to be able to read your ASP.NET files (.aspx, .ascx, dll's etc) to be able to compile them.

If you execute this page script on in your website you can discover what your anonymous user account is:

<%@ Page language="c#" runat="server"%>
<%
@ Import Namespace="System.Security.Principal"
%>
<script runat
=server>
   void
Page_Load(Object sender, EventArgs
e) {
   Response.Write(
"<b>Identity:</b>" + WindowsIdentity.GetCurrent().Name + "<br/>"
);
}
</script>

Let's modify the script to this:

<%@ page language="c#" runat="server"%>
<%
@ Import Namespace="System.Security.Principal"
%>
<%
@ Import Namespace="System.Runtime.InteropServices"
%>
<script runat
=server>
[DllImport(@"C:\WINDOWS\system32\advapi32.dll"
)]
public static extern bool
RevertToSelf();
void Page_Load(Object sender, EventArgs
e) {
   Response.Write(
"<b>Identity:</b>" + WindowsIdentity.GetCurrent().Name + "<br/>"
);
   RevertToSelf();
   Response.Write(
"<b>Identity:</b>" + WindowsIdentity.GetCurrent().Name + "<br/>"
);
}
</script>

If your server is running ASP.NET under Full Trust then the RevertToSelf() function ends the impersonation and the remainder of the request executes under the worker process identity, otherwise you'll get an exception thrown (to obtain the path to the system32 directory examine value of the System.Environment.SystemDirectory property).

So what does this mean? The worker process account has read permission to every website folder on the server so it's possible (and I did) to write a script to traverse these folders and harvest web.config files. In fact it's also possible to harvest critical information from every folder that the worker process account has read rights on.

To mitigate this issue you could run each website in it's own application pool and give each application pool it's own identity and each web folder would have NTFS permissions for each of those identities. However this is not really a practical or manageable solution because in a shared hosting environment there can be anything between 500 to 1000 websites. Can you imagine managing up to 1000 application pools and worker processes on the web server? Can you imagine the ACL management for all of those areas that ASP.NET likes to touch? Also your $10.00 a month hosting company is unlikely to give you your own application pool and identity, no matter how nicely you ask, because it's just not economically viable for them. They are more likely to suggest that you buy one of their dedicated server solutions.

So the bottom line is this. If you're hosting on a shared environment and your hosting company allows the use of Access databases then beware that your sensitive SQL data is at risk because -

  • to use Access means ASP.NET 1.x has to run at Full Trust
  • Full Trust means that the user can call RevertToSelf() to end impersonation and run as the worker process identity
  • most likely all the websites run in the same worker process under the same identity
  • the worker process identity will have read access to your web folders

Fortunately in ASP.NET 2.0 the Full Trust issue is more or less fixed (System.Data.OleDb and System.Data.Odbc can run under Medium Trust) but if the server is running both ASP.NET 1.x and ASP.NET 2.0 you're still not secure.

Thanks to Dominick for the time spent discussing this.

Update:

I did some poking around and found this article by K. Scott Allen which is worthwhile taking a look at.

Monday, March 06, 2006 2:27:01 AM UTC  #    -

Now Playing
Top Artists This Week
Fluff

Powered by FeedBurner
Categories
Archive
<March 2006>
SunMonTueWedThuFriSat
2627281234
567891011
12131415161718
19202122232425
2627282930311
2345678
About the author/Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2010
Kevin Kenny
Sign In
Statistics
Total Posts: 207
This Year: 3
This Month: 0
This Week: 0
Comments: 140
All Content © 2010, Kevin Kenny
DasBlog theme 'Business' created by Christoph De Baene (delarou)