Hacking the Code ASP.NET Web Application Security [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Hacking the Code ASP.NET Web Application Security [Electronic resources] - نسخه متنی

James C. Foster, Mark M. Burnett

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید








Authenticating Users




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. In this section, we will cover:







Building login forms







Using forms authentication







Using Windows authentication







Using Passport authentication







Blocking brute-force attacks








Building Login Forms
















Summary:






The login form should protect user credentials and resist attack






Threats:






Account hijacking, information leakage, SQL injection, cross-site scripting






Several years ago I sat in the hallway at a security conference watching another attendee’s laptop screen as a list of usernames and passwords slowly scrolled down an open command prompt window. I immediately recognized that he was sniffing the network, gathering user logins—something I certainly could expect at this type of security conference. But what surprised me was when I started talking to him about it, he explained that those were only passwords from the Web-based e-mail services Hotmail and Yahoo! Within 10 minutes he had collected a long list of login credentials from people logging in to their e-mail accounts across an insecure, untrusted network connection.



Indeed, it used to be very easy to sniff these credentials. Both services offered SSL versions of their login screens, but few people actually used them. Fortunately, since then Hotmail has moved to authenticating with Passport over a secure connection, and Yahoo! creates an MD5 hash of your password before sending it over the wire. But many Web sites still fail to protect users’ credentials when they log in.



Because the 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.



As you design and build a login form, keep it simple and avoid using a single form for multiple tasks. Always transmit credentials across a secure connection using SSL.







Tip



Try to establish a secure connection to the login form itself, not after users click the Login button to submit credentials. You want to assure the user that the login form is not only secure but authentic. See Chapter 4, “Encrypting Private Data,” for more information on using SSL.






Because URLs are logged by proxy servers, browser caches, and typed URL histories, it is best to use the HTTP POST with Web forms method rather than the HTTP GET method. (See Chapter 6, “Building Secure ASP.NET Applications,” for more information on creating forms.) It is important to always validate form input to prevent SQL injection and cross-site scripting attacks. (See Chapter 5, “Filtering User Input,” for more information on filtering input.)



When handling failed logins, be careful how you return error messages. For example, inexperienced programmers sometimes return different error messages for bad usernames than for bad passwords. The error message should be generic enough to prevent credential harvesting based on the error messages returned. Figure 2.1 is an example of a proper failed-login message. With different error messages for bad usernames and bad passwords, an attacker could go through a list of usernames until the error message switches from indicating a bad username to indicating a bad password. After finding a valid username, the attacker could go on to guess the password.






Figure 2.1: Generic Failed-Login Message



When auditing a login screen, the first thing you should do is view the source code for the form. In particular, look for extra hidden tags within the form that could be modified or could reveal sensitive information. The next step is to try entering invalid information into the form fields to determine what attackers can learn from the error messages. Finally, try some of the SQL injection and cross-site scripting techniques mentioned in Chapter 5, “Filtering User Input.”



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
















Summary:






Insecure authentication form settings could weaken the Web application’s security






Threats:






Account hijacking, information leakage






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. Another alternative is to use an online hash generator such as the one at www.securecode.net/HashCalc+mainl.









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/cainl 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







Warning



Because web.config files are plain hashes that do not make use of a salt, they are more vulnerable to cracking from precomputed hash lists. See Chapter 4, “Encrypting Private Data,” for more information on hashing with a salt.






When using forms authentication, remember that it only applies to those resources managed by ASP.NET. That includes any files with the extensions:







.asax







.aspx







.ascx







.ashx







.asmx







.axd







.vsdisco







.rem







.soap







.config







.cs







.csproj







.vb







.vbproj







.webinfo







.licx







.resx







.resources







.jsl







.java







.vjsproj







If you use forms authentication and request a file in a protected directory with any of these extensions, you will be forwarded to the login page. If you request a file with any other extension, you will get the file directly, with no request for authentication. For instructions on how to secure all files, see the sidebar “Mapping Non-ASP.NET Resources” later in this section.



Although forms authentication is a great improvement over features available in ASP, you still must use it carefully. Forms authentication is most secure when used with custom authentication against a SQL database, a protected data file, LDAP, or an operating system account. Storing the passwords or hashes in the web.config file itself may be safe, but it carries great risk. Another alternative is to use a custom XML file in a protected directory to handle authentication. For an example of how to implement this solution, see http://msdn.microsoft.com/_library/en-us/cpguide/html/cpconcookieauthenticationusinganxmlusersfile.asp.










Hacking the Code…Mapping Non-ASP.NET Resources




Most ASP.NET security features only protect ASP.NET resources, so you must take extra measures to protect non-ASP.NET files. To do that, you have to map these resources to the ASP.NET ISAPI filter using IIS 5 or IIS 6.



Using IIS 5:







In the Internet Services Manager, select the properties for the application to configure.







From the tab, click the button.







From the tab, click the button.







Click the button, and locate the .NET ISAPI filter (typically located at C:\Winnt\Microsoft.NET\Framework\<version>\aspnet_isapi.dll).







Enter the extension you want to map to ASP.NET (or enter to map all extensions).



Using IIS 6:







In the Internet Services Manager, select the properties for the application to configure.







From the tab, click the button.







From the tab, click on the button.







Click the button and locate the .NET ISAPI filter (typically located at C:\Winnt\Microsoft.NET\Framework\<version>\aspnet_isapi.dll).







Enter the extension you want to map to ASP.NET.







To add a wildcard mapping, click from the tab, and enter the path to the .NET ISAPI filter.



Note that adding wildcard application maps cause ASP.NET to handle all file extensions. This will work fine for most static content, but you will not be able to do this for extensions mapped to other applications, such as Perl or Cold Fusion. Wildcard mappings might have some effect on server performance, depending on the type of content in your Web directories. ASP.NET does have a special handler for static content, but you might want to run performance tests for your particular Web site.



















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.








Using Windows Authentication
















Summary:






Windows authentication can be secure, but only when configured properly






Threats:






Account hijacking, man-in-the middle, information leakage






In addition to Forms authentication, ASP.NET provides support for native IIS authentication methods, collectively referred to as Windows Authentication. When Windows Authentication is used, the browser prompts the user for a username and password, as shown in Figure 2.7.






Figure 2.7: Windows Authentication Prompt



To implement Windows authentication, modify the web.config file as _follows:



<authentication mode="Windows" />
<authorization>
<deny users="?" />
</authorization>



You must then open the Internet Services Manager and select the properties for the protected content directory. Uncheck anonymous access and select an authentication method.



IIS provides four standard methods for authentication:







Basic authentication







Digest authentication







Integrated Windows authentication







Client certificate mapping







Basic Authentication




Basic authentication works by prompting a Web site visitor for a username and password. This method is widely used because most browsers and Web servers support it. The benefits are:







It works through proxy servers.







It is compatible with nearly every Internet browser.







It allows users to access resources that are not located on the IIS server.







Basic authentication also has some drawbacks:







Information is sent over the network as cleartext. The information is encoded with base64 encoding (see RFC 1521 for more information on base64 encoding), but it is sent in an unencrypted format. Any password sent using basic authentication can easily be decoded.







By default, users must have the Log On Locally right to use basic authentication.







Basic authentication is vulnerable to replay attacks.







Because basic authentication does not encrypt user credentials, it is important that traffic always be sent over an encrypted SSL session. A user authenticating with basic authentication must provide a valid username and password. The user account can be a local account or a domain account. By default, the IIS server will look locally or in Active Directory for the user account. If the user account is in a domain other than the local domain, the user must specify the domain name during logon. The syntax for this process is domain name\username, where domain name is the name of the user’s domain. Basic authentication can also be configured to use user principal names (UPNs) when you use accounts stored in Active Directory.



To prevent exposing user credentials to others on the network, it is essential that you always use SSL with basic authentication. Note that basic authentication causes the browser to send user credentials to every page on the same site or within the same realm, not just the login page. If you don’t use SSL on every page, user credentials will be visible on the network. One way to prevent these credentials from being sent on unprotected content is to use a unique realm for protected and unprotected content. See Chapter 4, “Encrypting Private Data,” for more information on using SSL.



Digest Authentication




Digest authentication has many similarities to basic authentication, but it overcomes some of the problems. Digest authentication does not send usernames or passwords over the network. It is more secure than basic authentication, but it requires more planning to make it work.



Some of the similarities with basic authentication are:







Users must have the Log On Locally right.







Both methods work through firewalls.







Like all authentication methods, digest authentication does have some drawbacks:







Users can only access resources on the IIS server. Their credentials can’t be passed to another computer.







The IIS server must be a member of a domain.







All user accounts must store passwords using reversible encryption.







The method works only with Internet Explorer 5.0 or higher.







Digest authentication is vulnerable to replay attacks, to a limited extent.







Digest authentication is secure due to the way it passes authentication information over the network. Usernames and passwords are never sent. Instead, IIS uses a message digest (or hash) to verify the user’s credentials. In order for digest authentication to work, all user accounts must be stored using reversible encryption in Active Directory, which may be a potential risk. After this setting is enabled for a user account, the user’s password must be changed to create the plaintext copy.



Digest authentication does provide more security, but for most Web sites, the limitations of this method outweigh the benefits. One interesting peculiarity with IIS is that when you send authentication headers to a client, it will send the basic authentication header before the digest one. Many Internet browsers use the first header they encounter and therefore opt for the weaker basic authentication.



Integrated Windows Authentication




Integrated Windows authentication is also a secure solution because usernames and passwords aren’t transmitted across the network. This method is convenient because, if a user is already logged on to the domain and if the user has the correct permissions for the site, the user isn’t prompted for his or her username and password. Instead, IIS attempts to use the user’s cached credentials for authentication. The cached credentials are hashed and sent to the IIS server for authentication. If the cached credentials do not have the correct permissions, the user is prompted to enter a different username and password.



Depending on the client and server configuration, integrated Windows authentication uses either the Windows NT LAN Mangager (NTLM) or Kerberos for authentication. You cannot directly choose which one is used; IIS will automatically choose a method based on the server and client configuration. The Web browser and the IIS server negotiate which one to use through the negotiate authentication header. Both Kerberos and NTLM have their own advantages and disadvantages. Kerberos is faster and more secure than NTLM. Unlike NTLM, which authenticates only the client, Kerberos authenticates both the client and the server. This helps prevent spoofing. Kerberos also allows users to access remote network resources not located on the IIS server. NTLM restricts users to the information located on the IIS server only.



Kerberos is the preferred authentication method for an intranet Web server. However, the following requirements must be met for Kerberos to be used instead of NTLM:







Both the client and server must be running Windows 2000 or later.







The client must be using Internet Explorer 5 or later.







The client and server must be in either the same domain as the IIS server or in a trusted domain.







Integrated Windows authentication has a few limitations:







It works only with Internet Explorer 3.01 or later.







It does not work through a firewall. The client will use the firewall’s IP address in the Integrated Windows hash, which will cause the authentication request to fail.







Client Certificate Mapping




Client certificate mapping is the process of mapping a certificate to a user account. Certificates can be mapped by Active Directory or by IIS. Both of these methods require Secure Sockets Layer (SSL). There are three types of certificate mappings:







One-to-one mapping







Many-to-one mapping







UPN mapping







Certificate mapping is the process of linking a certificate to a specific user account. Normally, if we wanted to give a user authenticated access to the intranet, we would either create a user account or allow the user to log in using his domain account. Creating duplicate accounts is time-consuming, yet if users use their domain accounts, there is the concern that their domain passwords could become compromised.



To provide better security and reduce the administrative workload, we could choose to issue each user a certificate. Certificates can be used to verify a user’s integrity. It is actually more efficient to use a certificate than a user account because certificates can be examined without having to connect to a database. It is generally safer to distribute certificates than user accounts. Furthermore, it is much easier to guess or crack someone’s password than it is to forge a certificate.



Authenticating Users




If you are securing an intranet application for which you have control over the server and client configuration and the corresponding clients and server(s) are in the same domain, integrated Windows authentication is probably the best solution. For a public Web site, the most widely supported method is basic authentication over an SSL connection. Because basic authentication is secure only if you use SSL, you might want to enforce this policy on your server. You can do this through an HTTP module, as shown in Figure 2.8 (C#) and Figure 2.9 (VB.NET). Every time an authentication request is sent to the server, this code checks to see if the request is using basic authentication and if it is sent over an SSL connection. If both those criteria are not met, the code returns a “403.4 SSL Required error” message back to the client.









using System;
using System.Web;
using System.Security.Principal;
namespace HttpAuthModules
{
public class AuthenticationModule : IHttpModule
{
public AuthenticationModule()
{
}
public void Init(HttpApplication httpApp)
{
// Register the event handler with Application object.
httpApp.AuthenticateRequest +=
new EventHandler(this.AuthenticateRequest);
}
private void AuthenticateRequest(object obj, EventArgs ea)
{
HttpApplication objApp = (HttpApplication) obj;
HttpContext objContext = (HttpContext) objApp.Context;
// Deny access if user is using basic authentication without SSL
if (objApp.User.Identity.AuthenticationType == "Basic" &&
objContext.Request.IsSecureConnection == false)
{
objContext.Response.StatusCode = 403;
objApp.Response.End();
}
}
public void Dispose()
{
}
}
}








Figure 2.8: Blocking Basic Authentication Without SSL: C#












Imports System.Web
Public Class AuthenticationModule
Implements IHttpModule
Public Sub Init(ByVal app As HttpApplication) Implements IHttpModule.Init
AddHandler app.AuthenticateRequest, AddressOf Me.AuthenticateRequest
End Sub
Public Sub Dispose() Implements IHttpModule.Dispose
End Sub
Private Sub AuthenticateRequest(ByVal obj As Object, ByVal ea As
System.EventArgs)
Dim objApp As HttpApplication
Dim objContext As HttpContext
objApp = obj
objContext = objApp.Context
' Deny access if user is using basic authentication without SSL
If objApp.User.Identity.AuthenticationType = "Basic" And _
objContext.Request.IsSecureConnection = False Then
objContext.Response.StatusCode = 403
objApp.Response.End()
End If
End Sub
End Class








Figure 2.9: Blocking Basic Authentication Without SSL: VB.NET







Tip



Note that code in an HTTP module runs only on files handled by ASP.NET. If you want ASP.NET to handle all files, follow the instructions in the sidebar “Mapping Non-ASP.NET Resources.”






Another problem with authenticating to the operating system or domain is that there is no direct control over which account is used to log in. If you provide a login box, anyone with an account on that system can try to log in. They might not be able to gain access to the resource, but they can authenticate to the server. This gives attackers the opportunity to launch brute-force attacks against privileged accounts such as Administrator.



Depending on the network and server configuration, Windows authentication might also allow relaying attacks from the Web server to other trusted domains or servers on the internal network. Windows authentication allows the user to enter a domain-qualified name in the format domain\username to authenticate to other trusted domains. If an attacker knows the name of other trusted domains that the Web server can see, he or she can potentially relay attacks by trying to authenticate to the internal domain. Basic authentication can also be configured to leverage UPNs when you use accounts stored in Active Directory, again providing more opportunity for data relay attacks.



When using Windows authentication, you might want to restrict which users can log in to the server. You can use file or URL authorization to prevent access, but this doesn’t prevent the user from trying to authenticate—it just prevents the user from accessing the content. Both of these methods enforce access based on the username, so a user must first be authenticated. If you don’t want to expose a privileged user account to a brute-force attack through your authentication mechanism, you can simply prevent that user from authenticating at all through the Web application. One way to accomplish this goal is through an HTTP module, as shown in Figure 2.10 (C#) and Figure 2.11 (VB.NET). This code checks the username whenever an authentication request is sent to see if it contains the user Administrator and returns an “HTTP 401 error” message if it does. This prevents anyone from even attempting to authenticate as Administrator.









using System;
using System.Web;
using System.Security.Principal;
namespace HttpAuthModules
{
public class AuthenticationModule : IHttpModule
{
public AuthenticationModule()
{
}
public void Init(HttpApplication httpApp)
{
// Register the event handler with Application object.
httpApp.AuthenticateRequest +=
new EventHandler(this.AuthenticateRequest);
}
public void AuthenticateRequest(object obj, EventArgs ea)
{
HttpApplication objApp = (HttpApplication) obj;
HttpContext objContext = (HttpContext) objApp.Context;
// If user identity is not administrator, return 403 code
if ( objApp.User.Identity.Name.IndexOf("administrator") >= 0)
{
objContext.Response.StatusCode = 403;
objApp.Response.End();
}
}
public void Dispose()
{
}
}
}








Figure 2.10: Blocking Administrator Logins: C#












Imports System.Web
Public Class AuthenticationModule
Implements IHttpModule
Public Sub Init(ByVal app As HttpApplication) Implements IHttpModule.Init
AddHandler app.AuthenticateRequest, AddressOf Me.AuthenticateRequest
End Sub
Public Sub Dispose() Implements IHttpModule.Dispose
End Sub
Public Sub AuthenticateRequest(ByVal obj As Object, ByVal ea As _ System.EventArgs)
Dim objApp As HttpApplication
Dim objContext As HttpContext
objApp = obj
objContext = objApp.Context
' If user identity is not administrator, return 403 code
If objApp.User.Identity.Name.IndexOf("administrator") >= 0 Then
objContext.Response.StatusCode = 403
objApp.Response.End()
End If
End Sub
End Class








Figure 2.11: Blocking Administrator LoginsVB.NET






Security Policies






Always use SSL with every page that uses basic authentication.







Use unique realms for protected and unprotected content.







Use Integrated Windows authentication if possible in an intranet environment.







Block privileged users from brute-force attacks by preventing them from authenticating.








Using Passport Authentication
















Summary:






Passport authentication has many strengths, but you must also be aware of the risks






Threats:






Account hijacking






In mid-1999, Microsoft released its Passport service, a single sign-on and e-commerce solution for the Web. Despite widespread privacy and security concerns, the Passport service is constantly growing, with support from large companies such as eBay, McAfee, and Citibank.



But many consumers feel uneasy with the concept of such a large central database controlled by a private company. With so much centralized control over this data, the potential for abuse is great. Another concern is security. Microsoft’s Passport service has had problems and has not gone long enough without security flaws to prove itself a reliable service.



Nevertheless, Passport does have its benefits. For consumers, it’s fewer passwords to remember; for Web sites, it involves no hassle setting up a user database. One could argue that having a single authentication service with a few flaws might even be better than a thousand poorly secured Web sites. But the risk is with the single point of failure: If someone hijacks your Passport account, that person gains access to every service you use with Passport.



One problem is that Microsoft has not proven that the service is secure; all we really have to go by is that the company says it is secure. Being a proprietary system, it has not gone through a public review. Microsoft doesn’t make much effort to publish third-party audits of the Passport services, nor does the company justify its security with details of the security measures it employs. Consequently, only time will tell us how secure Passport is. Another problem is that as more sites begin to use Passport, the more attractive it will become as a target.



The Passport login forms from different sites are not consistent in appearance or format—sometimes appearing inline, as at Hotmail.com and MSN.com; appearing on their own pages at the same site, as at eBay.com (see Figure 2.12), or appearing as a customized branded page at login.passport.net (see Figure 2.13). Depending on your operating system, you might also be prompted for a .NET Passport from a Windows dialog box or wizard. The problem with this lack of consistency is that it makes it more difficult for users to discern a real login box from a fake login box. In fact, anyone can probably put a fake .NET Passport sign-in box on a Web site and simply collect the usernames and passwords people enter.






Figure 2.12: eBay’s Passport Login Form.









Figure 2.12: Citibank’s Passport Login Form



Although Passport lets you set various parameters for security, there is no guarantee that other participating sites are going to use the same level of security. In other words, although you might choose to use more secure settings, the user’s password is no more secure than the security implemented by the least secure participating Passport site.



Despite these shortcomings, there are many uses for Passport. Web sites that use Passport for user customization or sites that do not store personal information are particularly well-suited for Passport authentication. In fact, it is beneficial for sites such as these to use Passport authentication rather than giving a user yet another username and password to have to remember. Many Web developers are not qualified to create secure account management features, and in these cases, Passport is a more secure option.



But for Web sites with sensitive financial and personal information, you should carefully consider the risks of Passport or any single sign-on mechanism. The Citibank example in Figure 2.13 says that after authenticating with .NET Passport, you’ll be asked to enter another password. Although this is a good security measure and makes up for many of Passport’s shortcomings, it makes me wonder why anyone would even bother with a single sign-on solution if you are going to make the user remember another password anyway.







Tip



Even if you do not use Passport on your site, you might still benefit from using it to help users prove their identity if they ever lose their account credentials for your Web site. Used in combination with the techniques described in Chapter 1, Passport would make for a reasonably strong verification of user identity. For example, if a user forgets her password, you can have her authenticate using Passport and then send her an e-mail with further instructions on how to reset her password for your site. This way you still keep user authentication private but benefit from Passport’s centralized authentication features.






Security Policies






Avoid using Passport on Web sites that store sensitive financial and personal information.







If using Passport on a sensitive site, consider implementing additional methods to authenticate the user.








Blocking Brute-Force Attacks
















Summary:






Brute force attacks are difficult to block completely but you can limit their effectiveness






Threats:






Account hijacking, denial of service, resource starvation






As we saw in Chapter 1, a brute-force attack is an attempt to discover a password by systematically trying every possible combination of letters, numbers, and symbols until you discover the one correct combination that works. An attacker will always discover a password through a brute-force attack, but the downside is that it could take years to find it. Depending on the password’s length and complexity, there could be trillions of possible combinations. To speed things up a bit, a brute-force attack could start with dictionary words or slightly modified dictionary words because most people will use those rather than a totally random password. These attacks are commonly referred to as dictionary attacks or hybrid brute-force attacks. Brute-force attacks put user accounts at risk and flood your site with unnecessary traffic.



Hackers launch brute-force attacks using widely available tools that utilize wordlists and rule sets to intelligently and automatically guess user passwords. Although such attacks are easy to detect, they are not so easy to prevent. For example, many HTTP brute-force tools can relay requests through a list of open proxy servers. Since each request appears to come from a different IP address, you cannot block attacks simply by blocking the IP address. Thousands of Akamai proxy servers were leveraged in an attack of this nature against a popular e-commerce site right after the turn of the century. To further complicate things, some tools try a different username and password on each attempt, so you can’t lock out a single account for failed password attempts.







Warning



Adult Web sites are notorious targets for brute-force attacks, often seeing hundreds or thousands of unique attacks each day. Many tools are available specifically for launching brute-force attacks against adult Web sites. One technique hackers use is to collect large lists of username and password combos. The logic is that if a person has an account on one adult Web site, there is a good chance that person has an account at another site and might be using the same password on both sites. Tools such as Combomania (available at www.securibox.net/phpBB2/_dload.php?action=viewall) scour the Internet for username and password combos to quickly build combo lists. Although tools like Combomania were designed to hack adult Web sites, the concept applies to all types of Web sites.






Locking Accounts




The most obvious way to block brute-force attacks is to simply lock out accounts after a defined number of incorrect password attempts. Account lockouts can last a specific duration, such as one hour, or the accounts could remain locked until manually unlocked by an administrator. But account lockout is not the best solution, because someone could easily abuse it and lock out hundreds of user accounts. In fact, some Web sites are attacked so much that they are unable to enforce a lockout policy because they would constantly be unlocking customer accounts.



The problems with account lockouts are:







An attacker can cause a denial of service (DoS) by locking out large numbers of accounts.







Because you cannot lock out an account that doesn’t exist, only valid account names will lock. An attacker could use this fact to harvest usernames from the site, depending on realized error responses.







An attacker can cause a diversion by locking out many accounts and flooding the help desk with support calls.







An attacker can continuously lock out the same account, even seconds after it is unlocked by an administrator, effectively disabling the account.







Account lockout is ineffective against slow attacks that try only a few passwords every hour.







Account lockout is ineffective against attacks that try one password against a large list of usernames.







Account lockout is ineffective if the attacker is using a username/password combo list and guesses correctly on the first couple of attempts.







Powerful accounts such as administrator accounts often bypass lockout policy, but these are the most desirable accounts to attack. Some systems lock out administrator accounts only on network-based logins.







Even once an account is locked out, the attack may continue, consuming valuable human and computational resources.







Account lockout is sometimes effective, but only in controlled environments or in cases where the risk is so great that even continuous DoS attacks are preferable to account compromise. In most cases, however, account lockout is not the best option for stopping brute-force attacks. Consider, for example, an auction site on which several bidders are fighting over the same item. If the auction Web site enforced account lockouts, one bidder could simply lock the others’ accounts in the last minute of the auction, preventing them from submitting any winning bids. The same technique could be used to block critical financial transactions or e-mail communications.







Warning



When I talk to administrators and developers about the problems with account lockouts, their first response is to suggest increasing the number of failed attempts before locking the account. This solution does prevent someone from accidentally locking out an account, but even if you allow 20 attempts, it is simple for an attacker to lock out an account. Another suggestion I hear is to decrease the lockout time to just a few minutes. In fact, Microsoft’s Passport uses this strategy. Although this solution does limit brute-force attacks, it doesn’t completely prevent DoS attacks, because an attacker can simply lock your account again after the few minutes pass. Ultimately, you have to decide yourself what works best for your Web site.






Finding Other Countermeasures




As described, account lockouts are not always practical solutions, but because of the automated nature of brute-force attacks, there are other things you can do. First, since the success of the attack is dependent on time, an easy solution is to randomly inject pauses when checking a password. Adding even a few seconds’ pause can greatly slow a brute-force attack but will not bother most legitimate users as they log in to their accounts. The code in Figure 2.14 (C#) and Figure 2.15 (VB.NET) shows an example of how to implement this pause using an HTTP module.









private void AuthenticateRequest(object obj, EventArgs ea)
{
HttpApplication objApp = (HttpApplication) obj;
HttpContext objContext = (HttpContext) objApp.Context;
// If user identity is not blank, pause for a random amount of time
if ( objApp.User.Identity.Name != ")
{
Random rand = new Random();
Thread.Sleep(rand.Next(minSeconds, maxSeconds) * 1000);
}
}








Figure 2.14: Password Authentication Delay: C#












Public Sub AuthenticateRequest(ByVal obj As Object, ByVal ea As 
System.EventArgs)
Dim objApp As HttpApplication
Dim objContext As HttpContext
Dim ran As Random
objApp = obj
objContext = objApp.Context
' If user identity is not blank, pause for a random amount of time
If objApp.User.Identity.Name <> " Then
ran = New Random
Thread.Sleep(ran.Next(ran.Next(minSeconds, maxSeconds) * 1000))
End If
End Sub








Figure 2.15: Password Authentication Delay VB.NET



Note that although adding a delay could slow a single-threaded attack, it is less effective if the attacker sends multiple simultaneous authentication requests.



Another solution is to lock out an IP address with multiple failed logins. The problem with this solution is that you could inadvertently block large groups of users by blocking a proxy server used by an ISP or large company. Another problem is that many tools utilize proxy lists and send only a few requests from each IP address before moving on to the next. Using widely available open proxy lists at Web sites such as http://tools.rosinstrument.com/proxy/, an attacker could easily circumvent any IP blocking mechanism. Because most sites do not block after just one failed password, an attacker can use two or three attempts per proxy. If the attacker has a list of 1,000 proxies, he can attempt 2,000 or 3,000 passwords without being blocked. Nevertheless, despite this method’s weaknesses, many Web sites—adult Web sites in particular—do choose to block proxy IP addresses because they are so often attacked. Companies such as Pennywize (www.pennywize.com) offer solutions to help block brute-force attacks.



One simple yet surprisingly effective solution is to simply design your Web site to not use predictable behavior for failed passwords. For example, most Web sites return an “HTTP 401 error” code with a password failure, but some sites instead return an “HTTP 200 SUCCESS” code but direct the user to a page explaining the failed password attempt. This fools some automated systems, but it is also easy to circumvent. A better solution might be to vary the behavior enough to eventually discourage all but the most dedicated hackers. You could, for example, use different error messages each time or sometimes let a user through to a page and then prompt him again for a password.







Tip



Some automated brute-force tools allow the attacker to set certain trigger strings to look for that indicate a failed password attempt. For example, if the resulting page contains the phrase “Bad username or password,” the tool would know the credentials failed and would try the next in the list. A simple way to fool these tools is to also include those phrases as comments in the HTML source of the page they get when they successfully authenticate.






After one or two failed login attempts, prompt the user not only for the username and password but also to answer a secret question. This not only causes problems with automated attacks, it prevents an attacker from gaining access, even if they do get the username and password correct. You could also detect high numbers of attacks systemwide and under those conditions prompt all users for the answer to their secret questions.



Other techniques you might want to consider are:







For advanced users who want to protect their accounts from attack, give them the option to allow login only from certain IP addresses.







Assign unique login URLs to blocks of users so that not all users can access the site from the same URL.







Use a CAPTCHA to prevent automated attacks (see the sidebar “Using CAPTCHAs”).







Instead of completely locking down an account, place it in a lockdown mode with limited capabilities.







Most of these techniques can sometimes be circumvented, but by combining several techniques, you can protect your site from many brute-force attacks. It might be difficult to stop an attacker who is determined to specifically obtain a password on your site, but these techniques certainly can be effective against many attackers, including just about all novice attackers. These techniques also



require more work on the attacker’s part, which gives you more opportunity to detect the attack and maybe even identify the attacker. Intrusion detection systems provide realized value in situations such as these.










Hacking the Code…Using CAPTCHAS




A completely automated public Turing test to tell computers and humans apart, or CAPTCHA, is a program that allows you to distinguish between humans and computers. First widely used by Alta Vista to prevent automated search submissions, CAPTCHAs are particularly effective in stopping any kind of automated abuse, including brute-force attacks. They work by presenting some test that is easy for humans to pass but difficult for computers to pass; therefore, they can conclude with some certainty whether there is a human on the other end.



For a CAPTCHA to be effective, humans must be able to answer the test correctly as close to 100 percent of the time as possible. Computers must fail as close to 100 percent of the time as possible. Ez-gimpy (www.captcha.net/cgi-bin/ez-gimpy), perhaps the most commonly used CAPTCHA, presents the user with an obscured word that the user must type to pass the test. But researchers have since written pattern recognition programs that solve ez-gimpy with 92 percent accuracy. Although these researchers have not made their programs public, all it takes is one person to do so to make ez-gimpy mostly ineffective. Researchers at Carnegie Mellon’s School of Computer Science continually work to improve and introduce new CAPTCHAs (see www.captcha.net/captchas).



If you are developing your own CAPTCHA, keep in mind that it is not how hard the question is that matters—it is how likely it is that a computer will get the correct answer. I once saw a CAPTCHA with a picture of three zebras, and the user was presented with a multiple-choice question asking how many zebras were in the picture. To answer the question, you clicked one of three buttons. Although it would be very difficult for a computer program to both understand the question and interpret the picture, the program could just randomly guess any answer and get it correct 30 percent of the time. Although this might seem a satisfactory level of risk, it is by no means an effective CAPTCHA. If you run a free e-mail service and use a CAPTCHA such as this to prevent spammers from creating accounts in bulk, all they have to do is write a script to automatically create 1,000 accounts and expect on average that 333 of those attempts will be successful.



Nevertheless, a simple CAPTCHA may still be effective against brute-force attacks. When you combine the chance of an attacker sending a correct username and password guess with the chance of guessing the CAPTCHA correctly, combined with other techniques described in this chapter, even a simple CAPTCHA could prove effective.

















Although brute-force attacks are difficult to stop completely, they are easy to detect because each failed login attempt records an HTTP 401 status code in your Web server logs. It is important to monitor your log files for brute-force attacks—in particular the intermingled 200 status codes that mean the attacker found a valid password.



Here are conditions that could indicate a brute-force attack or other account abuse:







Many failed logins from the same IP address







Logins with multiple usernames from the same IP address







Logins for a single account coming from many different IP addresses







Excessive usage and bandwidth consumption from a single use







Failed login attempts from alphabetically sequential usernames or _passwords







Logins with a referring URL of someone’s mail or IRC client







Referring URLs that contain the username and password in the format http://user:password@www.example.com/login







If protecting an adult Web site, referring URLs of known password-sharing sites







Logins with suspicious passwords hackers commonly use, such as ownsyou (ownzyou), washere (wazhere), zealots, hacksyou, and the like (see www.securibox.net/phpBB2/viewtopic.php?t=8563)







Security Policies






Use account lockout policies only in controlled environments or where the risk of a compromised account is greater than the risk of continual DoS attacks.







Insert random delays in the authentication process to slow brute-force attacks.







Consider blocking IP addresses with multiple failed login attempts, but take into consideration the impact of blocking a proxy used by multiple clients.







Vary responses to both failed and successful password authentication.







Ask users to answer their secret questions after seeing multiple failed logins.







Provide user options to limit account login to specific IP addresses.







Use unique login URLs for different blocks of users.







Use a CAPTCHA to prevent automated attacks.







Limit an account’s capabilities if an attack is suspected.







/ 96