Wednesday, June 24, 2009

Vanguard.com Doesn't "Recognize" Me

I upgraded the hard drive on my home computer. The first time I tried to log into my Vanguard account online, it asked me to answer a security question. No problem I thought to myself. The site just doesn't recognize me since I have a new drive. It wants extra information to be sure I'm me. This is part of PassMark "sitekey" functionality. I typed in the answer to the question and was promptly told "sorry, invalid answer". Weird. I tried again. same result. I was 95% sure I was entering the correct answer, but each time I tried, it didn't work. Eventually I got an email telling me I disabled my ability to log in from an unrecognized computer due to repeated wrong answers. Nice. The web site didn't inform me of this - only the email. The email also stated I could now only log in if I used a recognized computer. To log in from an unrecognized computer, I would have to reset my security questions or call Vanguard customer service. Great.

Luckily, I had logged into Vanguard from my work computer, meaning it was "recognized" and I wasn't asked a security question. Using my work computer, I logged in and reset my security questions and answers as required. Now back to my home computer. I was quite confident facing a security question this time. But again, failure! Why does it not accept my answer? I was 100% sure it was correct this time. I just reset them for cryin' out loud.

At this point I concluded that it was a bug in Vanguard's site. Do I call their customer support? Ugh. Instead I took the approach of trying to get the site to "recognize" my home computer. Long story short, I copied a single file from my work computer to my home computer and solved the problem. I knew the PassMark/sitekey solution uses a Flash local shared object to determine whether a computer is recognized. It does not use a persistent cookie as you might first guess. Anyway, I found the shared object file "PassMark.sol" in the following directory on my work computer:

C:\Documents and Settings\[user]\Application Data\Macromedia\Flash Player\#SharedObjects\xxxxxxxx\vanguard.com\passmark\flash\pmfso.swf

where "xxxxxxxx" changes for different users. I copied PassMark.sol over to the corresponding directory on my home computer and it worked like a charm! Vanguard's site suddenly recognized my home computer and I got logged in.

This episode was very frustrating and got me wondering how normal users feel. After all, I was only able to solve the problem with:
  • Luck - I had another computer that was recognized
  • Esoteric knowledge - Vanguard's site uses Flash shared objects to recognize a computer
The vast majority of users are not web application security experts. They must be going crazy, and on the phone with support a lot.

Monday, June 8, 2009

Patent Abuse?

This is not strictly an application security post, but I just read an amazing article about a security/tech company here in Dallas. I had never heard of DeepNines, Inc. even though I live in DFW and work in the information security field. Based on the article, my first impression of DeepNines is not good. Apparently they won an $18 million settlement against McAfee because McAfee violated their patent. Their patent is "for detecting attacks on a site in a communications network and for taking actions to reduce and/or redirect such attacks". Not satisfied with their windfall, they are suing again, this time Secure Computing, which was just acquired by... McAfee. Now McAfee has to deal with them all over again!

This looks like an egregious case of patent trolling to me. How could a patent be granted for such a thing? Patents are supposed to be "nonobvious to a person having ordinary skill in the area of technology related to the invention" (ref). It's highly questionable that's true here. It's like patenting a steering wheel as "the process of taking an action to cause the rotation about a vertical axis the front-most wheels of a vehicle causing said vehicle to turn in a rightward or leftward direction."

One of my previous employers is dealing with something very similar. It's too bad there are companies that don't like to compete on the merits of their technology or customer service. They find it easier to acquire questionable patents and then sue the pants off anyone they see as a threat. For some companies, patent trolling actually seems to be the true business model.

Wednesday, May 27, 2009

Simultaneous Sessions for a Single User

It's a common request or recommendation that a web application not allow a user to have more than one session active at a time. In other words, after a user logs into an application, he should not be permitted to open a different type of browser (or use another computer) to log in again until his first session has ended. I've recommended this myself, but it's always been kind of muddy as to why this should be done. It is not trivial to implement this feature in the code. Recently, one of our clients wanted to better understand the reasons behind this recommendation. I was given the task of explaining.

The bottom line is that I could not find one strong, clear-cut reason for disallowing simultaneous sessions for a single user. There are a number of scenarios where it might help. Listed below are the reasons I came up with for implementing this feature. Please let me know if you have other ideas on this subject.
  • An application has a licensing scheme that allows only a limited number of concurrent users or requires users to pay for access or premium content. A technical control to prevent simultaneous sessions for a single user ID would limit the financial harm caused by users sharing login credentials.
  • It is out of the ordinary for a user to be logged in from more than one location (or more than one type of browser) for a given point in time. Anything out of the ordinary should be assumed to be a potential security risk.
  • An attacker somehow steals a user's credentials (perhaps by sniffing unencrypted HTTP traffic) while the user was authenticating to the application. The attacker immediately tries to log in with the stolen credentials. The application sees that the user is already logged in and returns an error to the attacker, thus temporarily protecting the account.
  • An attacker shoulder surfs to obtain a valid username (but not the password). He then immediately proceeds to run a password guessing or dictionary attack hoping to determine the password. If his attack happens to be successful during the time the legitimate user is logged in, it would prevent the attacker from gaining access.
  • An attacker and a victim log in such that their sessions overlap. The application displays an error message that alerts the victim that someone else is using his account. The victim may contact the site owner, spurring an investigation, which might uncover a compromised account.
  • It could help ensure data integrity and non-repudiation. A user may have multiple authenticated sessions at the same time, and one of the sessions might be used to make a critical change. If a user claims he never made such a change, it could be a problem for the logs to show that two authenticated sessions existed and the user claims he was logged in only once.
  • It could help defend against a malicious user who wishes to overload the server memory by creating an excessive number of authenticated sessions. Authenticated sessions typically use much more memory on the server than unauthenticated sessions. With valid credentials and no limit to simultaneous sessions, a user could potentially create a denial-of-service condition.
After my research, I came to the conclusion that disallowing simultaneous sessions often does not increase an application's security posture enough to justify the required development and implementation cost. Obviously there are some special situations, like the licensing issue, where it could make sense.

This feature may actually introduce new problems. Let's say a user logs into an application and his machine crashes or the power goes out. A few minutes later, when trying to log in again, the user is denied access and told he's already logged in. Of course, it's true from the server's perspective (his session is still active), but now there's an angry user shouting profanities at his computer. Unless the user knows his previous session ID (fat chance), there's nothing for him to do but wait until the session expires due to inactivity or call your customer service department and complain.

Monday, May 18, 2009

The Importance of Case-Sensitive Passwords

It is rare that I encounter a web application that doesn't support case-sensitive user passwords. But it still happens. In my experience this often occurs not because the application developers weren't cognizant of security, but because the authentication is actually processed by an old, backend system that doesn't support case-sensitive passwords. Let's review why implementation of case sensitive passwords is so important.

At first you might think that having case-sensitive passwords would double the number of possible passwords. Of course, that is not how it works. Let's say a user decides he wants a password of "orange7". Without case sensitivity, the number of possible passwords for this user is exactly one. But with a case-sensitive password, the user can choose from sixty-four possible passwords:

orange7 Orange7 oRange7 orAnge7 oraNge7 oranGe7
orangE7 ORange7 OrAnge7 OraNge7 OranGe7 OrangE7
oRAnge7 oRaNge7 oRanGe7 oRangE7 orANge7 orAnGe7
orAngE7 oraNGe7 oraNgE7 oranGE7 ORAnge7 OrANge7
OraNGe7 OranGE7 OrAnGe7 OrAngE7 OraNgE7 ORaNge7
ORanGe7 ORangE7 oRANge7 oRaNGe7 oRanGE7 oRAnGe7
oRAngE7 orANGe7 orAnGE7 orANgE7 oraNGE7 oRaNgE7
orANGE7 oRaNGE7 oRAnGE7 oRANgE7 oRANGe7 OraNGE7
OrAnGE7 OrANgE7 OrANGe7 ORanGE7 ORaNgE7 ORaNGe7
ORAngE7 ORAnGe7 ORANge7 oRANGE7 OrANGE7 ORaNGE7
ORAnGE7 ORANgE7 ORANGe7 ORANGE7


So, having case-sensitive passwords vastly increases the universe of possible passwords and sets the bar significantly higher for hackers running brute force or dictionary attacks on a web application. For example, 64 passwords must be checked versus only one in the scenario presented here.

As an end-user, be sure to take advantage of case sensitivity to strengthen the security of your account. Use a mixture of upper and lower case letters, plus numbers. It may prevent a lazy or time-crunched attacker -- who checks lower case passwords only -- from compromising your account.

Wednesday, May 13, 2009

IE Developer Toolbar Follow-Up

In an earlier post, I had commented on the fact that the IE Developer Toolbar has a problem in that it doesn't report cookies that are marked with the "HttpOnly" attribute. Well, as they said in the movie Independence Day, that's not entirely accurate (clip). There is an exception. The exception is when the cookie is a persistent cookie. The tool apparently doesn't utilize JavaScript in that case, and correctly reports the existence of the cookie. It's not actually a situation that would occur very often. Applications normally only need to mark *sensitive* cookies with HttpOnly, and sensitive cookies should not be persistent in the first place.

Saturday, April 25, 2009

More on Blacklisting and XSS

Following up on my last post, another scenario where blacklisting of angle brackets doesn't work to stop XSS is where untrusted data is output into an existing section of script. Consider a JSP application that takes a URL parameter and outputs it within opening and closing <script> tags. If encoding is not being done, which it often isn't, then an XSS attack would be possible. An attacker would simply close the previous executable line of script with a semicolon and immediately follow that with his malicious script.

An example of how this might occur is shown below. A JSP defines a JavaScript function called "gotoPreferences()", which causes the browser to re-navigate to a URL ("prefURL"). Note that prefURL is constructed dynamically by incorporating untrusted data -- the "category" parameter.

<script type="JavaScript">
function gotoPreferences()
{
var prefURL="https://www.server.com/prefs.jsp?category=" + <%= request.getParameter("category") %> + ";"
location.href=prefURL;
}
</script>

To exploit XSS, an attacker might set the value of "category" to:

"";location.href="http://www.evilsite.com"


The resulting line in the HTML would then be:

var prefURL="https://www.server.com/prefs.jsp?category=" + "";location.href="http://www.evilsite.com";

When the function was called, the victim would be navigated to the attacker's site instead of the expected URL.

Thursday, April 23, 2009

Blacklisting and XSS Failures

Looking at a financial application, I was somewhat surprised to see blacklisting of angle brackets used as the main countermeasure against cross-site scripting. Stripping angle brackets or throwing an error every time you see one in a request is not sufficient protection against XSS. There were a couple of ways to exploit XSS in this application despite the rigorous rejection of angle brackets.

One attack vector was due to a page that accepted a parameter containing a relative URL to another page in the application. It ended up being a tailor-made way for someone to avoid the blacklisting altogether. When a request was received, this special page caused a forward (not a redirect) to the specified URL. The code that rejected angle brackets was hit on the request from the client only, and not when the forwarding was done. Therefore, "<" and ">" could be slipped in by double URL-encoding them in the initial request as follows: %253C and %253E (%25 is a URL-encoded percent sign).

The other XSS attack vector was via JavaScript event handlers. This technique is available when user-supplied data is output to the attribute list of a page element. This often happens for an <input> tag, where the HTML form has multiple text inputs. The user enters the data, but one or two values may be invalid, so the application returns the same page and prepopulates the values that were entered. An attacker can employ XSS by closing off the previous attribute with a double-quote (assuming double-quotes were used) and injecting an event handler such as onMouseOver, onFocus, or onClick.

An example injection is: x%22%20onFocus%3d%22alert('xss')%22%20%22. The resulting HTML might look like this:

<input type="text" name="val5" value="x" onFocus="alert('xss')" "">

Notice there were no angle brackets used in this attack, so blacklisting those characters did not provide any protection.

Friday, April 10, 2009

Just Say No to Forced Password Changes

Don't force web application users to change their passwords. Instead, require strong passwords from the outset. I feel sorry for users when I see strong password requirements with forced password change after a certain time. The aggravation and inconvenience for users is not worth the trouble. In fact, for web applications, forcing passwords changes may actually increase the chance that passwords will be compromised. The reason is in how a brute force attack is done: a malevolent person with a valid username systematically tries every possible password combination hoping to get a hit. Depending on password complexity, it could take decades or longer.

Let's say the minimum password length for a web application is 8 characters, and a certain user has chosen an initial password of "muiylmo9". Now assume a slow brute force attack on that user's account is launched, where a password of "aaaaaaaa" is tried, then "aaaaaaab", then "aaaaaaac", and so on. Some time after this attack begins, the user is forced to change his password and he chooses "aciylmo9". The result? The user's password is now more likely to compromised earlier on in this attack. The user's account would have been more secure if the password had never changed. This might be a simplistic scenario, but I think it demonstrates the dubious nature of it all.

Forced password changes make more sense when passwords are stored in a file of some sort (e.g., Apache HTTP Server or Windows) that could be stolen and brute-forced via rainbow tables in offline mode. If a password is cracked in that scenario, the account may still be safe if the user has changed his password.