Chapter 1: Managing Users – Hacking the Code

Chapter 1

Managing Users


Users are generally a large component of Web applications and a focus point for a Web application’s security. In fact, much of a Web application’s security is intended to protect users and their private information.

Every Web application has different levels of risk and sensitivity. You must assess this risk in your organization to determine how much emphasis you put on user security. How you build your Web application will greatly affect how your users participate in security. Your users may or may not take security as seriously as you want them to, but as a security professional, it is your job to ensure that the data is properly protected.

Consider a magazine’s online article archive that is available to authenticated subscribers. The owners want to protect their copyrighted content, so they require users to authenticate to gain access to certain articles. However, readers will not store personal information on the site, and they might not be careful with security, perhaps even sharing their login information with friends to allow them to gain access to protected articles.

Perhaps more often, users are more concerned about security than are the Web site operators. Too many companies do not put a great emphasis on security until after it is too late. In March 2001, the Federal Bureau of Investigation (FBI) National Infrastructure Protection Center (NIPC) issued an advisory that hackers were targeting e-commerce and e-banking Web sites, stealing credit card information, and attempting to extort money from the site owners. The hackers exploited well-known Windows vulnerabilities, all of which were moot if the site operators had kept up to date with security patches. The NIPC advisory stated that hackers have stolen more than a million credit card numbers from 40 companies. Obviously, these companies recklessly handled sensitive user information by not taking security seriously. Their lack of diligence put private user information at risk.

Whether the weakness lies with Web site operators or users, a Web site’s security begins with the basic fundamentals of managing users.

Understanding the Threats

The primary threats covered in this chapter are:

 Brute-force attacks These attacks involve the process of discovering user credentials by trying every possible character combination. Brute-force attacks can be optimized by first trying dictionary words, common passwords, or predictable character combinations.

 Account hijacking This threat involves taking over the account of a legitimate user, sometimes denying the rightful user access to his or her account.

 Social engineering This is the process of using soft skills (rather than software or hardware techniques) to obtain sensitive information (i.e. passwords) that can be used to compromise a system.

 Spamming We’re all familiar with this one—it involves the process of sending large quantities of unwanted e-mail to a user or Web site, thus jamming Internet lines and sometimes causing servers to crash.

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


You should always require both a username and a password. Occasionally, we run across Web applications that require only a pass-code 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


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?

Figure 1.1 Example of a Weak Password Policy


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.


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.

Figure 1.2 Validating Passwords Using a CustomValidator Control: C#

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


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 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 ( Of course, you will need some wordlists, which you can find at or

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


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.


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

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

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

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

4. 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:,,,,,, 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.


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:

Here’s a better example:

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.


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.

Managing Passwords

Once a user has established a username and password, there are certain steps you must take to protect that password. In this section, you will learn about:

 Storing passwords

 Password aging and histories

 Changing passwords

Storing Passwords

Summary: Passwords stored in databases are a risk to your application as well as others
Threats: Account hijacking, potential liability

In February 2001, RealNames, a company that substituted complex Web addresses with simple keywords, announced that hackers had accessed its customer database, revealing credit card information and passwords of all its customers. A month later, Web hosting company announced that a hacker stole personal information and passwords of some 46,000 customers. Month after month since then, we have heard similar stories of hacked servers and stolen passwords.

The risk of these types of attacks can be greatly reduced with one simple strategy: Don’t store passwords in your database.

There are three ways to store passwords for later use in authenticating users:

 You can store the password itself in plaintext.

 You can encrypt the password and store the ciphertext.

 You can create a one-way hash of the password and store that hash in the database.

Obviously, the first solution is a terrible one, and the second isn’t much better: Although the password is encrypted, that encryption is based on a secret key. If the Web application must perform this encryption and decryption, the application must somehow store this secret key. If a hacker gains control of the application and the application can decrypt passwords, the hacker too can decrypt any passwords.


Hashes are called one-way functions because you can derive a hash from a password but you cannot reverse the algorithm to produce the original password from the hash. Nevertheless, hashes are not completely impervious to attack and should still be carefully protected. If an attacker can obtain a hash, he or she can go through a large list of words, run each through the same hashing algorithm, and compare the two hashes until a match is found. This method of attack became popular in password crackers such as John the Ripper and l0pht crack.

One important reason for not storing actual passwords is that by if you do so, no one at your organization ever has access to user passwords. This is important because it is not uncommon for users to reuse passwords for many different systems. If some people in your organization have access to passwords in your application, it could mean that those people also have access to a user’s accounts on other Web systems.

If passwords are stored in a database, an attacker can potentially gain access to all user accounts, even if the passwords are encrypted. This puts all users at risk, especially if they use the same passwords on other systems, as many users do. Some hackers collect large lists of username and password combinations to use in brute-force attacks of other systems.

Identify the hashing algorithm that would work best for your organization. Because hashes are still vulnerable to brute-force attacks, the best solution usually is not the algorithm with the best performance. In this case, a slower algorithm means the brute-force process will take longer. Design the system so that you never have to actually retrieve a password. Passwords should only be set or reset.

In rare instances, however, the application must store a password for later use. For example, I once audited an application that had to authenticate to a third-party data provider. Because the data provider required authentication, the application had to store the password using reversible encryption. Because the application required a retrievable password, the company had to compensate by taking extra measures to protect the encryption key, which it did by placing the encryption and decryption code in a COM component.

One weakness with using reversible encryption in a Web application is that in the real world, the encryption key rarely changes. The problem is that if you ever want to change the encryption key, you must decrypt all ciphertext in the database and then re-encrypt it using the new key—something that few Web or database applications are designed to handle. If you plan to use reversible encryption, plan also to have a mechanism to regularly change the encryption key and update all encrypted data.


If you plan on using reversible encryption, always use a strong encryption algorithm such as DES, Blowfish, or some other algorithm that has been proven secure. Never use XOR, ROT-13, or a homegrown encryption code; these usually provide little protection and are easier to break than people realize. Weak encryption algorithms are roughly equivalent to the tiny locks that come with most luggage—hardly a deterrent to even the most casual thieves.

Use one-way hash functions and store the hash in the database. When a user logs in, run the hash function on the password the user enters, and compare that hash to the one in the database. One advantage of hash functions is that they consist of only numbers and letters, allowing users to enter any keyboard character as their password without you having to take extra measures to handle special characters.


If you have an existing system that stores plaintext passwords, the process of switchover to hashes is relatively painless. To do this, create a new hash field next to your existing password field. Next, hash all existing passwords and save them in the new hash field. Next, add the hash function to your authentication code and to your password-setting code. Finally, instead of storing and checking against the password field, update your code to first hash the password, then store and check using the hash field.

SeeChapter 4, “Encrypting Private Data,” for more information on using the encryption features provided by the .NET Framework.

Security Policies

 Never store a password in plaintext or using reversible encryption.

 Use strong hashing algorithms such as MD5, SHA-1, SHA256, or SHA512.

Password Aging and Histories

Summary: Old or reused passwords provide more opportunity for attackers
Threats: Brute-force attacks, account hijacking

As an application ages, so do user passwords, because users normally don’t make the effort to regularly change their passwords. It is not uncommon to see users with passwords as old as the system itself, sometimes going several years without changing a password. This is especially true with Internet service provider (ISP) e-mail accounts that provide no easy method for changing passwords. You should always require users to change their passwords at regular intervals, a practice that few Web sites follow.

But setting the right interval isn’t always easy. If the maximum password age is six months, the risk of compromised passwords increases. However, if you go the other extreme and require password changes every 30 days, you will find users writing down their passwords more and developing patterns such as sequential passwords or passwords based on dates. Requiring users to change their passwords too frequently can actually make the system less secure. Furthermore, if users log in to your Web application only once every few months and find they have to change their passwords each time, they are likely to get annoyed.

To determine the optimal maximum password age, ask yourself the following questions:

 How sensitive is the protected data?

 How often do users log in to the application?

 How long would it take to guess a password based on your password complexity requirements?

If your Web application is an online banking system, you might want to consider maximum password ages of three to six months. On the other hand, if you provide an online flower shop, you may get away with letting users keep their same passwords for a year or more.


If you want to encourage users to change their passwords occasionally but do not want to force maximum password aging, consider warning users at regular intervals via e-mail that their password is getting old, along with a quick link to change their password. Another idea is to let users select their own password-aging requirements.

Related to password aging are password histories, which are historical lists of previous passwords a user has selected. Password histories prevent users from alternating between the same two or three passwords every time one password expires. A system should reject any password that matches those in the history list. Many systems will remember the last three to five passwords, but some may keep a history of 20 or more passwords. Keeping a password history doesn’t require a significant amount of resources, so it usually makes sense to keep as many as possible.


If you keep password histories, store only the hashes of the passwords, not the passwords themselves, as explained earlier in the section “Storing Passwords.”

Despite password aging and history lists, some users are still determined to reuse the same passwords. They circumvent these security measures by resetting their password enough times to fill up the history list and then setting their password back to the original that just expired. The countermeasures are to keep long history lists and to set minimum password-aging requirements. Minimum password ages are the least amount of time that must pass before users can again change their passwords.


Minimum password aging can sometimes be inconvenient, but it doesn’t take much to be effective: A day or even an hour could be enough to prevent users from resetting their passwords several times in an effort to flush the history list. If you do enforce minimum password ages, be sure to allow administrators to override this policy.

Passwords are nothing more than an obscure secret word or phrase. Given enough time, an attacker could eventually guess a password through brute-force methods or through exposure from operating system or application vulnerabilities. As passwords age, the risk of an attacker compromising that password increases. Furthermore, if an intruder has obtained a password without alerting the user, the intruder will have access for as long as the password is valid. Without password aging, the intruder will have access until the user manually changes his or her password.

Password aging and histories require extra database fields to track when a password was set and to keep a list of recent passwords. There is also the extra processing requirement of hashing the password and comparing it to each entry in the history list. You might want to allow different aging policies for individual users or groups, or choose a systemwide policy. One advantage of systemwide policies is that you can immediately expire all passwords in case there is a major security incident such as a server intrusion.

You should check a password’s expiration date immediately after a user successfully authenticates to the system but before allowing access to the system. If you centralize your authentication to a single include library, you can more easily perform the password-aging check. If the password has not yet expired but is getting close, you might want to warn the user several days ahead of time. Figure 1.5 is an example of a password expiration screen.

Figure 1.5 Example of an Expired Password Screen

You should check password histories and minimum password ages when validating a user’s new password.

Security Policies

 Set a maximum password age that is appropriate for your application and for users.

 Keep a list of recent passwords to prevent password reuse.

 If possible, enforce a small minimum time interval between password resets.

Changing Passwords

Summary: Make it easy and encourage users to regularly change their passwords
Threats: Brute-force attacks, account hijacking

Many security experts warn against using “security through obscurity”(the practice of securing something by hiding it) as a defense mechanism. But passwords or authentication credentials—the center of many security systems—are nothing more than security through obscurity. A password’s strength completely depends on our expectation that no one else will be able to guess or otherwise discover the password.

Given enough time, attackers can discover passwords, either by exploiting some system vulnerability or through the process of a brute-force guessing attack. Our only defense is to regularly change passwords, hopefully before anyone has a chance to discover the current one. Therefore, an important feature to include in any Web application is the ability to change passwords.

I once knew of a company with a financial trading application that required users to log in to perform trades. Since most brokers performed many trades throughout the day, they simply minimized the Web browser on their screens and remained logged in. The brokers complained about constantly having to authenticate because their browser sessions timed out, so the developers eliminated all session timeouts on the server. At the end of the day, most of the brokers left their computers running, and most of them also failed to exit the browser application, leaving them logged in to the application. Some users would sometimes go all week using a single browser session.

Keeping an open session presented a big risk, but an even greater risk was how the application managed password changes. To set a new password, users browsed to the preferences page, clicked on a link to change the password, and then entered the new password. But consider this scenario: Another broker waits until a target goes to lunch and then sets a new password using the target’s open session, having no knowledge of the previous password. The target session remains logged in for the next week, but the other broker has full access to the account with the new password. It is not until the target is forced to log in again that he or she discovers that the password has changed.

If users do not regularly change their passwords, they face an increasing probability that others will be able to discover their passwords and therefore gain access to their accounts. The harder it is for users to change passwords, the less likely users are to change their passwords. This situation is worsened if users are not reminded or forced to regularly change passwords. Without techniques such as entering previous passwords, expiring sessions, and notifying users of changes, an attacker might be able to use an account for an extended period of time without detection.

Design the system so that changing passwords is a simple and intuitive process. Avoid practices that discourage changing passwords, such as overly oppressive password complexity requirements. Always require authentication before and after changing passwords.

After a user logs in, provide quick links to the most common account management tasks, including changing passwords. If your security policy does not require users to change old passwords, consider a simple warning including a link, like the one shown in Figure 1.6.

Figure 1.6 Example Warning for Old Passwords

A password-change page should consist of three text boxes: one to enter the previous password, one to enter the new password, and a third to verify the new password. Figure 1.3 demonstrates a sample password reset screen.

To prevent anonymous brute-force attacks; make the password change page available only to active sessions of authenticated users.

Security Policies

 Always allow users to change passwords themselves.

 Make it intuitive and easy for users to change passwords.

 Remind or force users to regularly change their passwords.

 Require knowledge of the previous password to change a new password.

 Require the user to enter the new password twice to ensure accuracy.

 Confirm account changes via e-mail or some other means of communication.

 Expire all active sessions and require authentication after changing a password.

Resetting Lost or Forgotten Passwords

Sooner or later, some of your users will lose or forget their passwords. Because of the potential security risk, you must carefully consider how to deal with lost or forgotten passwords. In this section, you will learn about:

 Resetting passwords

 Sending information via e-mail

 Assigning temporary passwords

 Using secret questions

Resetting Passwords

Summary: Follow a well-planned procedure for resetting lost or forgotten passwords
Threats: Brute-force attacks, account hijacking

To avoid the customer support overhead of dealing with lost passwords, many Web sites allow users to conveniently retrieve or reset their own passwords. However, password reset features, if not implemented correctly, can introduce security weaknesses to your Web application.

You should always treat a lost password as a security event, taking extra precautions to protect the user’s account from intruders. Too many Web sites take a casual approach to lost passwords: Users enter a username or e-mail address (as shown in Figures 1.7 and 1.8), and in a few minutes they receive an e-mail containing the original password. Indeed, users who infrequently visit a site sometimes use the convenient password retrieval process instead of other methods to record or remember their passwords.

Figure 1.7 Password Retrieval Using E-Mail Only

Figure 1.8 Another Password Retrieval Method Using E-Mail Only

But retrieving passwords means that your Web application is either storing passwords in plaintext or using reversible encryption, both poor practices, as described earlier in the section “Storing Passwords.” If a lost password event occurs, you should always abandon the old password and require the user to set a new password. You should never allow users to retrieve a lost password, only to set a new password. Password hints that remind a user of the actual password are not much better, especially if the hint is the password itself.


Another benefit of not sending the old password and forcing a reset is to prevent an attacker from retrieving a user’s password without his or her knowledge. Although a skilled attacker may be able to obtain enough information and access to reset a user’s password, this is hardly a stealthy attack, and the user certainly will be alerted the next time he or she tries to log in to the account and the old password no longer works.

The difficulty in resetting passwords is that you want to provide users the convenience of resetting their own passwords, but you do not want to weaken password security in the process. Before your application resets a password, you should be reasonably certain that it is the user, not an impersonator, on the other end of the transaction. Since the user no longer has the original password to prove his or her identity, you must take other steps to validate the user’s identity. Here are some ways to accomplish this:

 Send the user an e-mail to the address assigned to the account.

 Ask the user to answer one or more preselected secret questions.

 Ask the user to provide one or more bits of information associated with the account (such as ZIP code or birth date).

For highly secure environments or when dealing with particularly sensitive information, you may even take further steps to verify a user’s identity:

 Call the user at the phone number assigned to the account.

 Send the user a fax to a preselected fax number.

 Send the user a letter through the postal service.

 Ask the user to appear in person and present identification at your main or branch office.

The purpose of asking the user to answer a secret question or provide other information is to verify that they know something about the account, as shown in Figure 1.9. This helps prevent random anonymous attacks against users, but it does not protect a user from attack from an individual who has knowledge of the user. Sending the user an e-mail will prove that the person requesting the password reset has access to the user’s e-mail account. It is possible for an attacker to have obtained access to the user’s e-mail account, but if the attacker can answer a user’s secret question and has access to the user’s e-mail, the user likely has a much bigger problem that you really cannot do much about anyway. Nevertheless, you still should never reveal the old password in the e-mail, only provide a link to reset the password.

Figure 1.9 Example Password Retrieval Using Personal Information

Design the system with a clear flow of events through the password reset process. Use secure session tokens with short expiration periods throughout the process. Never put usernames, e-mail addresses, or other identifying information on any URL.

The process for resetting a password should be as follows:

1. Ask the user to provide an account name and answer one or more questions that demonstrate knowledge of the account, as shown in Figure 1.10. Log the IP address of the client that initiated the request, and assign a secure token for the password reset session. Set a short expiration period for the session—24 hours or less.

Figure 1.10 Password Reset Process

2. Send an e-mail to the address assigned to the account explaining that a password reset has been requested; include the client IP address that initiated the request. Provide a secure link to your Web site using a temporary token linked to the reset process. Always provide an e-mail address or URL for the user to report a security incident if they were not the ones who initiated the password reset.

3. After the user clicks the link, ask the user to provide a new password and optionally a new security question and answer. Always check the session token to be sure it has not expired.


Sometimes a user loses both the username and password or no longer have access to the e-mail address used to set up the account. In this case, you might need to provide a manual authentication process, requiring the user to e-mail or phone a customer service representative to verify his or her identity.

Figure 1.11 shows an example of a password reset process. This particular screen shows that the site correctly requires setting a new password rather than retrieving the old one. Although the site asks for an e-mail address and some personal information, a credit card number is by no means secure enough to verify a user’s identity. Any merchant that has taken an online order from a user will likely have all the information necessary to complete this form. At first it might seem like this process is more secure because it sends the user an e-mail, but remember that this is the user’s e-mail account, so it would be impossible to send the user an e-mail if her or she have forgotten the password. In this case, authentication will have to be sufficient to allow full access to the account. In addition to asking for the credit card information, this process should ask for additional personal information and ask the user to answer a secret question.

Figure 1.11 Example Password Reset Process

A common flaw in the password reset process is for a Web application to use hidden form fields or query strings to pass state information from one page to the next. For example, to ask users their secret questions, you must first find out who they are and then look up the secret questions. Therefore, most password reset processes begin with a user entering an e-mail address in a Web form. On the next page, the Web application presents a secret question and asks for an answer. Finally, the secret question is verified and action is taken to retrieve or reset the password. But sometimes a Web site will pass the user’s e-mail address or username as a hidden form field that an attacker can modify. Sometimes this will result in the password being sent to the e-mail address of your choosing. Another common flaw is that you can begin the process with one account and modify a parameter halfway through to jump to another account and finish the process.

Review the password reset process, ensuring that the application sufficiently validates the user’s identity before sending e-mail. Never send e-mail to any address other than the one assigned to the account. Walk through the reset process, watching every step to ensure that it is appropriately and securely linked to the previous step. Make sure that it is not possible to switch to the context of another account halfway through the reset process.

Security Policies

 Treat password resets as a security event, logging the client IP address and taking other practical security measures.

 Never retrieve a user’s password; only allow a user to set a new password.

 Never use password hints to remind the user of the actual password.

 Ask the user to show some knowledge of the account through secret questions or by providing information associated with the account; never allow an anonymous password reset.

 Send the user an e-mail to confirm a password reset, providing a secure link to complete the process.

 If practical, after a password reset, clear any sensitive information stored with the account, such as credit card numbers.

 Expire all existing sessions after a password reset.

Sending Information Via E-Mail

Summary: E-mail is insecure and you should not use it to convey sensitive information
Threats: Sensitive information leakage, account hijacking, user privacy

Consider this e-mail I recently received after subscribing to a Web-based information service:

The problem with this e-mail is:

 It transmitted my username and password in plaintext across the Internet.

 It transmitted my credit card information in plaintext across the Internet.

 Whoever has access to the mailbox will receive a copy of this sensitive information.

 It instructs me to save the e-mail for future reference, potentially exposing sensitive information if someone gains access to my e-mail client.

 It tells me that they probably store my password and possibly my credit card information either in plaintext or using reversible encryption, not using a secure one-way hash.

E-mail is by nature an insecure medium: There is no guaranteed authentication of either the sender or the recipient, e-mail traffic is not encrypted as it traverses various networks in its path, many e-mail servers and clients do not encrypt stored messages, and there is no way to prevent others from receiving bounced, quarantined, or rejected copies of your e-mails. E-mail is also subject to attacks such as cross-site scripting, client vulnerability exploitation, scripting attacks, malicious attachments, and social-engineering attacks.

Another potential risk of e-mail is that a user is not guaranteed to always have the same e-mail address or domain. Some companies automatically forward e-mails addressed to departed employees to the new employee in that position. There is also the issue of expired domains that are registered by new owners, giving the new domain owner access to all e-mail sent to the entire domain (see

Design the system so that it only relies on e-mail as a secondary form of identification and notification. If possible, take advantage of S/MIME or PGP signing and encryption to strengthen e-mail communications. Allow users to provide you with a public key to be used for all e-mail communication.

If you want a user to have some confirmation of an order or account registration, provide a secure, temporary link via which the user can view this information on your Web site. Rather than sending users their usernames and passwords, instruct them during the registration process to remember this information. If you must provide confirmation of a credit card order, only provide the last few digits of the card number, and do not provide any other identifying information.

When composing e-mails, always consider the effect on the user if this information is intercepted or viewed by others.


One feature I have yet to see any Web site implement is taking advantage of public-key encryption technologies such as PGP to sign or encrypt e-mails. It would be simple to allow a user to paste in or even permanently store a public key to use for all e-mail communications. You should also provide a public key for your organization and sign all outgoing e-mails. For a list of free PGP tools and development libraries, visit

Security Policies

 Never send sensitive information such as user credentials or credit card information via e-mail.

 Never rely on e-mail alone to verify a user’s identity.

 Do not use e-mail to save the results of a Web form submission that contains sensitive information.

 If possible, digitally sign or encrypt e-mail communications.

Assigning Temporary Passwords

Summary: Users will not change temporary passwords unless forced to do so
Threats: Account hijacking, password guessing

I once signed up for an account at an online book Web site, but I did not use the site until a couple months later. By that time I had forgotten my password, and despite several attempts to guess it, I was forced to click the Forgot Password link.

To my surprise I was not taken to a Web form, but instead my e-mail client popped up with a blank e-mail addressed to the site’s customer service representatives. I was surprised that such a large site would rely on such a manual process, but I composed an e-mail and sent it off. A few hours later, I received an e-mail from a support representative telling me that my password had been reset, but she did not give me any instructions on how to log in to my account. I e-mailed her back and asked her how I set a new password. She promptly responded and told me my new password, which sounded suspiciously like a password she used often. I logged in to my account and could not find any place to change my password. After all, the password reset process was manual; could I possibly expect them to provide a password change feature? Because I was under a tight deadline, I gave up and simply used the assigned password. It wasn’t until a month later that I actually figured out how to change my password to something new. Chances are there are hundreds of customers who never got around to changing their passwords for that site.

Temporary passwords are normally not a good solution, and you can usually find a better method to accomplish your goal. Temporary passwords created by humans tend to be repetitive and easily guessed. Automatically generated passwords also tend to follow patterns or are difficult to remember. Users are not likely to change temporary passwords unless forced to do so.

Building the Code

Design the system so that it does not depend on temporary passwords. If there is no alternative, provide a means for generating strong passwords, and limit each password so that the user must immediately change it to something else. A system with password-aging capabilities allows more flexibility with temporary passwords.

Never expect a randomly generated or temporary password to be temporary unless you force it to be temporary. One technique in generating passwords for users is to create the password but set the expiration date so that it is already expired, forcing the user to change the password the first time it is used. Be sure to add this password to the password history list.

Hacking the Code

If you find that an application uses temporary passwords, try creating several accounts to see if there is an obvious pattern. Also try resetting your password to see if it creates temporary passwords there.

As an auditor, determine if users are likely to immediately change those passwords. It is usually not enough to recommend that they change their passwords; the application should enforce this policy.

Security Policies

 Avoid having customer service representatives set temporary passwords.

 If you must use temporary passwords, use a strong random password generator.

 If you must use temporary passwords, provide a short expiration date or set the password as already expired.

Using Secret Questions

Summary: Secret questions are not a replacement for passwords
Threats: Sensitive information leakage, account hijacking, user privacy

To help verify a user’s identity in the case of a lost password, many Web applications use secret questions. By answering a preselected question, a user can demonstrate some personal knowledge of the account owner. A classic example is asking to provide a mother’s maiden name.

Answering secret questions requires some knowledge of the user account, but secret questions break all the rules for strong passwords and have some significant weaknesses:

 An attacker can sometimes discover the information with little research.

 The answer to the question is usually a fact that will never change.

 Users reuse the same secret questions and answers across multiple Web sites.

 Someone close to the individual could know the answers to many of the questions.

 People rarely change their secret questions.

 The answers are often case-insensitive and usually contain a limited character set.

 Some questions have a limited number of answers.

 With some questions, many people will have the same common answers.

Secret questions usually ask for an obscure fact that hopefully only the account owner would know and supposedly would never forget. Many Web sites assume that the user providing the answer to the question is sufficient to identify the user. But many secret questions ask for facts that anyone could discover with little research. To make things worse, if someone discovers this information, you can’t just change a fact from the past.

I have seen countless Web sites that provide great tips on avoiding easily guessed passwords but then turn around and ask for a pet dog’s name or what city you were born in to answer a secret question.

Even if an attacker knows nothing about the target user, the nature of secret questions limits the possible range of answers. For example, consider the questions and ranges of answers shown in Table 1.1. As the table shows, many secret questions have so few possible answers that a brute-force attack against these secret questions is completely feasible. To make matters worse, some Web sites fail to detect or prevent brute-force attacks against secret questions. For years security experts have told people to avoid using pet names, family names, or dates in passwords, but secret questions go directly against that advice.

Table 1.1

Secret Questions and Ranges of Answers

Question Range of Answers
What is the name of your favorite pet? The top 20 dog names are Max, Buddy, Molly, Bailey, Maggie, Lucy, Jake, Rocky, Sadie, Lucky, Daisy, Jack, Sam, Shadow, Bear, Buster, Lady, Ginger, Abby, and Toby.
In what city were you born? The top 10 largest U.S. cities are New York City, Los Angeles, Chicago, Houston, Philadelphia, Phoenix, San Diego, Dallas, San Antonio, and Detroit; one in three of all U.S. citizens live in the top 250 cities; the top 10 most common U.S. city names are Fairview, Midway, Oak Grove, Franklin, Riverside, Centerville, Mount Pleasant, Georgetown, Salem, and Greenwood.
What high school did you attend? There are approximately 25,000 to 30,000 high schools in the United States; you can use to get a list by U.S. state and city.
What is your favorite movie? For a list of the all-time top 250 films, see
What is your mother’s maiden name? There are approximately 25,000 common surnames; one in 10 U.S. citizens have the surname Smith, Johnson, Williams, Jones, Brown, Davis, Miller, Wilson, Moore, Taylor, Anderson, Thomas, Jackson, White, Harris, Martin, Thompson, Garcia, Martinez, Robinson, Clark, Rodriguez, Lewis, Lee, Walker, Hall, Allen, or Young.
What street did you grow up on? The 15 most common street names are Second/2nd, Third/3rd, First/1st, Fourth/4th, Park, Fifth/5th, Main, Sixth/6th, Oak, Seventh/7th, Pine, Maple, Cedar, Eighth/8th, and Elm.
What was the make of your first car? Most cars are built by Acura, Audi, BMW, Buick, Cadillac, Chevrolet, Chrysler, Daewoo, Dodge, Ford, GMC, Honda, Hummer, Hyundai, Infiniti, Isuzu, Jaguar, Jeep, Kia, Land Rover, Lexus, Lincoln, Mazda, Mercedes-Benz, Mercury, Mitsubishi, Nissan, Oldsmobile, Plymouth, Pontiac, Porsche, Saab, Saturn, Subaru, Suzuki, Toyota, Volkswagen, or Volvo.
When is your anniversary? The average length of a marriage is 7.2 years, giving 2,628 likely dates.
What is your favorite color? There are around 100 common colors, even considering colors such as taupe, gainsboro, and fuschia.

The key to properly using secret questions is to understand that they should never be the equivalent of a password. They should only be used to initiate a password reset, to prevent anonymous attacks against the password reset process. Providing the answer to a secret question should never be enough to validate a user, but combined with other factors, such as having access to the user’s e-mail account, secret questions can be effective in helping to identify a user.

The greatest threat with secret questions is that the answer is usually fixed and an attacker can sometimes discover this information through research. Because there is usually a limited set of answers to secret questions, they are also vulnerable to brute-force attacks. Finally, secret questions are usually ineffective against attacks by people close to the user. Individuals such as ex-spouses, once-close business associates, or wayward teenage children may have sufficient information and sufficient motivation to break into a user’s account.

Building the Code

The key to successfully and securely using secret questions is to clearly define their role as just one part of the password retrieval process. They prevent password resets without some personal knowledge of the user. Design the system to be flexible with secret questions and answers, allowing users to disable secret questions or requiring a telephone call for final confirmation. Another effective technique for security-sensitive Web applications is to allow or require users to answer more than one secret question. Consider the impact on the database of having multiple and perhaps a variable number of secret questions.

Avoid allowing users to select their own questions, since most users are not trained to select strong enough questions. Sites that allow users to select their own secret questions end up with insecure questions such as:

 What year were you born?

 What is your password?

 What is the capital of Georgia?

Select good questions, carefully considering the possible range of answers as well as the likelihood of common answers. Use unique questions, and try to avoid subjects that return short, one-word answers. Also try to avoid questions that others commonly use, such as mother’s maiden name, pet name, or high school. But keep in mind that you should ask questions that users will always answer the same way.

Establish a large list of questions, but provide a short, random list for users to select from. For users more concerned with security, you might want to provide an advanced option to select from a larger list of secret questions.

If the user provides a predetermined number of incorrect answers to the security question, you might not want to return an error, but instead send the user an e-mail explaining that he or she answered incorrectly. This will prevent

brute-force attacks against the secret question process and alert users to a possible attack against their accounts.

Here are some examples of good secret questions:

 What is the first and last name of your first boyfriend or girlfriend?

 Which phone number do you remember most from your childhood?

 What was your favorite place to visit as a child?

 Who is your favorite actor, musician, or artist?

Security Policies

 Secret questions by themselves are not secure and should never be used as a password equivalent.

 Allow users to change their secret questions and answers if necessary.

 Detect brute-force attacks against secret questions.

Empowering Users

A security system is never complete without user participation. Users have a unique perspective that allows them to spot security problems that administrators and developers may overlook. But to participate in security, users need knowledge and tools. It is up to you to provide the knowledge and tools they need. In this section, you will learn about:

 Educating users

 Involving users

Educating Users

Summary: Users must know how to protect their accounts
Threats: Account hijacking, social engineering, identity theft

With the increasing dependence on the Internet for financial and business transactions comes an increasing threat of Internet crime. Identity theft, fraud, and online scams are rampant, and Web site security can only go so far. At some point, users must take responsibility for protecting themselves.

Despite great advances in security technology and techniques, users consistently fall for the same scams they fell for since the very beginning of electronic communication. For example, users will click links on HTML pages and e-mails and will eagerly enter account information in an e-mail-based form, and many users will divulge their passwords to someone who claims to be an administrator or help-desk technician.

Many users of online financial institutions and other Web sites have fallen victim to spoofed e-mails intended to steal user account information, an attack know as phishing. In these cases, users receive an e-mail such as that shown in Figure 1.12, explaining an account problem and asking them to authenticate using the provided form. The form submits the personal information to a Web server controlled by the fraudster and then transparently forwards the information on to the real Web site. The user is not aware that his or her information has been stolen until it is too late. Fortunately, these e-mails are notorious for poor English grammar and spelling, such as the word unnormally in Figure 1.12.

Figure 1.12 Example eBay Scam E-Mail

Another variation of the scam is to send users an e-mail that looks like plaintext but that is actually an HTML-based e-mail. Links appear to be one (legitimate) URL but take the user to another URL with a fake login form that looks identical to the original. Yet another variation is to encode or obscure the URL in such a way as to trick the user into thinking she is visiting one site while she is, in fact, visiting another.

If users are not aware of the techniques used by scammers, fraudsters, and identity thieves, the users will consistently fall victim to these social-engineering techniques. Users who are not smart about security may fall victim to account hijacking or identity theft and put themselves as well as others at risk.

Security Policies

 Through various media, educate users about the security risks involved with using your Web application.

 If possible, provide a user forum to discuss security issues.

 Never provide links or forms in e-mails sent to users; ask them to simply log in to their account.

Involving Users

Summary: Involving users in security will raise awareness and help limit attacks
Threats: Account hijacking, social engineering

Once I was talking with a friend about a scam e-mail sent to customers of a major bank, asking them to log in to their accounts through a form provided in the email. I mentioned that a surprisingly large number of users fell for the scam, despite the obviously poor grammar in the e-mail message. My friend mentioned that he had actually received that e-mail and was proud to say that he immediately recognized it as a scam and deleted the message. But how many users could he have protected if he had instead reported the e-mail to the company?

Many users are aware of scams, fraud, or other suspicious incidents and never report them. My friend’s reasons for not reporting the suspicious e-mail was that first, someone else probably will, and second, he wouldn’t even know where to start to report the e-mail.

Users can play a great role in security if you make it easy for them. Since some users are already technically savvy and security-educated, you should give those users access to advanced security tools or security options. For example, some advanced users might want to set an option to only allow access to their accounts from specific IP address ranges. Advanced users might also want access to advanced security reports for their accounts.

If users have no way of identifying and reporting security incidents, the impact of a security incident could be larger than necessary. Design the system in such a way that all account actions are easily audited and reported. Provide conspicuous links for identifying and reporting security incidents. Create a modular design that allows users to easily customize their own security options.

Security Policies

 Allow users access to a history of account transactions and events.

 Provide users a clear and easy way to report security incidents, and ask them to report anything suspicious.

 If possible, provide a user forum to discuss security issues and incidents.

 Allow advanced security options for those who want to use them.

 Provide users a way to revoke or delete accounts they no longer want to use.

Coding Standards Fast Track

Establishing User Credentials

Enforcing Strong Passwords

 Access a password form field only once to validate it and assign it to a variable. After that use only the validated variable.

 Use a standard function to check password complexity requirements.

Avoiding Easily Guessed Credentials

 All temporary passwords should have a short expiration period or should be marked as already expired, forcing the user to change the password.

Preventing Credential Harvesting

 Never place the username on the URL’s query string.

 Avoid user directories or other methods that others could use to harvest usernames.

 Do not automatically generate usernames or account IDs.

Managing Passwords

Storing Passwords

 Always use well-established hashing algorithms, such as those included with the System.Security.Cryptography class.

 Centralize all encryption code so that you can easily change algorithms and/or keys.

Password Aging and Password Histories

 Always check the password age immediately after authenticating the user.

Changing Passwords

 Password changes should be on a page of their own and accept the old password as well as the new password in a single step.

 Expire all user sessions immediately after changing a user’s password, requiring the user to reauthenticate.

Resetting Lost or Forgotten Passwords

Resetting Passwords

 Treat lost passwords as a security event, taking measures such as logging event details, including client IP address.

 Carefully manage session state throughout the reset process; do not track session account identifiers on hidden form fields or query strings.

Sending Information Via E-Mail

 Never send sensitive information via e-mail.

 If possible, use PGP or S/MIME to digitally sign and/or encrypt e-mail communications.

Assigning Temporary Passwords

 If creating temporary passwords, use a strong random algorithm with sufficient entropy.

Using Secret Questions

 Use questions with enough possible answers to prevent guessing or brute-force attacks.

 Avoid questions for which many people will select the same common answers.

Empowering Users

Educating Users

 Avoid long or overly complex URLs, especially at the application entry points such as a login screen.

Code Audit Fast Track

Establishing User Credentials

Enforcing Strong Passwords

 Does the application allow for and enforce strong passwords?

 Does the application require both a username and password?

Avoiding Easily Guessed Credentials

 Does the application avoid using sequential user account numbers?

 Do account numbers or usernames follow predictable patterns?

 Do customer service personnel select passwords for users rather than users selecting their own?

 Does the system create default passwords?

Preventing Credential Harvesting

 Do account numbers or usernames follow predictable patterns?

 Are identifiable account numbers or usernames passed as query strings on URLs?

 Do account numbers or usernames unnecessarily appear on HTML pages?

Limiting Idle Accounts

 Does the system have large numbers of idle accounts?

 Is it possible to determine another user’s account activity?

 Are users notified via e-mail after major account changes?

Managing Passwords

Storing Passwords

 Are password hashes rather than actual passwords stored?

 Are password hashes stored using well-established hashing algorithms?

 Can encryption keys be easily changed?

 Do password hashes use random salts?

Password Aging and Password Histories

 Does the application allow for password aging and do passwords expire after a set amount of time?

 Does the application enforce password histories to prevent users from reusing passwords?

Changing Passwords

 Is it convenient for users to change their passwords?

 Are users reminded to regularly change their passwords?

 Does the password change process require the previous password?

 Does the system confirm password changes via e-mail?

 Does the system expire all active sessions after changing passwords?

Resetting Lost or Forgotten Passwords

Resetting Passwords

 Does the system allow only password resets, rather than retrieval?

 Does the system require users to answer secret or other questions to reset the password?

 Does the system send an e-mail to confirm the password change?

Sending Information Via E-Mail

 Does the system avoid sending sensitive information via e-mail?

Assigning Temporary Passwords

 If using temporary passwords, does the system use a strong random password algorithm?

 If your system uses temporary passwords, do they have a short expiration period?

Using Secret Questions

 Are secret questions treated as password equivalents?

 Do the secret questions have a great number of possible of answers?

 Does the system avoid secret questions with common answers?

 Does the system prevent users from setting their own secret questions?

Empowering Users

Educating Users

 Is a help page available to educate users on security?

 Does the Web site provide other methods to educate users?

Involving Users

 Are users able to view a history of transactions and events related to their account?

 Are users able to view a history of account logins, including dates, times, and IP addresses?

 Do users have an easy and intuitive way to report security incidents?

 Can advanced users customize their security options?

 Are users able to revoke or delete unused accounts?

Frequently Asked Questions

The following Frequently Asked Questions, answered by the authors of this book, are designed to both measure your understanding of the concepts presented in this chapter and to assist you with real-life implementation of these concepts. To have your questions about this chapter answered by the author, browse to and click on the “Ask the Author” form. You will also gain access to thousands of other FAQs at

Q: Which hashing algorithms are bundled within the .NET Framework?

A: MD5, SHA1, SHA256, SHA384, and SHA512.

Q: Should I automatically generate passwords with totally random characters to make sure their passwords are secure?

A: Many people believe that generating completely random passwords will best protect users. But keep in mind that it is extremely difficult for users to remember a random password such as jD4nWpa8v, likely requiring them to write it down. Perhaps a better solution is to create a more memorable password made up of multiple random English words and punctuation. Users are more likely to remember these passwords, and you can even get away with giving users longer passwords.

Q: What should I allow for a maximum password length?

A: If you are using a hashing algorithm, the hash itself is a fixed length, regardless of the size of the password. In other words, a seven-character password produces a hash the same length as a 200-character password. So if you use password hashes, you do not need to enforce a maximum password length.

Q: My Web forum page is completely dependent on showing usernames. How can I prevent others from harvesting these usernames?

A: Some Web applications are based on user interaction and cannot completely prevent username harvesting. To counteract this potential danger, allow users to change their usernames and set aliases for their accounts.

Q: I operate a Web application that contains very sensitive user financial information. Should I force users to change their passwords every 30 days to ensure maximum password security?

A:  This is the most secure policy, but it could cause users to find measures to circumvent this inconvenience by writing down passwords or following predictable patterns. A better solution is to encourage stronger passwords and allow users to keep them longer.

Q: After a password reset, what is the point of putting a link in the e-mail rather than the actual password? If a hacker can access the user’s e-mail, he can just as easily access the link in an e-mail. Why not just e-mail the user a temporary password?

A: It is true that a link in an e-mail is just accessible as the password itself, but there are other reasons for doing this. First, it establishes a secure communication channel when the user clicks the link. Second, it allows the Web server to record the client’s IP address and time of visit. Third, it prevents the user from saving an e-mail containing the password. And finally, if the user no longer owns the e-mail account or if the e-mail is routed incorrectly, it prevents others from obtaining the user’s password.

Q: Are temporary passwords bad?

A: Temporary passwords are not bad, as long as you force them to be temporary. The best technique is to mark them as already expired so that when a user logs in she is forced to immediately change her password.

Q: What is the best way to get users involved in security?

A: The best way to get users involved is to allow users to discuss security in a public forum or via a mailing list. Such a forum is a great way for your organization and your users to discuss current security issues. But be careful to monitor the forum, since they are sometimes used as a way to social-engineer users into revealing their passwords. A fraudster once posted phony support phone numbers at an online payment support forum, instructing users to call those numbers to report security incidents. If someone called those support numbers, the fraudster on the other end first asked them to “authenticate” themselves by revealing their passwords.

Q: Where can I obtain some word lists for checking user passwords?

A: Visit or