Oh really? I'll check that sometime. But it *does not submit again on refresh*
I've just checked: you're wrong. I've just submitted two orders instead of one this way, both on litecoinglobal and on btct. It is easily reproducible:
You need to wait until it shows redirect page, and then hit F5 before redirect happens Browser asks whether you want to submit form again.
And it is trivial to reproduce multiple click on a button problem too.
While we are here, I'll explain how it
should be done:
1. There should be protection entirely on server side. You cannot rely on things which happen outside of your server. Doing a redirect DOES NOT solve the root problem. Blocking buttons with JS DOES NOT solve the problem.
2. Each form should get an extra field with unique ID generated on server. (If you feel like that you can make it server-signed, then it doubles as CSRF protection. But it isn't necessary. Any random ID is fine in this context.)
3. When server receives POST request it should check whether form with such ID was already submitted. If yes, cancel and show error. If no, add ID to database and perform the action. (If you use proper SQL database you can just rely on unique constraint: DB won't allow you to add ID more than once, so it is secure against all sorts of race conditions as long as SQL database is properly implemented.)
People who write web applications usually only consider how it works in ideal case when communication is instant and there is no way to get it aborted in process.
But they really should understand that client and server communicate with each other with use of a certain protocol. The fact that we have HTML and JS on one side and PHP on other side changes nothing, it is still a protocol.
And so if you have a protocol message which submits an order, you need to consider a scenario where such message gets sent twice. As there is non-instantaneous communication there is no way to make sure that client and server state are synchronized (Byzantine general problem is applicable here), so... see above.
Blocking buttons is only a cosmetic solution, you can't really rely on it...
It's a bit easier to understand this when application is AJAX because at least you see an "API", but still developers fail to understand that communication between client and server isn't perfect. ICBIT.se got a lot of flak because of a problem with client and server state not in sync.