There’s news and discussion about a recent flaw in Gmail that can expose your contact list to any page.
Summary: If you are logged into a Google account (email, personal homepage, etc) then another site can use that authentication to access your contact list. Log out before visiting sites you semi-trust.
This is an example of Cross Site Request Forgery – you learn something new every day. There’s a detailed writeup here on the gmail flaw.
Update (1/1/07): The flaw appears to be fixed.
How it works
The code is pretty straightforward. Basically, Google docs has a script that runs a callback function, passing it your contact list as an object. The script presumably checks a cookie to ensure you are logged into a Google account before handing over the list.
Unfortunately, it doesn’t check what page is making the request. So, if you are logged in on window 1, window 2 (an evil site) can make the function call and get the contact list as an object. Since you are logged in somewhere, your cookie is valid and the request goes through.
Also, if you check the object that is returned, you see fields for the contact’s name, email and “affinity”. Presumably, a higher affinity means a more-emailed contact, so it may be possible to know the relative importance of your contacts.
Possible solutions
Google is run by smart people and I’m sure they’ll have this fixed soon. A few suggestions appear to be popping up, all centered on making sure the user is on a Google.com page and not a random site:
Referrer blocking: Block all requests from sites not in the google.com domain. However, some people run referrer-blocking software. It may be the price they have to pay for security, but there could be other consequences.
Script checks: An idea I had was to check the window.location (just like you check the cookie) to make sure it’s coming from a google.com domain. This is another way to see what page is making the request.
Challenge-response: Google pages (like Gmail) can have some token or unique, computed data that they submit with their requests. Random pages won’t have access to this token when they make the function call. The above solution works, but can be cumbersome since it has to be added to every form field.
(From user JRF on reddit): Include part of cookie in the request URL as a unique token that only a “real” Google page would know. Need to watch out for proxies/browser history (accessible from other pages) being able to access this unique data. May need to seed or salt it in a challenge-response system. This is known as “double-submitting” the cookie – the server can check that your cookie actually contains the value you submitted (the evil page can’t access your cookie directly, only the fact that you are logged in).
It’s interesting to think of solutions to this problem – do you have any others?
I’m sure Google will have this fixed, but beware browsing random sites on the net (obvious, yes, but be especially wary). Log out of Google first.
This is a wake-up call about the realities of Web security.
Other Resources
- CSRF Explanation & PHP Code](http://shiflett.org/articles/cross-site-request-forgeries) – has examples of token authentication using PHP.