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

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

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

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








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 ADDR.com 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.






Warning


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.






Warning


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.






Tip


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.




See Chapter 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.






Tip


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.






Warning


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.






Tip


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.





/ 96