Protect Database Connections with .NET Framework 4.5's SecureString

Offer better security with the SqlCredential and SqlConnection objects in .NET Framework 4.5

One problem with using a connection string to connect to a database or data store is that you often have to provide database login credentials to establish the connection. You have to take responsibility for keeping the credentials secure and safe, but embedding these credentials in the connection string makes them inherently insecure because they're stored in memory for a short time and might be discovered. This problem can be avoided with Integrated Windows Authentication (IWA). Microsoft strongly recommends using IWA when you can, but that's not always possible for several scenarios such as when an application is accessing the database from outside the domain.

Another problem is that regular .NET strings aren't secure. Strings are immutable after you create them, and you can't schedule strings for garbage collection after you're finished with them. This limitation means that the string is at risk of exposure through memory scans and other attacks, including reading the clear text from the pagefile or memory dumps.

These problems are addressed with SecureString objects, which were originally introduced in the .NET Framework 2.0. The text value of a SecureString is automatically encrypted using the Data Protection API (DPAPI). You can modify a SecureString's value until you change permissions to read-only using the MakeReadOnly method. In addition, you can immediately delete the string from memory when the app is finished with the string or during regular processing for the garbage collector. For even more protection, a SecureString is pinned in memory so that it can't be moved or copied. Also, you can't directly set a SecureString's value to a string because this would require the password or other sensitive information to exist in memory. Instead, you have to set the value of the secure string one character at a time, as there's no other secure means to set the value. Although this feature makes a SecureString inconvenient to use, it also makes your strings more secure.

A SecureString can go a long way toward protecting login credentials in memory, but there hasn't been a way to use SecureStrings with connection strings. That situation will change with the .NET Framework 4.5, which introduces the SqlCredential object and adds support to the SqlConnection object for secure credentials. SqlCredential works by letting you provide the credentials for a connection separately from the connection information. For example, you can set the text value of a SecureString to the password and initialize a SqlCredential object by using the same SecureString. Then you can set the new SqlConnection object's Credential property to the SqlCredential object and connect to the database.

The code in Figure 1 shows how a SecureString might work with connection strings in the .NET Framework 4.5. Imagine that you're prompting the user for a username and password. You can use the SecurePassword property from the PasswordBox class to securely create the SecureString, change the string's permissions to read-only, and use the string to create the SqlConnection object. You can either pass the credential as the second argument to a new constructor for the SqlConnection object or use its Credential property as the code in Figure 1 shows. Microsoft also recommends setting the PersistSecurityInfo property to false in the connection string so that the credential isn't available as a part of the connection. Note that the PersistSecurityInfo property is set to false by default.

Figure 1: Using the SqlConnection object's Credential property

SecureString password = txtPassword.SecurePassword;
password.MakeReadOnly();

SqlCredential credential = new SqlCredential(userName, password);

using (SqlConnection cn =
    new SqlConnection("Server=(local);Initial Catalog=SecretStuff;"))
{
    cn.Credential = credential;
    cn.Open();
    // Use the connection
} 

One problem that you might face is that a different credential that's used with an unchanged connection string will use a different connection pool. However, connections that use the same connection string with the same credential will use the same connection pool. This situation isn't really different from the way things are now because if you provide a different username or password in the connection string, then ADO.NET won't share the connection in a connection pool. The only difference is that the whole scheme now understands separate credentials.

Overall, SecureStrings in the .NET Framework 4.5 will be a great new feature that will help make applications that connect to databases more secure. And this feature is another reason to eagerly await the release of the .NET Framework 4.5.

Hide comments

Comments

  • Allowed HTML tags: <em> <strong> <blockquote> <br> <p>

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
Publish