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

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

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

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








Establishing User Credentials


User security begins with the selection of a username and password. You demonstrate to users the importance of security in the way you select or let users select usernames and passwords. In this section, you will learn about:





Enforcing strong passwords





Avoiding credentials that can be guessed easily





Preventing credential harvesting





Returning safe error messages





Limiting idle accounts






Tip


You should always require both a username and a password. Occasionally, we run across Web applications that require only a passcode to log in to the system. But consider the scenario in which a user changes his or her password and finds that the preferred code is already in use: This user now has now obtained another user’s credentials. You should always require a public credential (the username) to identify a user and a private credential (the password) to authenticate the user.







Enforcing Strong Passwords














Summary:




Use technical measures and policies to ensure strong user passwords




Threats:




Brute-force attacks, account hijacking




If passwords are the central mechanism of your application’s security, you must ensure that users have strong passwords. Establish a policy to ensure that passwords are complex enough to prevent someone guessing them easily. You can create a robust password policy by:





Enforcing a minimum password length of at least 8 characters





Not limiting the maximum password length





Requiring multiple character sets including lowercase letters, uppercase letters, numbers, and punctuation symbols





Allowing users to use any keyboard character in their passwords, including spaces





Not allowing dictionary words





Not allowing the username in any part of the password






Tip


Users are sometimes frustrated when they cannot come up with a password that meets complexity requirements. To avoid this problem, you might want to consider both length and number of character sets in the password as factors of complexity. Passwords that are longer but all lowercase are just as effective as shorter passwords that use multiple character sets. In general, adding two to four characters to the password’s length is just as effective as adding a number or punctuation symbol. A six-character password with upper- and lowercase letters and punctuation is roughly equivalent in complexity to an eight-character password that is all lowercase.






Many popular Web sites do not enforce minimum passwords lengths, or they enforce a minimum length that is much too small to be secure. Figure 1.1 shows a Web site that allows passwords of only three characters and limits the maximum length to 25 characters. The minimum length is much too short, and although 25 characters is a long password, why impose any limit at all?






Tip


Another benefit of requiring long passwords is that it reduces the number of dictionary words available to users for use as their passwords. Passwords found in a dictionary are easily cracked and should be avoided. Setting a minimum password length of eight characters eliminates all three- to seven-letter words, of which there are about 50,000 words in an English dictionary. That is 50,000 fewer easily cracked passwords.




Many users will select predictable, easily guessable passwords if you do not enforce complexity requirements. Weak passwords are vulnerable to password-guessing brute-force attacks. If passwords are not long enough and do not contain multiple character sets, the number of guesses required to brute-force the password is greatly reduced. If an attacker is able to guess a user’s password, he or she could use those user credentials to access restricted content, obtain sensitive user data, impersonate the user for a variety of purposes, delete or modify sensitive data, or even cancel the user’s account.




Figure 1.1: Example of a Weak Password Policy







Warning


Attackers often try to guess passwords of eBay users by viewing the user’s About Me page and gathering information about names of children, pets, friends, automobiles, or other interests. If an attacker can successfully guess a password, they authenticate to the account, change the password and contact information, and then list fake auctions under that user’s account. This way they take advantage of the victim’s reputation and feedback to defraud other users.




Ensuring Strong Passwords



To check password complexity, use a RegularExpressionValidator control or a CustomValidator control, as shown in Figure 1.2. This code assigns a CustomValidator to txtPassword. When validating form input, the control calls the PasswordCheck function. This is illustrated using C# in Figure 1.2 and VB.NET in Figure 1.3.








<HTML>
<HEAD>
<TITLE>Password Checker</TITLE>
<SCRIPT language="C#" Runat="Server">
public void Button_Click(object sender, EventArgs e)
{
if (Page.IsValid)
{
Response.Write("Password passes complexity requirements.");
}
else
{
Response.Write("Password does not pass complexity requirements.");
}
}
public void PasswordCheck(object sender,
System.Web.UI.WebControls.ServerValidateEventArgs eventArgs)
{
if (eventArgs.Value.Length < 8)
{
eventArgs.IsValid=false;
}
else
{
// Require any two of the following
// Change the -2 to adjust complexity requirements
// The lower the value, the stricter the requirements
if (0 -
Convert.ToInt32(Regex.IsMatch(eventArgs.Value,"[a-z]")) -
Convert.ToInt32(Regex.IsMatch(eventArgs.Value,"[A-Z]")) -
Convert.ToInt32(Regex.IsMatch(eventArgs.Value,"\\d")) -
Convert.ToInt32(Regex.IsMatch(eventArgs.Value,".{10,}")) <= -2)
{
eventArgs.IsValid = true;
}
else
{
eventArgs.IsValid = false;
}
}
}
</SCRIPT>
</HEAD>
<BODY>
<form id="Password" Runat="Server">
Password:
<br>
<asp:TextBox
id="txtPassword"
TextMode="Password"
Columns="30"
Runat="Server" />
<asp:CustomValidator
runat="server"
ControlToValidate="txtPassword"
OnServerValidate="PasswordCheck"
ErrorMessage="Invalid password."
id="CustomValidator1" />
<p>
<asp:Button Text="Check Password"
OnClick="Button_Click"
Runat="server"
id="Button1" />
</p>
</form>
</BODY>
</HTML>







Figure 1.2: Validating Passwords Using a CustomValidator Control: C#










<HTML>
<HEAD>
<TITLE>Password Checker</TITLE>
<SCRIPT language="C#" Runat="Server">
Sub Button_Click(s As Object, e As EventArgs )
If Page.IsValid Then
Response.Write("Password passes complexity requirements.")
Else
Response.Write("Password does not pass complexity requirements.")
End If
End Sub
Sub PasswordCheck(oSource as Object, oArgs as ServerValidateEventArgs)
If oArgs.Value.Length < 8 Then
oArgs.IsValid=False
Else
''''''''Require any two of the following
''''''''Change the -2 to adjust complexity requirements
''''''''The lower the value, the stricter the requirements
If Regex.IsMatch(oArgs.Value,"[a-z]") + _
Regex.IsMatch(oArgs.Value,"[A-Z]")+ _
Regex.IsMatch(oArgs.Value,"\d") + _
Regex.IsMatch(oArgs.Value,".{108,}") <= -2 Then
oArgs.IsValid = True
Else
oArgs.IsValid = False
End If
End If
End Sub
</SCRIPT>
</HEAD>
<BODY>
<form id="Password" Runat="Server">
Password:
<br>
<asp:TextBox
id="txtPassword"
TextMode="Password"
Columns="30"
Runat="Server" />
<asp:CustomValidator
runat="server"
ControlToValidate="txtPassword"
OnServerValidate="PasswordCheck"
ErrorMessage="Invalid password."
id="CustomValidator1" />
<p>
<asp:Button Text="Check Password"
OnClick="Button_Click"
Runat="server"
id="Button1" />
</p>
</form>
</BODY>
</HTML>







Figure 1.3: Validating Passwords Using a CustomValidator Control: VB.NET







Warning


The most obvious way to hack weak passwords is to simply use a brute-force attack against the Web application. Any of the tools at http://neworder.box.sk/codebox.links.php?key=wwwcrks are useful for password cracking. If the Web application uses an HTML form for _password entry, you might need to use a tool such as Elza (www._securityfocus.com/tools/1127). Of course, you will need some wordlists, which you can find at www.gattinger.org/wordlists/downloadl or http://neworder.box.sk/codebox.links.php?key=passdict.




Security Policies





Ensure that passwords are at least eight characters long. They can be as long as the operating system or application will allow.





Require at least two character sets, and let users include any keyboard character in the password.





The password must not be a dictionary word and must not contain the username.






Avoiding Easily Guessed Credentials














Summary:




Usernames or passwords that are easy to guess expose accounts to attack




Threats:




Brute-force attacks, password guessing, account hijacking




One of the most prevalent security holes in the history of computers is the selection of easily guessed passwords. Despite years of password advice, users and sometimes administrators continue to use passwords such as password, letmein, or simply leaving passwords blank. One Web services company had its salespeople assign passwords to new customers. The salespeople made no effort to come up with secure passwords, and customers made no effort to change their default passwords. After two years in business, they had 200 customers, all with the same password: dragon.


Several years ago I created an account at a now-defunct online auction site. The registration process never asked for a password, but instead the site owners e-mailed me an automatically generated password, which was my username plus the number 22 at the end. Of course, they recommended that I change my password once I had logged into my account the first time, but they didn’t explain how to do that. Curious about how many users actually changed their passwords, I tried logging in as other users, appending the number 22 to the end of the username as each user’s password. That didn’t work, but I tried 11, 33, 44, and so forth, and was quickly able to guess passwords of nearly any account on the system.


The lesson: If you automatically create passwords for your users, expect that few of them will ever change the default password, unless doing so is enforced on the first logon sequence. Therefore, if you create passwords for users, be sure to use a strong random password algorithm that does not create predictable passwords. One example of a strong password generator is the Pafwert tool, available at www.xato.com/pafwert.






Tip


Your choice of explanatory words can affect how users select passwords. For example, avoid asking for a PIN, which many people associate with an ATM machine, perhaps influencing them to select four-digit numeric passwords. Instead, ask for a passphrase or, as one site puts it, “a very long password.”




A common problem with many free or shareware CGI scripts such as Web forums or shopping carts is that they have administrative functions with default passwords. If you provide such an application, simply do not provide default credentials, but do allow users to create the initial password through the installation process.


Just as troublesome as easily guessed passwords are easily guessed usernames. Usernames are not meant to be secret the way passwords are, but you should try to limit other people’s ability to guess any username, because they all follow a sequential or predictable pattern. (See the section “Preventing Credential Harvesting” for more detail on credential harvesting.)


It is also important to avoid common default administrative account names such as administrator, admin, system, or operator. Password lockout policies sometimes do not apply to administrative accounts and therefore are attractive targets for brute-force or other attacks.






Warning


If you allow users to select their own usernames, be sure to block official-sounding names such as administrator, support, root, postmaster, abuse, Webmaster, security, and so forth. A hacker who creates an account with one of these names might be able to social-engineer other users, tricking them into revealing their passwords.




Easily guessed, predictable, or default passwords are vulnerable to password guessing and brute-force attacks, as are easily guessed usernames. Predictable or default passwords may result in the compromise of a large number of accounts. Some common CGI scripts use default passwords, and an attacker could use a search engine to locate vulnerable sites.


Design your system so that users set their passwords the first time they use the account or application. Use randomly generated passwords only if necessary and to allow users to initially log on to their accounts, after which the application forces them to change their passwords. Avoid designing a system that expects the username or password to follow any specific pattern.


Also avoid any code that automatically generates usernames or passwords, unless you take extra steps to avoid predictable patterns. Allow users to select their own usernames and passwords whenever possible.


Security Policies





Do not allow customer service personnel to select passwords for _customers.





If randomly generating passwords, do not follow a predictable pattern or base the password on the username.





Never use default passwords on any system.





Do not use predictable or sequential user account names.





Do not use obvious names for administrative accounts.






Preventing Credential Harvesting














Summary:




Credential harvesting exposes users to a variety of attacks




Threats:




Brute-force attacks, social engineering, spamming




Several years ago I received a phone call. The gentleman on the other end called me by name and said he was from my bank and needed to confirm my account information in their records. I was immediately suspicious, but before I had a chance to respond, he began to read off my full name and street address. But he read my address incorrectly, which happened to be the way it was listed in the phone book, tipping me off to the fact that he simply used information from the publicly available white pages to trick me into revealing other personal information. This person harvested names from the phone book to use as scam targets. Consider these risks in the following examples of credential harvesting.


Scenario: Alice’s Checking Account





Alice signs up for an account at a banking site, logs in, and notices the following URL:


http://bank.example.com/userid=2184&account=checking




Wondering how secure this bank application really is, Alice changes the userid parameter to this:


http://bank.example.com/userid=2000&account=checking




She now finds she is looking at someone else’s checking account ledger. Taking the concept one step further, she tries the following:


http://bank.example.com/userid=1&account=checking




She finds this is a test account, so she tries userid=2, which turns out to be the account of a member of the bank’s board of directors.





In this scenario, Alice finds a flaw in the application and uses the predictably sequential user ID to hop to other accounts.


Scenario: The Spam King



Bob, a well-known spammer, has written a script to crawl through the thousands of Web pages every day at all the popular auction sites. On each page his script extracts the username of every auction user it finds. After collecting several million account names, he takes the lists and combines each username with each of the most common e-mail and Internet service providers: hotmail.com, msn.com, juno.com, aol.com, earthlink.net, yahoo.com, and so forth.


Next Bob sends out an e-mail to every one of these combined addresses and tracks which accounts are valid. When all is done, he has well over a million valid e-mail accounts. Of course, the first spam e-mail he sends out is one offering a million valid e-mail addresses for the low price of $99.


Scenario: Chuck the Hacker



Chuck is a hacker. He steals identities and financial information from unsuspecting e-commerce customers. He knows that one large retailer’s Web site allows customers to save their credit card information to make future purchases more convenient. Chuck wants to break into customer accounts and grab this stored credit card information.


For his first attempt, he makes a small list of common usernames and passwords and tries a scripted brute-force attack against the Web site. It doesn’t take long for him to realize that this site locks out accounts once a user enters five bad passwords in a row. But there’s another way to brute-force passwords: Instead of trying a lot of passwords against one account, he can try one or two common passwords against many different user accounts. Statistically, he knows that if he tries a few common passwords against enough accounts, he will get a match.


Now the only problem is how to collect account names. To do this, he writes a script to sign up for accounts using random but common usernames. The script fills in and submits the signup form and watches for the message, “Sorry, that username is already in use.” If he gets that message, the script saved the username. If not, it cancelled the session and started again with the next name.


After several hours, the script gathers several thousand usernames from this busy Web site. He takes that list and feeds it into his brute-force script, which eventually finds three accounts with the password: asdf. Three accounts might not be a huge score, but he now has the scripts and runs them every day, changing them slightly each time to turn up more results.


Limiting Credential Exposure



By harvesting usernames, an attacker might be able to collect e-mail addresses for spamming, attempt to trick other users into revealing passwords using social-engineering techniques, attempt brute-force attacks across multiple accounts, or exploit other weaknesses in an application. Stopping credential harvesting is really just a matter of not showing usernames and not using predictable credentials. However, some Web sites are completely based on user credentials, so you must use a variety of measures to limit credential exposure.


Design the system so that the username is not the database primary key. This solution allows users to change their usernames without losing important account information or history. One technique to protect usernames is to allow users to create one or more aliases that are not used to log in to the account. Avoid usernames that are sequential or that follow predictable patterns. If connecting users to external accounts, such as checking accounts, do not use the checking account numbers as user IDs, because these account numbers are often sequential and an attacker could easily discover this information.






Warning


Allowing users to change their usernames or allowing aliases can, in some instances, facilitate abuse. You should carefully consider the implications of allowing username changes or aliases to determine if doing so is appropriate for your application. One forum Web site, for example, allows you to change your username, but only once a month, to prevent account abuse. However, nothing prevents abusers from simply creating new accounts.




The best way to prevent username harvesting is to simply never show usernames on your site. However, if this is not practical for your Web application, you can try fooling some automated harvester scripts by varying the encoding used to write the usernames.


Another important guideline is to avoid passing the username as a query string parameter to prevent it from showing up in browser histories, proxy logs, and HTTP referer [sic] headers of other sites. Consider the following URLs that may appear in another Web site’s Web logs.


Here’s a poor example:


www.example.com/inbox.aspx?userid=mburnett&folder=inbox


Here’s a better example:


www.example.com/inbox.aspx?session=3FAC-FF2E-8B1C-722A-391D


In this example, the latter is more secure because the URL contains no identifying information.


Security Policies





Never use an e-mail address as the username, and avoid otherwise revealing user e-mail addresses.





Avoid public user directories and white pages.





Allow users to change their usernames when necessary.





Allow users to assign one or more public aliases to their accounts.





Allow for the detection of brute-force or harvesting attacks.






Limiting Idle Accounts














Summary:




Idle accounts make easy targets for hackers




Threats:




Account hijacking




If you are a hacker and want to hijack someone’s Web site account, what type of account would you go after? You certainly do not want an account that someone uses every day, but you also don’t want an account that someone never uses.


Once an attacker gains control of an account, he or she may change the password and completely lock out the legitimate user. Hackers have many motivations for taking over someone else’s account. For example, they could use a hijacked auction account to list fake auctions or use a PayPal account to make fraudulent purchases.


Idle accounts are a security risk because:





The account owner might not be aware of recent activity or changes in account information.





Passwords could be old.





Users might not even be aware that they have an online account.





A couple years ago, hackers penetrated a banking Web site and gained access to the bank’s entire database. The hackers used their knowledge of electronic funds transfers to move funds to other online financial accounts. Some account holders noticed the problem and reported the transfers to the bank. The bank immediately reviewed all recent electronic transfers and contacted customers to find out if the transactions were legitimate or not. Most customers were surprised by the breach, but many of them were also surprised to find out that they even had online accounts that the bank had automatically created for them.


Users are often the best ones to spot fraud, but not with idle accounts. One travel agent found that she could transfer accrued air miles from one customer to another. She found some seldom-used accounts that had high air-mile balances and transferred small amounts from each to the account of a relative, thinking the customers would not notice the change. However, she was not aware that the airline sent e-mails to the customers confirming any air-mile transfers. Several customers complained, and the company quickly tracked down the agent responsible for the transfers. This company side-stepped the idle account problem by following up with an e-mail to users.


Online accounts are potentially dangerous, especially those that deal with financial transactions. An attacker can potentially steal and abuse the identity of a legitimate account. If users are not aware of the breach, an attacker can sometimes access the account for an extended amount of time without detection.


Design the system to track account activity and aging, and provide a method for placing an idle account on hold without completely closing the account, as shown in Figure 1.4. Clearly define how and when users receive notification of account changes or transactions, and provide a clear method for users to report suspicious or fraudulent transactions.




Figure 1.4: Expiring Idle Accounts


Centralize the code for account changes and transactions so that you have an integrated location for recording, analyzing, and notifying users of these actions. Develop a process to suspend and eventually purge idle accounts.






Tip


Many Web applications have some indications of a user’s Web activity. For example, some Web forums will tell you the date of a user’s last post and auction, or classified ad sites often show a history of what a user has bought or sold.




Security Policies





Put an account on hold after it sits idle for an extended period of time, requiring a simple reactivation procedure similar to a password retrieval process.





Avoid revealing any information to others that indicates that an account is idle.





Notify users via e-mail, letter, or other means after changing any account information or after performing significant transactions in case the action was not initiated by the users.





Use antifraud techniques such as monitoring account activity for anomalies.





Do not automatically activate online account access for all your customers with offline accounts.





/ 96