Over the past few months I've published articles documenting an extremely trivial weakness that allows any third-party operator to determine if its users are signed in to several well-known Web services. This is pretty clearly information that ought not to be shared; even if it's not explicitly stated in the service's terms of service, it's expected by the public.
As a result of several eye-opening conversations I've had while at SxSW this year, I've taken down all of the articles detailing live exploits. As trivial as they are, I should not have disclosed any specific vulnerabilities without warning the service operators first, and I want to strongly discourage anyone from following my example, which was the wrong thing to do.
I will, however, present an overview of the methods I used, and the lessons I learned during the process.
If the contents of that file vary sufficiently depending on the user's cookies--which almost always contain his or her login status--a third-party site can infer information which should be private, beginning with the user's login status and potentially including much more.
Detecting Vulnerabilities in Your Service:
Before you push a new feature to your AJAX-powered site, please run through the following steps:
Get Firefox and Firebug, and sign in to your service.
Go to any page that has an AJAX-powered interaction that should only be usable if the user is signed in. This could be a message post, a profile update, a mailbox read, a social network connection update ... we're looking for anything that affects the content of the page without reloading it that should only be visible if the user is logged in.
Once you've found it, run it.
Open up Firebug, go to the Net tab, and find the interaction.
Open the interaction's URL in a separate browser tab.
Go back to the original tab and sign out of your site.
Open a new tab, and paste in the interaction's URL again.
View the source code of both states, and answer these two questions:
If not, when both states are loaded as SCRIPT tags, do they throw different errors?
Make sure your error messages come down in the same format, whether or not the user is logged in. If an URL returns XML when the user is logged in but redirects to the login page when he's not, you're vulnerable, because they throw different errors when included as SCRIPT tags.
If you're offering an API, be sure that your endpoints throw the same errors whether or not the user is logged in. Are you offering a JSON object wrapped in a callback to authenticated users and a redirect to your login page to others? One throws an error and the other does not.
Test all the URLs on your site that are supposed to be POSTed and be absolutely certain they return the same error whether or not the user is logged in, in the event some clever fellow tries a GET.
Keep an eye on your referrer and error logs. Are your AJAX endpoints starting to throw a lot of those please-go-log-in errors? Are they being linked from sites that have no business peeking or poking at them? Somebody may have already found a hole in your site.
Have a clearly marked path for reporting security holes, listen, and be extremely responsive!
This isn't meant to be a definitive list, just cautionary squawking about a very common vulnerability. Please be careful; your users are depending on you.
Any malicious third-party operator who knows about this can ping the script by including it in the body of his page with a <SCRIPT> tag. All he has to do is set a setInterval loop to check if mySiteLogin has changed every few seconds; if it does, he has your login.
This seems like it ought to be a really obvious Bad Thing, but I've run into some very popular Web 2.0 sites that send down your login, your e-mail address, and a list of your friends' logins and e-mail addresses in this exact manner. (All of those sites corrected the issue immediately, thank goodness, but I'm sure more are out there.)
woot .:. 2008-05-28 09:06:22