CCing justdave, as a Bugzilla security issue is mentioned in the comments. Gerv
The attack described here is well-known and called "Cross-site request forgery". Most believe that it is the web application's responsibility to fix it, not the web browser's. This is probably a duplicate of one of the dependencies of bug 322301. Can this bug report be made public?
> The attack described here is well-known and called "Cross-site request > forgery". Obviously I was not aware of this fact :) In fact, http://en.wikipedia.org/wiki/Cross-site_request_forgery describes exactly this problem. As there are so many vulnerable web applications, I guess few people are aware of this kind of exploit. I don't think there is any acceptable way for the web application to fix this. If you put the session id into a hidden field, old browser tabs cannot be used any more---unless you use some Java script, which is not enabled in every browser. I'd agree to make this bug report public.
Instead of the session ID, you can use something unchanging about the user's login or cookie. (Preferably one that changes if the user's site password changes.)
Users tend to save HTML files or send it to friends, unknowing that it contains sensitive information (like, for instance, a cryptographic hash of their password). This would enable their "friends" to engage in cross-site request forgery attacks.
Agreed on this one being a CSRF issue that should be fixed in the webapp, not the browser. As for fixing CSRF, the standard mechanism is to generate a CSRF "token" (a random string) and embed it in the form, and store the token in the server-side session variables. Alongside it, you store the page which it should target. Then, on the receiving script, you verify that the token passed in the POST vars matches one of the tokens in your session vars, and that the associated target page is correct. Once it is used, the token is deleted from the array, making it useless. Additional security can be provided by making the tokens expire automatically after a few hours. I do this in PHP by maintaining an array in the following format: $_SESSION['csrf-tokens'] = array( array('token' => 'as2f4iuaXmvxs...', 'target' => '/search.php'), array('token' => 'KdtTYu9mCno8w...', 'target' => '/search.php'), array('token' => 's7R22jwe3dP6p...', 'target' => '/console.php'), ... ); Each token is generated via entropy from /dev/urandom. Having a single global CSRF token that is distinct from the session ID (e.g. a single var stored in the session) is also acceptable, but provides no damage limitation should the token be leaked. In the one-time token model, a leaked token allows for only one CSRF attack to be performed per leak, and only allows that token to be used on the specific target form that the token was generated for. In the single-token model, a leaked token means that all pages are vulnerable to CSRF.
To be clear, the tokens I showed above are not static - they are generated on the fly when a page is loaded that contains a form. The array I showed was just for descriptive purposes.