Some web applications, banking websites in particular, prevent you from using the browser\'s navigation buttons, opening links in new tabs or even refreshing the page. Ofte
From javascript you can detect a new window by checking the length of the history.
You can capture a backbutton event by injecting an iframe in your page, pointing to (e.g.) http://www.example.com/cacheable_blank_page.html then changing it's location to http://www.example.com/cacheable_blank_page.html#offset. When the user clicks on the back button, the iframe reverts to it's original location. If you attach an event handler to this then you can detect the back button and handle the situation appropriately.
There's some code to do that here.
Ultimately the problem that peolpe usually use this for is that their server-side code is poorly written and is innappropriately storing transaction related data in the session and/or overusing PRG patterns - ultimately this is a nasty hack intended to pre-empt problems rather than a solution to the root cause of the problem.
SilverlighFox's token based solution is great for CSRF but does not solve the problem of poor state management on the server.
Rather than having a different URL handler for different pages, they are probably passing the page state using POST variables passed by hidden form fields and the same URL handler will handle each request.
e.g. the link to "recent transactions" could be coded as follows
<form method="post" action="https://www.example.com/securebankpage">
<input type="hidden" name="action" value="recentTransactions" />
<input type="hidden" name="token" value="3423432432535235325098525125242" />
<input type="submit" value="View Recent Transactions" />
</form>
Where token
is a secure random generated value that is recorded server side against each user session and action combination and the server side records are validated against the submitted form values when the user navigates.
As each page is loaded via the POST method, it is not possible for the user to repeat the action by accidentally clicking back and then accepting the browser prompt to resubmit the data. This is because the token
will have been marked as already used server side and will not allow the token to be used again. Useful if the back button navigated to the money transfer page as the money transfer will not be accidentally repeated. This also can protect against certain types of replay attacks.
This architecture also guards against CSRF as the token value would be unknown to any attacker that tries to initiate a POST to https://www.example.com/securebankpage
from their site and passing the action
as doMoneyTransfer
.
The tokens should be time limited so if not used in a set amount of time (e.g. 15 minutes) they should be marked as expired and if the user's session is still active they should be regenerated for each possible action when rendered.
Links opening in new tabs isn't a security risk in itself, but if the server continually refreshes the token for each possible action, the links in the original window would now contain expired tokens as they have not been refreshed which is why the system is probably discouraging you from doing this and having a single path throughout the system instead which can be tracked.
In my examples above I mention everything being passed via POST, but it is also possible to implement similar using GET and separate page handler URLs. The POST route is slightly more secure as pages will be automatically expired in the browser via the mechanism that stops re-submission of forms, although it is also possible to implement this by via other means. The use unique tokens is the important point.