Given is a simple script to prevent multiple clicks on a submit button like in the following (reduced) example: After the first click the button cannot be clicked until the next form is loaded with a deliberate delay of 2 seconds.
<?php
sleep(2);
?>
<html>
<body>
<script type="text/javascript">
var done = false;
function once() {
if (done) {
return false;
}
done = true;
return true;
}
</script>
<form method="POST" onsubmit="return once();">
<input type="submit" value="ok">
</form>
</body>
</html>
This works fine but triggered a security audit. Content-Security-Policy will become mandatory, so all event handlers must be assigned by scripts using a nonce.
This works fine as well except for this locking script. The new version looks like that:
<?php
sleep(2);
header("Content-Security-Policy: script-src 'self' 'nonce-test'", true);
?>
<html>
<body>
<script type="text/javascript" nonce="test">
var done = false;
function once() {
if (done) {
return false;
}
done = true;
return true;
}
</script>
<form id="1" method="POST">
<input type="submit" value="ok">
</form>
<script type="text/javascript" nonce="test">
document.getElementById("1").addEventListener('submit', function(e) {
return once();
});
</script>
</body>
</html>
Basic functionality is there; the event handler is assigned, and with a breakpoint on done = true I can check that it is called when I click on the button. But each repeated click on the button creates a new request which is exactly what should not happen.
Why do these two scripts behave differently?