Monday, December 29, 2008

A Failure of Imagination

It's a bit old news now, that the American Express web site americanexpress.com had a nasty Cross Site Scripting vulnerability that would let a Bad Guy harvest all the Amex user's authentication cookies.

Cross Site Scripting is an attack technique that lets random people add their own (typically malicious) code to a web site. There's a painless flash demo of how it works here. XSS (as it's called) has been around for about ten years now, so it's rather dismaying that you still see it, especially in high visibility sites like Amex.

Especially because the credit card companies - including Amex - require that people who handle credit cards online ensure that there are no XSS vulnerabilities in their web code. Oops.

Even worse, it seems that the guy who discovered the vulnerability tried to tell the Amex folks, and they ignored him. For weeks.

McRee aired the American Express dirty laundry here after spending more than two weeks trying in vain to get someone inside the company to fix the problem. After getting no response from lower level employees, he emailed a director of a department responsible for information security at Amex. None of his emails was answered.

"I believe they have an obligation to respond, even if it's brief and callous," McRee told El Reg. "You don't have to be polite. Just fix it."

Sigh. All fixed now, so that's not the point of this post. The question is How come this keeps on happening? After all, XSS has been known for about ten years. Heck, buffer overflows have been known for over thirty years and we're still seeing them.

The answer, sadly, is that programmers lack imagination. There, I said it. Sorry to all my friends who are programmers, but with the exception of about five of you, unfortunately, you lack imagination.

Specifically, validating user input (what users type into forms and that sort of thing) is tedious and boring, and in looking for a reason not to have to do it, you ask The Question:
Why would someone do something like that?
The classic way to find a buffer overflow is to get a form field and type a thousand "A" characters. The program doesn't expect that (the programmer didn't check user input), and so makes the assumption that the buffer contains no more than, say, 100 characters. Boom.

Why would someone do something like that?

I've posted this cartoon before, but it illustrates what happens when you don't validate user input.

Database commands entered into a web form? But why would someone do that?

Sigh. (Uses quiet, patient voice that you use when talking to a loved but rather slow child)
Because, punkin, there are Bad Guys out there. Sometimes they want to steal things, and sometimes they want to hurt people, but they're bad. That's why we call them Bad Guys. I'm so terribly sorry that you have to learn this, but you're old enough to know it, and when you're a grown-up, it will be important for you to understand this.
The problem with the web is that web pages are a horrid mix of text ("web pages are a horrid mix of text") and code:
if(window.addEventListener) {
window.addEventListener("load",
function(){ object[attribute] = val; }, false);
It's all on the same page, and it's all munged together. You can see it yourself, if you want to. In Firefox (you're not using Internet Explorer, are you?), go to the "View" menu, and select "Page Source." Voila! Javascript city!

Sometimes code takes user input, and mostly it doesn't. Now imagine that you're the developer who is writing a major site's web site - maybe hundreds of thousands of lines. Find the XSS flaws. Go ahead; we'll wait.

Actually, we won't. And your boss won't, either. Time is money, and the site has to go live, and get it done already, mkay? There's always time to fix it later, although somehow nobody ever does. Besides, why would someone do something like that?

We're going to keep seeing this sort of thing, folks. The reason is that the incentive structure is working against us. Spot who loses when there's a XSS flaw:
The Line of Business VP. He's all about profit and loss, and going online helps his profit.

The Director of Software Development. He's all about programmer efficiency - how many lines of code per dollar spent. Code reviews and testing take time, don't generate any lines of code, and while it improves code quality, this is astonishingly hard to measure well.

The Software Developer. He's all about meeting the deadline, and to a very small amount, he's about the number of identified bugs per line of code (yes, kids, that's precisely how it works).

The poor sod End User. Its his credit card or identity that gets stolen.
So, dear End User, you're screwed. Don't feel bad, I am, too. That's why I work really hard to limit the damage that can happen. That means giving up some pretty attractive things - like online banking.

Why would someone do something like this? We've asked that before.

3 comments:

Jay G said...

Interesting.

And here I was thinking that it was my laziness that kept me from doing my banking online.

Little did I know I was just being a shrewd operator...

Anonymous said...

Now imagine that you're the developer who is writing a major site's web site - maybe hundreds of thousands of lines. Find the XSS flaws.

Phooey. Real programmers don't waste time writing code to detect and counter these attacks after-the-fact. Real programmers write their code so that the attack never gets a chance to start. More precisely, real programmers develop coding standards so that they don't even have to think about blocking these simpleminded script-kiddie attacks -- the standards do it all automagically.

The Web would be a lot safer place if web-programmers had been trained as programmers first and foremost. But too many of them weren't.

Borepatch said...

Wolfwalker, great point. Real Programmers code defensively - validate user input, trap error/exit, that sort of thing.

Probably a factor of 100 difference in the number of exploitable vulnerabilities between best and worst practice.

Alas, not everyone can be in the top 10%.