Topic: Lost updates
In (a bit) lieu of preventing CSRF attacks, I thought the same procedure might be used to prevent the "lost update" in PunBB. Well, the common "lost update" isn't really present, but what happens is that in the timespan between person A has read a thread, formulated a reply and clicked "Submit", the thread might have gotten anything from one to 100 new replies. I'm thinking that the CSRF token can be used in some way to prevent this by telling the user that the thread has had replies the user started formulating a response and thus present the user with those replies along with his or her respone.
I think this is a nice feature to have, because I see too many times on (not only PunBB-based) forums that people submit a reply someone else has already submitted, asks a question that has already been answered in the same thread or simply just screws up a "Let's create a story by replying to this thread with two words each" thread. I haven't completely wrapped my head around how the CSRF token can be utilized to fix this problem or exactly how the technical details are going to look like, but it shouldn't be too hard to fix nonetheless.
If we don't think about CSRF, a simple timestamp in a hidden field would do. The timestamp can be hashed and even employed as an ETag in the response, so User Agents and intermediaries (like proxy servers) more easilly can cache threads and such. Here's a simple and dumb implementation:
Request code:
<?php
function get_etag($thread_id) {
$latest_date = get_date_of_the_last_post_in_thread($thread_id);
return md5($latest_date);
}
?>
<input type="hidden" name="etag" value="<?php get_etag($thread_id = 1234) ?>" />
Response code:
<?php
if ($_GET['etag'] != get_etag($thread_id)) {
echo 'There has been replies in this thread since you started writing yours. Please read them and click submit again if your reply is still valid and relevant (or whatever).';
// display all replies or just the new ones
} else {
// save the reply in the database and redirect back to the thread like usual.
}
?>