Skeptikal.org

Thursday, September 2, 2010

Cross-subdomain Session Fixation

Last fall I wrote a bit about cross-subdomain cookie attacks. As often as I come across more uses for them, I think that they are a much more serious issue than most people (myself included) have made them sound. Today, I came across a variant which I'd theorized about in the past, but never bothered to find in the wild, and I think it merits some attention.

You may be familiar with Hack Is Wack- a stupid marketing campaign from Norton/Symantec. The premise is simple: users submit videos, which are voted on, and the winner gets to roll with Snoop Dogg...'s manager. You may not know it, but most of Snoop's music is information security-related. "What's My Name" is about AuthN, "Drop it like it's Hot" is about SQL injection, not to mention constant references to cron, gzip, and other unix commands in his lyrics. It's really a pretty natural match.

At any rate, the Hack is Wack site is chock full of holes. For example, there's the publicly available, indexed cache directory with all that SQL, JSON and other data. There's the XSS vulns (HTML5 only, though it should be simple enough to rewrite), CSRF holes, and the Flash upload issues in the video upload script (a Joomla module that appears to have been used without any quality control or review despite the fact that it's currently in Alpha)

A security company using bad code in a marketing site? Shocking, I know. I'm really not here to harp on them though. I'm over security vendors being full of shit- they all are, it's not news.

I just found a particular attack vector interesting.

The voting system for uploaded videos is grossly vulnerable to CSRF, and probably much more serious things, based on the format of the "vote" URL (unencoded, for ease of reading):

http://www.hackiswack.com/index.php/home/rate.html?videoid=\'.24.\'&rating=4

This means that I can create image tags in my own website to vote for a specific video and stuff the ballot box. Classic CSRF, right? It's something I've talked about before, but unfortunately, this one isn't quite so simple. You have to be logged into the site to vote, and they prevent a user from voting twice for the same video, so to manipulate this poll, we really need to create a whole bunch of user accounts. The user registration page is part of the main Joomla codebase, and it uses session-based tokens to prevent CSRF- the way they should.

The interesting thing here, is that the application doesn't enforce the HTTP Host header. Instead of http://hackiswack.com, there's no reason you can't use the application from http://184.106.223.144, or more importantly, http://hackiswack.skeptikal.org (no, this doesn't actually go there, but there's no reason it can't).

Once I have my own domain set up, I can easily force a visitor to skeptikal.org to assume arbitrary session cookies that will also be sent by his browser to hackiswack.skeptikal.org, and with a known session cookie, I can request the page myself and parse it for the CSRF token. I can then embed that token in any forms I force the user to send, bypassing the protections that Joomla so carefully puts in place.

All right, so this is a lot of work, and probably isn't practical for stuffing ballot boxes, (especially since there are already much more serious vulnerabilities to take advantage of) but as a way of bypassing CSRF protections, it's perfectly valid. There are plenty of times where a CSRF protection mechanism can be bypassed with a simple session fixation attack. A variation on this was described by RSnake last fall, using DNS rebinding instead of subdomains. It's probably more potent with DNS rebinding, but a cross-subdomain attack tends to be much simpler to set up.

The key to remember is that in this case, you can't take over an arbitrary session, so it is of limited use for, say, compromising an Admin. However, if you want to log a user into a website (with known credentials), or otherwise force him to do something on your behalf, it's a very useful technique. Something to keep in mind, at least, and another reason why websites that don't require specific Host headers should be considered vulnerable.

Hat tips to The Harmony Guy and Packetwerks for pointing out some of the holes in the Hack is Wack site

Labels: ,

Friday, June 25, 2010

Getting The Gist Of Things

This blog post represents a progression of thought. I'm not making arguments, I'm making suggestions as they occur to me.

Security is very hard to quantify- it's the classic "how to prove a negative" problem, coupled with the "every application has bugs" problem, and wrapped up with the "holy crap this is impossible" problem. Maybe we don't need to accurately quantify it though. I mean, when we're doing the risk assessment part, we want to be close, but as far as the remediation phase? In my experience, at the end of a vulnerability assessment, people usually care about about three things:

a) What issues do I need to fix?

b) What kinds of issues are most common?

c) Where does my organization stand (relative to the competition and the global web application environment)?

When people focus on one of these issues, which one they fixate on can be very telling. While somebody should always take a look at the report and fix the specific issues (where possible), the people who only care about the found vulnerabilities often refuse to look at the big picture.

If we're doing vulnerability assessments to find bugs, we're going to fail. This is the problem with every assessment: It won't find all the vulnerabilities. What it can do is find "a bunch" of vulnerabilities, which collectively can inform you about where you need to put your efforts. The job isn't done when you've patched the bugs. The goal of a vulnerability assessment, at least from an action standpoint, is to know where you stand security-wise. If you can do that, you can manage the specifics.

In Jeremiah's response to my last blog post, he discussed some of the problems with web app scanner inconsistencies, making the point that all scanners will miss something, and that some are better than others at specific things. I'm going to neatly ignore that and talk about something slightly different.

He's right, but it's a limited view of the problem. A scanner may not be able to find a specific issue, or all instances of a specific issue, but a human tester won't either. The quick wins that the scanner provides in tracking down holes should be considered a byproduct- we should use the scanner primarily to get a feel for where the problems exist. If you find out that your servers are rarely up-to-date, or that you have a high concentration of XSS vulnerabilities, that is useful information in itself. The most important part of a report should be a venn diagram of weak spots, not a list of vulnerabilities. I'd argue that, from a high-level security management perspective, whether an exploitable issue is actually found or not is irrelevant. That's not the goal.

The scanner's results will be skewed and inconsistent, just like the human tester. Unlike the human tester, a scanner will be consistently inconsistent. We can compensate for that. If we have base metrics regarding which vulnerabilities are most common in which situations (numbers we're only beginning to put together as a community), and we know that a scanner consistently produces skewed results, we can calibrate our reports to compensate. We can then spot check the weak points to confirm our findings, and further calibrate the reporting process.

Accuracy is always ideal, but lacking that, the ability to make reasonable estimates about where the problems lie would speed up the bug hunting process, the patching process, and allow us to focus training, policy and development procedures. With that approach, the problem of scanners "missing things" largely goes away, and in fact even the worst scanner will still produce useful results. On top of that, scanners can be easily compared with simple relevancy ratings between the predicted vulnerability distribution, the discovered issues, and actual findings (from supplementing the scanner with human testing).

Scanners are a tool in the bag, and they're a pretty good one. If the results aren't interpreted correctly, it doesn't matter if you have the world's best bug hunter on your side. An assessor's most important role isn't in finding the bugs- it's in interpreting the results.

Labels:

Thursday, June 24, 2010

Are Secure Web Apps Possible? Yes (and no)

Mike Rothman wrote a post addressing the general problem of web security, titled "Are Secure Web Apps Possible?". My answer: Yes. And no. The general conclusion Mike comes to is that web scanners are useful for generating quick wins, but hardly complete. As long as they are used with that knowledge, they are excellent tools to have available.

He's absolutely right, but there are some problems with web application scanners. Well, "some" is an understatement. In traditional application testing, the attack surface is relatively small, and fairly well-defined. The rules for building a secure application haven't changed much in the last few years, and the basic language communicating with the hardware has been relatively stable for quite some time. At the very least, it's well-documented. The fact that we still have critical bugs popping up in common applications has more to do with the development process than the technology itself.

With web applications, it's not so simple. The platform is not the hardware. The platform is the web browser, and the web browser speaks hundreds of dialects, in dozens of languages, and they all interact. There are many more layers between the user and the hardware, and every one of them is exposed- to the network, to malicious users, to malicious servers, etc. The attack surface that presents is massive, but more importantly, it's dynamic. With new standards being added to the browsers, old ones being phased out, and the way that they interact changing constantly, creating a scanner that understands the context a web site runs in seems impossible. When you consider that there are about a dozen browsers currently in mainstream use (including mobile versions), the problem just compounds.

I don't expect web scanners to ever be able to address those problems, but I hope I'm wrong. Currently, it takes at least a few years of dedicated experience before you really get a "feel" for finding and assessing bugs, and RSnake doesn't scale well.

My opinion is that the fundamental architecture of the web needs to change drastically before it is even remotely close to "secure." Until then, all we can do is fix bugs, fix development processes, fix user behavior, or try to hack on kludges when the problems come up.

The last solution doesn't seem very helpful, so let's take a look at the other three.

Fortunately, in many cases, the subtle and obscure bugs aren't the problem. Security isn't black and white, and the trivial ones are easy to fix. If a company like AT&T hasn't at least found the simple issues (like the ones used in the recent so-called "hack"), they are being negligent. Mike is right, getting a few quick wins with a web scanner isn't a bad idea- just make sure you know what that means. You won't get everything, but you'll get the easy stuff, and this is where risk assessments really shine. That's a much bigger topic than this blog post can handle though.

Fixing development processes is just starting to catch on. Web developers, browser developers, and low-level system developers alike are beginning to adopt SDLs, and we're already seeing positive results. People are developing frameworks for secure development (more on that in future posts). Things are happening.

If development processes are hard to change, user behavior is next to impossible. Still, the truly paranoid user can expect a decent level of security through careful system configuration, limited browser functionality and general security awareness.

The general conclusion, something we all know, is that security is an extremely difficult, complex process. Many facets are involved, but each can only be addressed by a specific party. It's each of their responsibility to help all of us.

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

Wednesday, April 14, 2010

5 Reasons HTTPOnly won't save you

In the fallout from the Apache.org hack, several people have suggested that HTTPOnly cookies would prevent this attack. This discussion seems to come up every time XSS is used for credential theft, and I'm getting tired of posting rebuttals, so I figured I'd write one post to point people to.

If you're not familiar with HTTPOnly cookies, there is a flag set on the server side when sending the cookie that instructs the browser to avoid giving client-side scripts access to that data. When the HTTPOnly flag is set, the cookie is only used for, and accessible through, HTTP requests- hence the name.

Don't get me wrong- I recommend you use the HTTPOnly flag on any applications you develop. It's easy to set the flag, and it can be a useful defense in depth measure. However, it does not solve any real problems. At the very most, it's a small hurdle for the attacker. Too often, people fixate on the specific exploit, and not on solving the problem. Assuming he is going to the trouble of writing custom exploits, it won't stop him. Here's why.

Inconsistent browser implementation
While the HTTPOnly flag is supported by all the modern browsers, it didn't used to be. Archaic browser support isn't really a huge concern, but it's not completely insigificant either.

Cookie Tampering
If we assume that I can't read your cookies, that doesn't mean I can't still write them. HTTPOnly cookies can still be overwritten in some browsers, and can be overridden (by setting a more-specific cookie (such as www.example.com where the HTTPOnly cookie is only restricted to example.com. The browser should send the www.example.com cookie when both exist. Some browsers will send both. It's complicated)). The attacker may not have access to your session ID, but if you're not regenerating it every time a privilege change happens (you should be), all the classic session fixation attacks apply. Even if you do regenerate the session ID, the attacker can still force you to take over his session. Depending on the situation, that may be enough.

Cross-Subdomain Information Leakage
Do you have any other applications on other subdomains? An HTTPOnly cookie that's set for example.com will also be sent with any request to ancient-app-that-you-forgot-about.example.com. See my paper from last fall for more details.

mod_userdir
Okay, those of you not on a mass-hosted webserver can tune out, but the millions of you that are, take notice. If your cookie domain is set to "example.com", path is set to "/" (as most are by default), and you're on a mass-hosted webserver (particularly cPanel, though this applies to others), nothing is preventing user "foo" from placing a script on http://example.com/~foo/cookie_logger.php- which he technically owns. Your browser will happily send it those HTTPOnly cookies.

Ignoring the Cookie
Here's the real elephant in the room. Why do attackers want your session cookies in the first place? Trust me, session IDs aren't really that exciting. The attacker's goal is really just to gain access to the application. If they have the ability to execute Javascript in your browser in the context of the targeted website, they've already won. Stealing the cookie happens to be the quickest route to that goal, but it is by no means the only route. What's preventing them from making AJAX calls directly to the application, setting you up as a proxy? Sure, it takes a little more bandwidth, and is slightly more visible, but honestly, how many users would notice a page taking half a second longer to load? How many analyze every request a web page makes?

HTTPOnly cookies are designed to prevent credential theft, but only in situations where the application is already compromised via XSS. Credential theft is a means to an end, and there are plenty of other means to that end. Attackers have options. Defenders don't.

Labels: ,