# Handling CSRF protection

I'm currently working on an implementation of a CSRF protection. What is the best practice when we detect a CSRF? Is it better to 404 the page, 403 (forbidden), 200 (OK) with an error message, something else?

Bonus : here's my code. I'm not very proud of the preg_replace and ob_*. If you also have suggestions on how to do it better, I'll take that too.

• The addCSRF method is called just before sending the output of an HTML page.
• The checkCSRF method is called when the server receives a request.

<?php
// This method checks if the content contains a form and adds a csrf_token hidden field
{
$content = ob_get_contents(); if (strlen($content))
{
// Random csrf token
$randomtoken = base64_encode(openssl_random_pseudo_bytes(32)); // Add the hidden input to the content if needed$content = preg_replace('/(<([^>]*\s)?form(\s[^>]*)?>)/i', '\1<input type="hidden" name="csrf_token" value="'.$randomtoken.'" />',$content, -1, $count); // If at least one input has been added, add the csrf_token value in the$_SESSION and replace the content
if ($count) { Session::set('csrf_token',$randomtoken);
// Echo the new content
ob_end_clean();
ob_start();
echo $content; } } return; } // This method checks if a form has been submited and if the csrf token is given and valid public static function checkCSRF() { // No form submitted if (!isset($_POST))
return;
// CSRF detected
if (!isset($_POST['csrf_token']) ||$_POST['csrf_token'] != Session::get('csrf_token'))
{
// 404 ? 403 ? 200 + error message ?
}
Session::forget('csrf_token');
}