Secure Authentication using ASP.NET (avoid Account hijacking, information leakage )
Post date: Jul 19, 2011 2:43:52 AM
The Web login screen is a chokepoint that forces a user to prove his or her identity by providing a valid username and password. It is important to carefully plan this login screen so that you can be sure of the user’s identity.
Login form plays such an important role in authenticating users, it is important to protect the form itself from flaws. A poorly written login form is vulnerable to password sniffing, information leakage, and phishing. Furthermore, the form itself may be vulnerable to flaws such as SQL injection and cross-site scripting.
Building Login Forms
When designing a login form, do not use hidden form fields to pass sensitive information. An attacker might be able to modify these hidden fields to gain unauthorized access or view them to gather information that will assist an attack. The following is an example of a hidden form field that might be vulnerable to attack:
<form method="POST"> <input type="text" name="txtUsername"></p> <p><input type="text" name="txtPassword"></p> <input type="hidden" name="AdminArea" value="False"> <p><input type="submit" value="Submit" name="B1"></p> </form>
Security Policies
Always transmit login criteria over an SSL connection.
Use the HTTP POST method for sending form data.
Always validate form input.
Do not rely on hidden form fields to transfer data, because they can be modified by the client and may reveal sensitive information.
Never reveal too much information in failed-login error messages.
Using Forms Authentication
Thousands of poorly written ASP Web site login authentication schemes are implemented all over the world. Programmers consistently make the same security mistakes, especially when they are not properly trained in secure coding practices. ASP.NET introduces a new concept called forms authentication. Even though it is still not perfect, forms authentication at least provides a reasonably strong framework from which programmers can build secure login mechanisms.
Forms authentication provides good security and is very easy to use: Create a login page and change some settings in the web.config file. But its ease of use may also lead to poor security practices.
The biggest problem is that it allows you to add usernames and passwords right in the web.config file, even allowing you to use plain, unencrypted passwords, as shown in Figure 2.2.
You can choose to store MD5 or SHA-1 hashes in the web.config file, as shown in Figure 2.3, but ASP.NET provides no easy method to create hashes of your passwords. Consequently, many developers will choose plaintext passwords simply because it is easier. The developers may intend to later encrypt these passwords, but it never seems to gain priority in their hectic schedules. If you set passwords in your web.config file, go ahead and use MD5 or SHA-1 right from the beginning.
<credentials passwordFormat="Clear"> <user name="Alice" password="test123"/> <user name="Bob" password="dragon"/> <user name="Charlie" password="superman"/> <user name="David" password="letmein"/> </credentials>
Figure 2.2: Cleartext Passwords in Web.config
<credentials passwordFormat="SHA1"> <user name="Alice" password="7288EDD0FC3FFCBE93A0CF06E3568E28521687BC"/> <user name="Bob" password="AF8978B1797B72ACFFF9595A5A2A373EC3D9106D"/> <user name="Charlie" password="18C28604DD31094A8D69DAE60F1BCD347F1AFC5A"/> <user name="David" password="B7A875FC1EA228B9061041B7CEC4BD3C52AB3CE3"/> </credentials>
Figure 2.3: Passwords Encrypted with SHA-1
Use the C# code shown in Figure 2.4 or the VB.NET code shown in Figure 2.5 to compile a command-line utility to
create password hashes.
using System; using System.Web.Security; namespace Chapter02 { // Add System.Web to your references class PassHash { [STAThread] static void Main(string[] args) { string sMethod, sPass, sOut; if (Environment.GetCommandLineArgs().Length < 3) { ShowHelp(); } else { sMethod = Environment.GetCommandLineArgs()[1].ToUpper().Substring(1,
Environment.GetCommandLineArgs()[1].Length - 1); sPass = Environment.GetCommandLineArgs()[2]; if ((sMethod == "SHA1" || sMethod == "MD5") && sPass.Length > 0) { sOut = FormsAuthentication.HashPasswordForStoringInConfigFile (sPass, sMethod); Console.WriteLine(sOut); } else { ShowHelp(); } } } public static void ShowHelp() { Console.WriteLine("Usage: PassHash [-MD5|-SHA1] <password>"); Console.WriteLine("Example: PassHash -SHA1 letmein"); } } }
Figure 2.4: PassHash Utility: C#
Imports System.Web.Security Module PassHash Sub Main() Dim sMethod As String, sPass As String Dim sOut As String If Environment.GetCommandLineArgs.Length < 3 Then ShowHelp() Else sMethod = UCase(Right(Environment.GetCommandLineArgs(1), _ Environment.GetCommandLineArgs(1).Length - 1)) sPass = Environment.GetCommandLineArgs(2) If (sMethod = "SHA1" Or sMethod = "MD5") And sPass.Length Then sOut=FormsAuthentication.HashPasswordForStoringInConfigFile(sPass, _
sMethod) Console.WriteLine(sOut) Else ShowHelp() End If End If End Sub Function ShowHelp() Console.WriteLine("Usage: PassHash [-MD5|-SHA1] <password>") Console.WriteLine("Example: PassHash -SHA1 letmein") End Function End Module
Figure 2.5: PassHash Utility: VB.NET
Some would argue that it is perfectly safe to use plaintext passwords in the web.config because ASP.NET prevents outside users from viewing this file. This is true to some extent; however, experience has taught us that those files are not always secure. In the future someone may discover a flaw in ASP.NET that allows viewing web.config files, or someone might access the file through other methods such as a poorly configured file share or FTP server. Too many developers have learned the hard way that you cannot guarantee that files on a server are safe from viewing.
But even if you do use MD5 or SHA-1 hashes, these too can be cracked through a dictionary or brute-force attack. Tools such as Cain & Abel at www.oxid.it/cain.html are able to crack MD5 and SHA-1 hashes. Although this method can be very slow with strong passwords, Cain can usually crack common passwords such as those shown in Figure 2.6 in a matter of minutes. You should weigh the risk of relying on web.config files to store security credentials before you roll any Web application to a production system.
Figure 2.6: Cain & Abel Performing a Dictionary Attack on SHA-1 Hashes
Configuring Forms Authentication
Some attributes in the Forms element of the web.config file do have some effect on security. These settings are:
name=“[cookie name]” Select a unique name that does not conflict with other form names.
protection=“[All|None|Encryption|Validation]” Although some of the settings might offer better performance, you should always set this to All to gain maximum cookie protection.
timeout=“[minutes]” This is the timeout in minutes for a cookie to be valid, measured from the time of the last request. The default value is 30 minutes, but you might want to select a shorter timeout, such as 10 or 15 minutes.
requireSSL=“[true|false]” This setting, when set to true, will mark the cookie as secure, causing the browser to not transmit the cookie unless a secure SSL session is established. Setting this value to true and using SSL offers the only true protection from cookie hijacking.
Security Policies
Never use passwordFormat=“Clear” on a production system or _deployment.
Understand the risks of storing any cleartext credentials in the web.config file.
When using forms authentication, take extra measures to protect files not handled by ASP.NET.
Carefully plan the settings for the authorization cookie to limit exposure to hijacking.