del.icio.us .:. tweet

Amazon Wish Lists Are (No Longer) Dreadfully Insecure .:. kentbrewster.com

Updated 3/27/2009, 10:01PDT: looks like this may have been fixed a few minutes ago. Read on, to learn more about what was happening.

Old friends may remember the How to Tell if a User is Signed In to Service X series, which ended last year around this time. As you can see from the comments in Patching Privacy Leaks, I advised users to sign out of Amazon.com on 17 October 2008, but did not say why.

Six months and multiple warnings later, nothing's been done. So here it is:

If you are signed in to the United States version of Amazon.com and have a wish list, the button should add an item. You'll see an alert with a success or failure message, and then this paragraph will change to tell you what happened and where to go to see it. If you're using Firefox or IE, we will be able to determine your Amazon login status, by watching onError. If all else fails, we will assume after a few seconds of inactivity that something went wrong.

I'm not sure what will happen if you have multiple lists or if you delete your wish list. Taking your wish list private will make it invisible to the bit that shows your name, but will NOT stop the item add from happening.

How It Works

By examining the source of Amazon's Universal Wish List toolbar bookmarklet, we find something suspicious: an HTTP GET that seems to modify data on behalf of the signed-in Amazon user. This is trouble, since Amazon is depending only on browser cookies to verify user identity. Anyone can create an URL, like this:

http://www.amazon.com/gp/wishlist/add/ref=wl_bm-add
?submit=1&operation=add&mode=JS&priceInput=&id=
&imageUrl.0=http%3A%2F%2Fi2.ytimg.com%2Fvi%2FE62DXiL_8Vs%2Fdefault.jpg
&name.0=Raccoon%20Party
&itemComment.0=amazon%20wishlists%20are%20dreadfully%20insecure
&productUrl.0=http%3A%2F%2Fwww.youtube.com%2Fwatch%21v%3eDeQ1DN7n2Eg

... and fire it off on behalf of the signed-in user. Here I'm being polite and requiring the user to click a button, but it would be trivial to list it as the SRC attribute of a SCRIPT or IMG tag.

Data Returned from Amazon

AUWLBook.results('SUCC', 'Wish List',
'http://www.amazon.com/registry/wishlist/JWMG6ATT26YQ/ref=wl_bm-view-list');

This is very helpful: it gives you back a SUCC or FAIL message, the title of the victim's wish list, and an URL pointing back to it, whether or not the victim has market his list as private. If the list is public, determining the victim's name is trivial; running the wish list through YQL and trimming the result with Pipes spits it right out.

I'm not going to go into great detail about how the JavaScript behind the exploit works; it's pretty self-explanatory. Feel free to view source and poke at it yourself, if you like.

Why It's Scary

  • I can think of lots of evil things to do with this, from the crude (add a bunch of porno links to your victim's wish list and send it to his boss or his wife or his mother) to the obvious (causing any visitor to my site to instantly wish for my book, over and over and over again) to subtle things like gray-hat SEO, in which links quietly stack up in thousands of public wish lists and change search engine results.
  • Possibilities for clandestine data mining--many people add their birthdays and home locations to their wish lists--abound. Once I know your name, home town, and birthday, I have a fair number of the items most commonly used as security questions for password recovery.
  • Although I haven't documented it here, there is at least one link on the user's wish list that will save a change to its configuration in response to a GET, and not just add an item. This is very, very bad.

The bottom line: Amazon never told their users that wish lists are actually online presence indicators and can be used invisibly to gather data about them wherever they go.

Lessons Learned

  • Never use GET to modify data on behalf of the user.
  • Don't give back live, executable JavaScript wrapped in easily-intercepted callbacks.
  • Returning HTML to signed-out users and JSON to signed-in users allows curious operators to determine the user's sign-in status by watching window.onerror.
  • Shipping a toolbar bookmarklet that changes data on behalf of a signed-in user is probably not a great idea; now that it's broken, everybody who's installed it will have to either re-install it or quit using it.
  • Have a clearly marked path for reporting security holes, listen, and be extremely responsive!

Thank You

  • Last-minute testers: Norm, Cyn, Ryan.
  • Those guys who do the thing in that place I used to work, who tried multiple times to get Amazon to fix this. They are heroes; I wish people would listen harder when they speak up.

Comments from before Disqus:

Copyright Kent Brewster 1987-2014 .:. FAQ .:. RSS .:. Contact