20 March 2009

Updating the security budget

You might think in your cosy world of internal corporate web applications you don't need to worry about XSS and CSRF attacks (cross-site-scripting and cross-site request forgery) - after all, these are worries for public-facing web sites, not for us, surely?

Wrong!

Suppose your disgruntled employee leaves the project, and "in these times of crisis, you know", has nothing to do so gets scripting. Your disgruntled ex-employee, who previously worked on a precious sensitive internal system (aren't they all?), knows exactly which URLs will trigger a money transfer if accessed by persons with the right privileges, assuming they are logged in at the time.

Suppose that person is you - you're the manager of Whatsit and Whatnot after all, you have clearance for pretty much everything, and we used to do lunch together, so you'd happily open a link I sent you because it's sure to be interesting, entertaining, funny, informative, edifying ... you know, the kind of links I send to people.

But all I need to do is include this bit of code, which will be completely invisible to you:

<form id="maliciousForm" action="http://internal.bank.example.com/transferMoney" style="display:none;">
  <input type="hidden" name="from" value="myOldBossesAccount"/>
  <input type="hidden" name="to" value="myPersonalAccount"/>
</form>

<script>document.forms.maliciousForm.submit();</script>

If you happen to be logged in to http://internal.bank.example.com at the time (perhaps in another tab or window of your browser), that's all it takes to do the damage. To cover my tracks I'd need to be a lot smarter and more subtle, but the basic attack is trivial. And, more likely than not, your application isn't protected.

In fact, you don't even know what scripts are embedded in this page ... do you dare "view source" and check? What malicious clandestine script has executed while you were reading this paragraph?

Time to run to the program manager and get a security budget extension! While you're at it, please don't shoot the messenger: smarter and meaner people than I (yes, they exist) have already thought of this. And even if your disgruntled ex-employee isn't that smart or mean, he might well be willing to sell his knowledge to someone who is.

For more information, see Adam Barth, Collin Jackson, and John C. Mitchell, Robust Defenses for Cross-Site Request Forgery (pdf). The most reliable defence involves ensuring all potentially harmful requests are made via POST, not GET; and then requiring that any POST request includes a secret token in its body (possibly via a hidden input); the server validates the secret token and allows the request to proceed only if the token is valid. Ruby on Rails provides framework methods for simplifying this (seriously: you call the protect_from_forgery method).

Asking your corporate users to logout when they're not using your precious sensitive application is like asking dogs to stop wagging their tails. It's not going to happen. If security isn't your problem, then it's a problem.

This post was inspired by the "Web application security horror stories" talk at FOWA Dublin 2009 by Simon Willison

No comments:

Post a Comment