ASP.NET 2.0 Security Guidelines - Forms Authentication

From Guidance Share

Jump to: navigation, search

- J.D. Meier, Alex Mackman, Blaine Wastell, Prashant Bansode, Andy Wigley, Kishore Gopalan


Contents

Use Membership Providers Instead of Custom Authentication

In ASP.NET version 1.1, you had to implement custom logic for validating user credentials, performing user management, and managing the authentication ticket. In version 2.0, you can use the built-in membership feature. The membership feature helps protect credentials, can enforce strong passwords, and provides consistent APIs for user validation and secure user management. The membership feature also automatically creates the authentication ticket for you.

The membership feature has built-in providers for user stores including SQL Server, Active Directory, and Active Directory Application Mode (ADAM). If you want to use an existing user store, such as a non-Active Directory LDAP directory, or a user store on another platform, create a custom membership provider inheriting from the MembershipProvider abstract base class. By doing this, your application can still benefit from using the standard membership features and API and login controls.

For more information, see How To: Use Membership in ASP.NET 2.0.


Use SSL to Protect Credentials and Authentication Cookies

Use Secure Sockets Layer (SSL) to protect the authentication credentials and authentication cookies passed between browser and server. By using SSL, you prevent an attacker monitoring the network connection to obtain authentication credentials and capturing the authentication cookie to gain spoofed access to your application.


If You Cannot Use SSL, Consider Reducing Session Lifetime

If you cannot use SSL, limit the cookie lifetime to reduce the time window in which an attacker can use a captured cookie to gain access to your application with a spoofed identity. The default timeout for an authentication cookie is 30 minutes. Consider reducing this to 10 minutes as shown here.


<forms 
   timeout="00:10:00" 
   slidingExpiration="true"... />
 

The slidingExpiration="true" setting ensures that the expiration period is reset after each Web request. With the preceding configuration, this means that the cookie only times out after a 10 minute period of inactivity.

If you are in a scenario where you are concerned about cookie hijacking, consider reducing the timeout and setting slidingExpiration="false". If sliding expiration is turned off, the authentication cookie expires after the timeout period whether or not the user is active. After the timeout period, the user must re-authenticate.


Validate User Login Information

Validate user login information including user names and passwords for type, length, format, and range. Use regular expressions to constrain the input at the server. If you are not using the SqlMembershipProvider and need to develop your own queries to access your user store database, do not use login details to dynamically construct SQL statements because this makes your code susceptible to SQL injection. Instead, validate the input and then use parameterized stored procedures.

Also encode login details before echoing them back to the user's browser to prevent possible script injection. For example, use HtmlEncode as shown here.


Response.Write(HttpUtility.HtmlEncode("Welcome " + Request.Form["username"]));
 

Do Not Store Passwords Directly in the User Store

Do not store user passwords either in plaintext or encrypted format. Instead, store password hashes with salt. By storing your password with hashes and salt, you help prevent an attacker that gains access to your user store from obtaining the user passwords. If you use encryption, you have the added problem of securing the encryption key. Use one of the membership providers to help protect credentials in storage and where possible, specify a hashed password format on your provider configuration.

If you must implement your own user stores, store one-way password hashes with salt. Generate the hash from a combination of the password and a random salt value. Use an algorithm such as SHA256. If your credential store is compromised, the salt value helps to slow an attacker who is attempting to perform a dictionary attack. This gives you additional time to detect and react to the compromise.


Enforce Strong Passwords

Ensure that your passwords are complex enough to prevent users guessing other users' passwords and to prevent successful dictionary attacks against your user credential store.

By default, the ASP.NET membership providers enforce strong passwords. For example, the SqlMembershipProvider and the ActiveDirectoryMembership providers ensure that passwords are at least seven characters in length with at least one non-alphanumeric character. Ensure that your membership provider configuration enforces passwords of at least this strength. To configure the precise password complexity rules enforced by your provider, you can set the following additional attributes:

  • passwordStrengthRegularExpression. The default is "".
  • minRequiredPasswordLength. The default is 7.
  • minRequiredNonalphanumericCharacters. The default is 1.

Note The default values shown here apply to the SqlMembershipProvider and the ActiveDirectoryMembershipProvider. The ActiveDirectoryMembershipProvider also verifies passwords against the default domain password policy.


Protect Access to Your Credential Store

Ensure only those accounts that require access are granted access to your credential store. This helps to protect the credential store by limiting access to it. For example, consider limiting access to only your application's account. Ensure that the connection string used to identify your credential store is encrypted.

Also consider storing your credential database on a physically separate server from your Web server. This makes it harder for an attacker to compromise your credential store even if he or she manages to take control of your Web server.


Do Not Persist Authentication Cookies

Do not persist authentication cookies because they are stored in the user's profile and can be stolen if an attacker gets physical access to the user's computer. To ensure a non-persistent cookie, set the DisplayRememberMe property of the Login control to false. If you are not using the login controls, you can specify a non-persistent cookie when you call either the RedirectFromLoginPage or SetAuthCookie methods of the FormsAuthentication class having validated the user's credentials, as shown here.


public void Login_Click(object sender, EventArgs e)
{
  // Is the user valid?
  if (Membership.ValidateUser(userName.Text, password.Text))
  {
       // Parameter two set to false indicates non-persistent cookie
       FormsAuthentication.RedirectFromLoginPage(username.Text, false);
   }
   else
   {
       Status.Text = "Invalid credentials. Please try again.";
   }
}
 

Restrict Authentication Tickets to HTTPS Connections

Set the secure property of the authentication cookie to ensure that browsers only send authentication cookies over HTTPS connections. By using SSL, you prevent an attacker from capturing the authentication cookie to gain spoofed access to your application.

Set the secure property by using requireSSL="true" on the <forms> element as shown here.


<forms loginUrl="Secure\Login.aspx"
       requireSSL="true" ... />
 

Consider Partitioning Your Site to Restricted Areas and Public Areas

To avoid the performance overhead of using SSL across your entire site, consider using a separate folder to help protect pages that require authenticated access. Configure that folder in IIS to require SSL access. Those pages that support anonymous access can safely be accessed over HTTP connections.


Use Unique Cookie Names and Paths

Use unique name and path attribute values on the <forms> element. By ensuring unique names, you prevent possible problems that can occur when hosting multiple applications on the same server. For example, if you do not use distinct names, it is possible for a user who is authenticated in one application to make a request to another application without being redirected to that application's logon page.


Consider Setting httpOnly on the Authentication Cookie

Consider setting the httpOnlyCookies attribute on the authentication cookie. Internet Explorer 6 Service Pack 1 supports this attribute, which prevents client-side script from accessing the cookie from the document.cookie property. The System.Net.Cookie class in .NET Framework version 2.0 supports an HttpOnly property. The HttpOnly property is always set to true by forms authentication.

Personal tools