Many AJAX requests immediately with CSRF protection

Welcome all.

My web application is based on asynchronous requests. The Timer widget works and updates its status every second AJAX (yes, it is necessary).

I send my CSRF tokens with every AJAX:

project_data.append(csrf_name_key,csrf_name_value);
project_data.append(csrf_value_key,csrf_value_value);

And in response, I update the global variables:

function setCSRF(response) {
    csrf_name_key = response.nameKey;
    csrf_name_value = response.name;
    csrf_value_key = response.valueKey;
    csrf_value_value = response.value;      
}

Everything is fine. But if I do another AJAX, for example, when I change the task in the todo list to "done", it sometimes fails because I send AJAX before I get new tokens from the previous request.

I really don't know how to solve this problem. The first idea was that I would make it “like a stack array” with 5 different tokens, but one https request = one pair of tokens, and I cannot create it.

, - ajax, - .

- - " 10 ":

if(e.target.response=="Failed CSRF check!") {
    if(failedAjax<10) checkForSurvey();
    failedAjax++;
    return;
}

, , .

Slim 3 CSRF. , , .

+4
2

:

  • csrf- javascript-

  • csrf, ( )

Slim-Csrf -middleware , , . api 5 csrf, api csrf-.

api .

$app->get('/foo', function ($request, $response, $args) {
    // check valid  csrf token

    $tokens = [];
    for ($i = 0; $i < 5; $i++) {
        $tokens[] = $this->csrf->generateToken();
    }

    return $response->withJson($tokens);
});

csrf- .

Guard::generateToken() - :

array (size=2)
  'csrf_name' => string 'csrf58e669ff70da0' (length=17)
  'csrf_value' => string '52ac7689d3c6ea5d01889d711018f058' (length=32)

csrf-

Slim-Csrf . Guard::setPersistentTokenMode(bool). :

$container['csrf'] = function ($c) {
    $guard = new \Slim\Csrf\Guard;
    $guard->setPersistentTokenMode(true);
    return $guard;
};

PhpDoc persistanceTokenMode -attribute

/**
 * Determines whether or not we should persist the token throughout the duration of the user session.
 *
 * For security, Slim-Csrf will *always* reset the token if there is a validation error.
 * @var bool True to use the same token throughout the session (unless there is a validation error),
 * false to get a new token with each request.
 */

ajax.

, , csrf.

, .

var requestQueue = [];
var isInRequest = false;

var csrfKey = ''; // should be set on page load, to have a valid token at the start
var csrfValue = '';

function newRequest(onSuccessCallback, data) { // add all parameters you need
    // add request to the queue
    requestQueue.push(function() {
        isInRequest = true;
        // add to csrf stuff to data
        $.ajax({
            data: xxx
            url: "serverscript.xxx",
            success: function(data) {
                // update csrfKey & csrfValue
                isInRequest = false;
                tryExecuteNextRequest(); // try execute next request
                onSuccessCallback(data); // proceed received data
            }
        }});
    );
    tryExecuteNextRequest();
}

function tryExecuteNextRequest() {
    if(!isInRequest && requestQueue.length != 0) { // currently no request running &
        var nextRequest = requestQueue.shift();
        nextRequest(); // execute next request
    }
}
+3

, CSRF, cookie .

localStorage .

CSRF .

0

Source: https://habr.com/ru/post/1674190/


All Articles