Implement CSRF token but without affecting navigation

Asked

Viewed 96 times

0

I’m developing a web application written in PHP7. In this application, I developed a module in which CSRF token automatically generates when the user "enters" any application page. This is the useful part of the code for the question:

if(!isset($_SESSION['csrftoken']) || $_SERVER['REQUEST_METHOD'] === 'GET')
{
    SessionController::CriarCSRFToken(); 
}


// Na classe SessionController...
public static function CriarCSRFToken()
{
    $_SESSION['csrftoken'] = bin2hex(random_bytes(32));
}

My intention is always to perform a token check on every POST type request. The useful code for the question is this:

if($_SERVER['REQUEST_METHOD'] === 'POST')
{
    SessionController::VerificarCSRFToken();
}

//Na classe SessionController...
public static function VerificarCSRFToken()
{
    if (!isset($_POST['csrftoken']) || !hash_equals($_SESSION['csrftoken'], $_POST['csrftoken']))
    {

        //Basicamente envia a mensagem e para a execução da requisição.
        JSONResponder::ResponderFalha("Você não tem permição para acessar essa funcionalidade", true, true);
    }
}

It is working well, however, this generates a usability problem for the application. Actions like using multiple browser tabs or just checking the page’s source code generates refresh in the session’s csrftoken. For example, I am in the tab 1 with the token "abc", but then I open a new tab aba2, the module updates the token to "Bcd". There is the problem. If I try to make a POST request in the tab 1, the module will "deny" the request. This happens because in the aba1 the token is still "abc" but when I opened the aba2 the token was "Bcd".

So how can I solve this problem? I hope I have made my question clear.

  • 1

    I’ve never worked with SESSION, then I would use COOKIES, but I don’t know if this could open a security breach in CSRF. I’m not going to put an answer on how to do it now because I’m running out of time to test if it would really work.

  • Add a input of the kind Hidden in the form, resolve this. Why have a hash for CSRF on "any page"?

  • Adding an Hidden type input is one of the things I’m doing. But if the user is in the tab1 the value of the input var be for example "abc", but if the user opens another tab aba2 in the browser, the module will update the value of the token to for example "Bcd". If the user then wants to perform a Submit in the form in the tab, this Hidden input form will be with the outdated value.

No answers

Browser other questions tagged

You are not signed in. Login or sign up in order to post.