Ajax Security, Part I
“Did you see 1 Raindrop today?” a coworker asked, referring to something Gunnar Peterson had written about Ajax security. I went off on a little rant about how yes XMLHttpRequest exploits are interesting and Amit Klein’s work is marvellous, but XHR can be used in an exploit regardless of whether a web app actually uses Ajax, that from a development perspective the approach is the same: we’re accepting requests from an untrustworthy client, so we need careful consideration of security throughout the development lifecycle, solid input validation & output escaping, session management, access control, and so on.
He waited patiently and smiled knowingly. “Yes, Sam, but you are already thinking about these things.”
Ah. As I also frequently complain, thinking like this is still unusual. That’s why software security is such a problem.
So I started looking around to see what was happening in the Ajax security space. It isn’t pretty, but the Ajax angle to the security problems is as overhyped as Ajax itself. There’s been a fair amount of discussion/coverage worth reading, including a new chapter in the OWASP Guide 3.0 draft. Gunnar’s post points to work by Amit Klein that I highly recommend.
On Tuesday I gave a short and overcaffeinated talk about Ajax security to my local OWASP chapter. To follow up on that, I’m starting a series of posts here addressing the topic in greater detail.
Executive summary: in the rush to add Ajax functionality to web applications, security is being disregarded or included as an afterthought (which often amounts to the same thing). Ajax itself isn’t insecure, but it sure can be unthinkingly misused and made insecure. Ajax can make other attack vectors like cross-site scripting and cross-site request forgeries worse, whether or not you actually use it in your application. As it has recently been made clear, XSS is far worse than we’ve thought, so it is important to be careful.
My position is actually a little more nuanced than that, and may well change as I write here. We shall see.
Quick Intro to Ajax.
You may already be familiar with Ajax, especially if you’ve read this far without being bored out of your mind. But just so we’re all on the same page, let me take this opportunity to show off a little Flash demo that my colleague Dave Kruse whipped up over breakfast just before an Ajax presentation that we were about to give.
You know how web applications have traditionally worked. Your browser makes a request to a web server, and the server responds by returning a whole new web page.
(For now, until I add some JavaScript to dynamically show/hide the animation, here’s a link to the first demo Flash movie. Thanks to Dave for his permission to use this here.)
With Ajax, your browser makes a request and the server responds, but this time with a small snippet of data that is used to update just a section of the page. No need for a full page reload.
(Link to the second Flash movie.)
Two key elements to this are that we are using JavaScript to make HTTP requests and to update the HTML page. We’ve actually been able to do this for some time, but in Ajax we can more easily manage the HTTP request and response using an object called XMLHttpRequest. The response from the server is usually one of the following:
- XML, which is parsed by JavaScript to generate the (X)HTML to add to the web page;
- more commonly we’re seeing JavaScript, which is
eval
‘d and run. JSON is a popular way to do this. - the actual HTML that will be added to the page.
Ajax use in web applications falls along a spectrum ranging from small usability enhancements such as auto-populating a drop-down without reloading the page (dubbed by Harry Fuecks as HTML++), to mopre full-blown client-side apps, where lots of business logic is in JavaScript on the browser. How you choose to use Ajax will affect your security posture, as we will explore in future posts.
Ajax Security
Fundamentally, Ajax is no different when it comes to web application security. We have the same concerns:
- We’re dealing with completely untrustworthy clients.
- Input validation is essential. From the perspective of server-side code, requests are coming in from anywhere — untrusted clients, remember? — and we need to be sure that the data in the requests is what we expect.
- Escaping output, nothing new there.
- We have to pay careful attention to session management and access control.
- Code injection is a problem. JavaScript, XML, LDAP, DOM…
- The list goes on. See resources at OWASP. There’s even a new Ajax chapter in version 3 of the OWASP Guide.
That said, developers (and architects, too, don’t let them off the hook!) are making security mistakes when they introduce Ajax to their applications. I don’t blame Ajax for this: the real danger is JavaScript that operates in a browser environment, allowed to make HTTP requests and modify the DOM, and web apps that allow this to be abused easily. Actually, the real danger is that software security is too often an afterthought. For some reason, the rush to use Ajax has led to developers placing too much trust in client-side code. What worries me most about this is that at separate presentations at last week’s Black Hat, Jeremiah Grossman and Billy Hoffman described a new spate of JavaScript malware that takes advantage of XSS and CSRF vulnerabilities to do some seriously scary stuff. Grossman describes XSS as the new buffer overflow. Ajax isn’t necessary for some of the techniques described, but it can make an XSS attack worse — whether or not you use it in your web apps.
So what’s different about Ajax from a security perspective? I’ll take that up in the next entry.
13 Aug 2006 Sam
Great Podcast on XSS…
I saw this great podcast on cross-site scripting (XSS) attacks come through on Sam’s del.icio.us links. Dan Kuykendall covers the anatomy of an XSS vulnerability starting at square one….