The main issue is that we offer the ability for a user to change their email address. This is a very common feature, and thus something a lot of sites fall victim to. The basic nature of an XSS is that a malicious site can cause you to POST or GET arbitrary URLs. Since cookies are always sent along with the request, if you are authenticated, the attacking site can cause you to hit traditionally protected URLs. This is normally a non-issue, as only your browser reads the content -- the attacking site has no visibility into the data. However, it is an issue when there are side-effects, when the malicious site can change things to their advantage. In this case, they changed the email address to their own via a post. From there, all they had to do was hit the password reset function for their email address.
As soon as we found out about this, we immediately turned off email and password reset. This prevented the XSS from working, as the urls in the attack 404'd. This was a temporary solution.
Next, we now require you to enter your current password when you reset your email. This would also prevent the XSS, as the attacker would need to know the users password. It also prevents against other attacks, such as someone with physical access to your logged in session from resetting your email address with out you knowing.
We also implemented the Django CSRF middleware. This protects the rest of our forms on the site from similar problems.
As for impact, our audit logs show that only the attackers account was compromised for the sake of his demo. Fortunately, he did not randomize the email address used to change the password. If anyone did become a victim to his example, it would not have changed the email to his address (we only allow unique email addresses in the system). However, it is possible this XSS was in "the wild" with other addresses, but according to our logs and the nature of the vulnerability, it is highly unlikely that it impacted any users.
As others mentioned in the comments, it would have been great for the author to contact us before posting this. As motivation to future security researchers, we will happily offer a bounty if you report your bug to us before posting it publicly. In fact, if you're really good -- we'll happily make the bounty a full time job with benefits! :)
If you have any questions or concerns about this issue, please do not hesitate to contact me personally! polvi@cloudkick.com
The attacker, EvilPacket, recommended the wrong thing. They wrote, "The best protection I have seen so far is to use tokens that are time sensitive, tied to the user session and verified when the request is submitted back to the server."
The reason that is wrong is because the attacker can request a new token using the same method it submits a change.
Email and passwords work as challenges as they both cycle through the human being that owns the account, rather than just the browser. it's important to have more than one method that is tied to the account owner because if you want to change one, you need to use the other to confirm.
1. Attacker makes one request. I read EvilPacket to suggest the time-limited challenge is a token stuffed into the cookie. Attacker then waits a few seconds before making the change request with the token safely in the cookie.
You should rather load a challenge in the submit form. I do recommend that for user-generated content.
http://usemod.com/cgi-bin/mb.pl?EditHash
2. However, if this page is vulnerable to HTML injection, you can get the hash back by embedding Javascript that creates another iframe or img back to yourself on the attacked page. http://www.codecouch.com/2008/10/cross-site-scripting-xss-using-iframes/
So, I just find it safer to ask for the user's password.At this point, we're "discussing" something on Hacker News that even Wikipedia has right (search for "XSRF"). But if you have to think about how to handle this problem, you're doing it wrong. Use your framework's builtin XSRF protection.
If your page is vulnerable to DOM injection, you have much bigger problems than XSRF.
Also, you know DOM injection is a very common problem. It's better if you don't have to assume the website has no DOM injection problems to do the right thing.
Therefore, I think it is reasonable to recommend asking password confirmation as a general best practice, since it's a straightforward way to be the safest. I'm not sure why you are arguing with that point.