Skeptikal.org

Thursday, May 27, 2010

Once More, With Feeling: URL Shorteners

I got in a quick Twitter discussion last night with @xssedcom, the same guys that run XSSed.com. It came up because a link to LongURL got passed around. LongURL is a service that allows you to paste in links from bit.ly, tr.im or other URL shorteners, and see what the ultimate destination would be. It sounds useful, but there's a few problems with the idea.

I may be preaching to the choir here, but it needs to put in writing. Years from now, you can point to my blog posts and say "This Mike guy, he was a visionary. We really should have listened to him."

First off, LongURL is vulnerable to XSS. If a perfectly innocent-looking bit.ly link can pop an XSS box, it can just as easily rewrite its own page to look like it goes to a completely different location. This is bad, but not as bad as you might think.

Okay, it's as bad as you think, but not for the reasons you expect.

Even assuming that you could reliably see the final destination URL of a website, it would be little-to-no help at all. Sure, you could catch the obvious phishing links, but how many users have the ability to assess the validity of a web page based on its URL? I, and I consider myself a pretty paranoid/savvy web user. URLs don't compromise users. It's the content of the web page. And as has been made abundantly clear time and time again, you cannot trust any web page. Not your own, not your bank's, and certainly not mine.

When people talk about browsing the web safely, they always say something along the lines of "don't browse sketchy sites." No porn, no filesharing, no 4chan. Even if people followed it (and they don't), that advice has been useless for years. Bad guys are delivering malware and XSS attacks through news sites, advertisers, government websites, social networking apps, countless hijacked blogs, forums and ecommerce sites, the list goes on and on.

If you think you can really trust any website at all, you're kidding yourself. If you think that avoiding the shady websites will keep you safe, you're just as naive.

We've been telling users for years now to look in the browser and make sure they're on the right website when they check for the little lock icon. Very few of them do. And the "secure" websites are training them to continue ignoring it. Log in to your online banking. With precious few exceptions, banks are usually outsourcing their online banking to a third party company that's equipped to handle this newfangled web thing. When you log in, you're probably getting 302'ed to a subdomain of some company you've never heard of. Or maybe it's a subdomain of your bank's website, but hosted, managed, and developed by a third party. Even if you did notice, did you ever care? How much attention are you really paying?

And the more important question- how much attention do you think the average user is paying to the website he's on? Most users aren't even looking at that domain name. If they are, they still aren't looking at the rest of the url- the important bits, like where an open framing, open redirect, HTML injection, or flash object poisoning issue is being exploited. They don't have a clue how to evaluate that. Without testing manually, I don't even know for sure what all those bits of the URL do.

But going back to my original point, this isn't all bad, it just takes a shift in approach- a shift that may be already happening. If you assume you can't trust any web site, that means that you absolutely have to trust your web browser. You have to know that no matter where you point it, it will block XSS attacks, prevent CSRF, and pop up a friendly alert box asking your permission before installing malware. If you can't rely on your browser, you're finished.

The good news: browsers are getting crazy good. They get exploited all the time, but new patches often come out within hours. Not weeks. Not months. If you keep them up to date, they're actually some of the best software on your computer. (Yes, there have been some serious failures in the browser industry that would contradict this statement, but they are the exception, and they are getting more rare all the time).

...And the bad news. Currently, your browser does almost nothing to prevent XSS, CSRF, and other client-side web exploits. We're moving in that direction, but you can't rely on it. If you're not browsing with Javascript and Flash disabled, you're not browsing safely.

But you can do better. Echoing on previous themes from this blog, the best thing you can do is prevent Cross-site Requests. If you allow no cross-site requests, you have no problem with cross-site request forgery, no reflected cross-site scripting, no cross-site framing, no cross-site flashing, no open redirects. RequestPolicy. Use it. Remember my post earlier this week about boundaries being the key to security? NoScript is the spermacidal lubricant of the web. RequestPolicy is the condom.

If you're really paranoid enough to check your links with something like LongURL, you should be using RequestPolicy. As a side benefit, it blocks off-site redirects, so when you click that bit.ly link, you'll be presented with a server-generated 302 page saying "click here if you're not automatically redirected." You can then examine the URL (or more likely, ignore it), and click through.

Well would you look at at that... a short-url-expander, built right into your browser. What a novel idea.

Edited on 5/28/2010 to say "no reflected cross-site scripting" in the RequestPolicy paragraph. XSS still works, if it's same-site or permanent XSS, but even they get harder to pull off.

Labels:

Tuesday, May 25, 2010

On Language and XSS

While I tend to be very aware of my own use of language, and most of my own errors in the way I word are deliberate, I'm not really one to correct people. The way I see it, as long as they communicate their message, they've done an adequate job. Sure, there's always room for improvement, but we're all in a different place. That said, I've been fascinated for a long time by the way that language and psychology work together in both verbal and nonverbal communication, and it's something I feel like I can speak to. Consider this my first of many posts about how we can all improve our communication skills. Whether we're researchers reporting a bug, pentesters presenting results, CISOs trying to help management understand the importance of what we do, or developers discussing the pros and cons of a new feature, we all have a message to communicate. We all feel like we're not being heard, and we all feel like what we're doing is important. Might as well do what we can to help other people "get it".

We all know the difference between a vulnerability and an attack, but often mix them up in vulnerability reports, technical documents, and normal conversation. The issue on my mind today- "XSS Vulnerability."

I know I'm going against popular usage of the term here, but it has always irked me. Cross-Site Scripting is not a vulnerability, at least not for websites (it could be argued that it is a weakness for browsers). When explaining XSS to a layperson, we usually start by saying that it isn't necessarily cross-site, and it doesn't necessarily require scripting. Talk about poorly-chosen words.

When I use XSS, I'm usually exploiting an HTML injection bug. Sometimes I'll exploit a Javascript injection, CSS injection or other type of markup/code injection bug. Why not call it what it is? If we all start calling the vulnerability by a descriptive name, when we refer to XSS (the attack), it's actually appropriate, descriptive, and useful.

When we write vulnerability reports, assessments, technical documents, or even blog posts, precision is key. I'm personally guilty of the usage above (and again, I'm not going to correct anybody), but we really should be more careful about which words we use. I couldn't care less about "correct" use of language, but when our points aren't being communicated, it may be worth a bit of effort to fix.

Labels: ,

Monday, May 24, 2010

Why Diversity Is Mostly Bad

This post is intended entirely as a food-for-thought conversation starter. It hasn't been reviewed by my peers, my legal team, my mom, or myself. It was written by the gnomes I keep tied up in my closet, so don't quote me.

Within your web application environment, diversity is a bad thing.

First off, let me arbitrarily redefine words to support the points I'm going to make. I'm doing this at the beginning so you don't notice when I contradict myself later.

The "diversity" I'm talking about involves using a variety of platforms, programming languages, or frameworks for your web applications. I'm also talking about the applications themselves- more diverse applications are more feature-rich.

Here's what I mean by "application environment:" All the applications you're running and the systems that support them. Defining that environment is tricky, because frankly, there is no such thing. I've said it before, but web applications have no enforceable boundaries. Not your webmail, your internal CRM app, or your firewall's web interface. As long as our web browsers support cross-site communications, those sites can't be considered to operate in any environment other than the public "internet."

That said, you can still do some things to define your environment. Just like you segment a network, you can put different applications and different kinds of content on different servers, different domains (not just subdomains), and different networks. You could argue that this is adding diversity as well, but if you do, I'll ignore you and subscribe you to various spam mailing lists.

If anything can be considered "good diversity," it's the segmentation of an environment in an effort to define application boundaries. Most risk assessments take the size of an environment into account, but few consider the homogenicity (what? It's a real metric). In my incredibly well-considered opinion, diversity should be considered when assessing risk, even when no known vulnerabilities exist.

Diversity provides more surface area

Does it really need to be said? If you're trying to lock down an application, expose as little of it as possible. The more different features you have, the more the attacker can break. Sometimes you need features. Add them. If you don't, your marketing department will complain to management. When you add those features, add them knowing that you're increasing your exposure, and do something about it.

Vulnerabilities pop up around edge cases. Diverse application environments have lots of edges. Many people pay me to do vulnerability assessments on single applications, which I'm happy to do, but they're not getting the whole picture, and they overlook how other applications can affect them.

Do you have other apps on the same server? How does that affect the seriousness of a local file inclusion bug? Do you have other apps on other subdomains? How does that affect your cookie and session security? Does your crossdomain.xml policy allow *.akamai.com? Are you even considering these kinds of things? All those edges provide untested, potentially exploitable surface area to the attacker.

Diverse environments are hard to manage

You know this one too. It's hard to keep up to date on patches. It's harder when you have a variety of technologies in place. I don't have statistics on hand to back this up (if you do, please tell me I'm wrong), but a significant portion of the vulnerabilities I find in assessments are things that could be fixed with patches or configuration fixes. As much as I rail on the Web App Scanning industry, detecting outdated and misconfigured applications is something they are (or at least can be) really good at. The more diverse your environment, the more difficult this gets. To quote Mark Twain, "Put all your eggs in one basket and watch that basket!"

When it comes to custom code, it's the same thing. I did a recent assessment on an application and found that they had excellent XSS countermeasures in place, but they weren't in place on every form throughout the application. They've been working on manually adding those controls to every form in the app. I only had to find one place where it wasn't implemented, and all the work they'd done to date was for naught. If they'd been using a centralized library to implement those security controls, they'd be done already. If I did manage to find anything, it would only take a few lines of code to update everything.

In most organizations, the biggest problem isn't finding the holes, it's fixing them. While vulnerability assessments can be pricey, it's nothing compared with the cost of developing fixes for the vulnerabilities that are found. If I'm wrong about this, then somebody is paying me too much, and not paying their developers enough.

If it's not a cost issue, it's a time issue- when I start a penetration test, I generally have a feel for where the app is going to be vulnerable in the first few hours. I may spend weeks on finding and documenting vulns, but I've done enough assessments that I can almost immediately tell you where you need to focus your remediation efforts. And yet, when I report vulns (to clients or to unwilling victims of my research), they go unfixed for months, years, or forever.

I take a lot of pride in being very good at my job, but it's not the hardest job out there. I just poke web apps until they fall over. Hacking is easy, but fixing the holes I find is much more difficult. Fixing things becomes far easier when you have homogenous systems.

Boundaries are the key to security

Now, you may be thinking that I haven't said a thing you can disagree with, and you can chalk that up to my remarkable debating skills. Keep in mind that this goes against conventional wisdom- Most people think that variety in an environment will limit an attack. Wouldn't that have lessened the impact of the worms of the late 90s? Well, yes and no. Those worms hit systems that were homogenous, but they were also poorly controlled. Technological monoculture isn't such a bad thing if we can break it up by putting boundaries around things.

Want to keep your applications from affecting each other? Put them on different servers, different networks and different domains. Want to keep Facebook from sharing data with the websites you visit? Use different browsers. SQL injection? XSS? Stack overflows? Use tokenization to put boundaries between content, presentation and code. Web browsers are so good at blurring those lines that we often don't even realize it, but they do that at the expense of security.

Effective security controls aren't attack-specific. They simply define and enforce boundaries.

Labels: ,