Sunday, August 01, 2004 12:29 AM bart

ASP.NET Security - The FAQ - part 2

Part 2 - Best practices for storing secrets and other cool stuff (regarding setup etc)

In this second part of my ASP.NET Security FAQ I'm going to cover the "storing secrets securely" theme and I'm going to tell something about other nices and useful features that have to do with security.

Question 1: What about storing secrets that are needed in your application?

People often ask "where is the best place to store a DSN (data source name) containing a password?" or an analogue question regarding the storage of some secret. Of course it's a best practice to put this string somewhere in a shared location so that all files of your application can access it. The obvious solution is to use the web.config file and create a section as follows:

<configuration>
   <add key="dsn" value="server=myserver;uid=myuser;pwd=Passw0rd!;database=MyDb" />
</configuration>

However, when telling this to people the answer is bounced back once again: is this safe? Then answer is not as easy as yes or no. First of all, it's safe in the sense that the .config file is mapped to the HttpForbiddenHandler of ASP.NET in the machine.config file, so nobody can download this file through a web request (luckily!). The only people who can read the file are you as the web developer and of course the administrator of the machine. In some cases this is not a problem (in cases where the web server admin is also the DBA of the database server, so he knows these secrets as well) but of course it's always better to make sure it's safe in case somebody can compromise the security of the machine to grab the file, or when the file contains other secrets as well. In my opinion, you should always go for the maximum level of security. The nice thing is that ASP.NET provides support for this, the dark side is that you'll only be able to apply the trick if you have local access to the machine.

Let me explain. The .NET Framework contains a tool that can do encryption of secrets and store these encrypted values in the registry on the server. In fact, there are several cases where this can be useful: to store secrets in a configuration section, to store the credentials of an impersonation account, to store the credentials of the processModel user and password to run ASP.NET under, to store the DSN for session state using a database server, etc. As all tools in the .NET Framework, once you get to know them, it's really easy to use and you will end up as a .NET Framework command-line tools addict :-). Here we go: the name is aspnet_setreg.exe and it can be downloaded from http://support.microsoft.com/default.aspx?scid=kb;en-us;329290:

C:\Documents and Settings\Administrator>aspnet_setreg
ASP.NET Encryption Tool Version 1.0.3705.361
Copyright (C) Microsoft Corporation 1998-2002. All rights reserved.

Usage:
------
aspnet_setreg -k: [-u:] -p:
aspnet_setreg -k: -c:
aspnet_setreg -k: -d:
aspnet_setreg -k: -g

As an intermezzo, allow me to tell you that ASP.NET Whidbey will have native support to encrypt connection strings in the web.config file but I won't cover this right now.

In fact, the tool is self-explaining. If you want to encrypt a connection string, just use something like this:

aspnet_setreg -k:"SOFTWARE\My ASP.NET App\Configuration" -c:server=myserver;uid=myuser;pwd=Passw0rd!;database=MyDb

Important: don't forget the quotes around the -k parameter value, since otherwise you'll end up with an exception :-(. Seems the tool still has some issues. However, once it has executed fine, you'll end up with a new registry key that can be found through the regedit.exe tool under HKEY_LOCAL_MACHINE\SOFTWARE\My ASP.NET App\Configuration\ASPNET_SETREG. As you'll see, the result is an encrypted string. The last thing to do is to point to the entry in the configuration file, as you're told to do by the tool:

Please edit your configuration to contain the following:

sqlConnectionString="registry:HKLM\SOFTWARE\My ASP.NET App\Configuration\ASPNET_SETREG,sqlConnectionString"

The registry: prefix tells ASP.NET to get the value (and decrypt it) from the registry.

Question 2: I just installed IIS 6 on my machine and every request to an ASP.NET file issues a 404 error message. What am I doing wrong?

This is a typical IIS 6.0 question. The answer is as easy as: "secure by default". First of all, on Windows Server 2003, IIS is not installed by default (it was on Windows 2000!). Furthermore, once it's installed through the Windows Components Setup or through the Configure Your Server tool, it will only handle static files (.htm for example). All the rest is blocked by default, including ASP, ASP.NET, etc. To enable ASP.NET on the box, you should go to the inetmgr.exe tool and go under Web Service Extensions to enable the ASP.NET ISAPI. The question people have asked me quite often as well, is why a 404 is thrown. The answer is pretty easy as well: don't tell hackers more than what's good for you :-). So, we should not tell people who want to get into the system that there are aspx files on the system, except that these are not enabled. Also a "secure by default" feature...

Question 3: I installed ASP.NET and IIS on my machine but ASP.NET does not seem to work (question for IIS versions lower than 6). What am I doing wrong?

The answer is in the question: you installed ASP.NET first and then you installed IIS. On IIS versions lower than version 6.0 (thus in Windows XP, 2000) IIS does not know anything about ASP.NET so it can't have support for it natively (also called: "backward compatibility"). The point is that the framework needs to register the ASP.NET ISAPI during the installation to tell IIS that some thing called ASP.NET is on there and that requests with extension .aspx, .asmx, etc should be sent to that "new strange thing" (strange from the IIS perspective). Fortunately, there is a tool (again!) called aspnet_regiis.exe that will help you to do this job. It's installed in the .NET Framework folder on the system (%windir%\Microsoft.NET\Framework\v1.1.4322 typically).

The most interesting command-line flags include:

  • -i to register the ASP.NET ISAPI on IIS, including scriptmaps (aspnet_client)
  • -ir to register the ISAPI only
  • -enable (for IIS 6) to enable the extension in IIS (see question 2), when combined with -i or -ir

Other flags are used to install scriptmaps on applications (needed for postbacks etc using JavaScript) and to uninstall ASP.NET again (the mapping).

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

Filed under:

Comments

# re: ASP.NET Security - The FAQ - part 2

Tuesday, August 24, 2004 2:00 PM by bart

as i remember the aspnet_setreg tool can only be used for pre-defined sections

so encrypting the dsn key in the appSettings want work if i'm correct

the only sections you can use it for are
<identity userName= password= />
<processModel userName= password= />
<sessionState stateConnectionString= sqlConnectionString= />

so basically you can not use if for the appSettings

please correct me if i'm wrong over here!!

# re: ASP.NET Security - The FAQ - part 2

Wednesday, August 25, 2004 12:14 AM by bart

Indeed, this is right and (since my post was done rather late that day) it might not be completely clear in my initial post. The sections you mention are the only ones which are supported (although this will change towards the Whidbey release of ASP.NET).

For storing secrets in <appSettings> in an encrypted way, use DPAPI as well (as ASP.NET is doing itself using aspnet_setreg). More information can be found on http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetsec/html/SecNetHT08.asp.

# re: ASP.NET Security - The FAQ - part 2

Thursday, October 07, 2004 8:22 AM by bart

am getting the following error in web.config where the connection string is read from the registry.

Format of the initialization string does not conform to specification starting at index 0

Could you please let me know what the problem is

# re: ASP.NET Security - The FAQ - part 2

Friday, November 12, 2004 4:43 PM by bart

I get the same error

Format of the initialization string does not conform to specification starting at index 0

Any joy?

# re: ASP.NET Security - The FAQ - part 2

Wednesday, December 15, 2004 7:49 PM by bart


Check the ACL on the registry keys. You'll get this if it can't access the encrypted values.

# re: ASP.NET Security - The FAQ - part 2

Tuesday, July 12, 2005 8:07 PM by bart

I get the same error, can anyone provide the solution to this problem.

# re: ASP.NET Security - The FAQ - part 2

Friday, September 02, 2005 8:06 PM by bart

I would take out the text:

<configuration>
<add key="dsn" value="server=myserver;uid=myuser;pwd=Passw0rd!;database=MyDb" />
</configuration>

at the the top of your article. This technique can only encrypt strings in select sections and is not a cover-all technique.

# re: ASP.NET Security - The FAQ - part 2

Saturday, September 03, 2005 1:24 AM by bart

Hi,

That's right indeed and things were messed up that time due to first insights in ASP.NET 2.0 features that provide this functionality. As a correction:

* aspnet_setreg.exe can be used to encrypt e.g. the DSN to the session state SQL server database
* For other encryption stuff, you need to talk to DPAPI right now

Apologies for any inconvenience whatsoever.

# re: ASP.NET Security - The FAQ - part 2

Friday, September 23, 2005 10:31 PM by bart

Format of the initialization string does not conform to specification starting at index 0