Jeden żeton kontra wiele żetonów, aby zapobiec atakom CSRF

Używam Codeigniter i chcę zapobiec atakom CSRF, które mogą się zdarzyć. Aby to osiągnąć, dodam ukryty znacznik wejściowy z losowym tokenem do każdego formularza, który chcę chronić, a jednocześnie zachowuję ten token podczas sesji, z którą należy porównać, gdy zaczynam obchodzić się z danymi formularza.

  // set a token to prevent CSRF attacks
  $csrf_token = md5(uniqid(rand(), true));
  $this->session->set_userdata("csrf_token", $csrf_token);

A formularz będzie wyglądał następująco:

<form action="path/to/handler/page" method="post">
    <input type="text" name="title">
    <input type="text" name="date">
    <textarea name="content"></textarea>
    <input type="hidden" name="csrf_token" value="<?php echo $this->session->userdata("csrf_token") ?>"> 
    <input type="submit" name="submit" value="Save"> 
</form>

Na stronie, na której obsługuję przesyłane dane, sprawdzam CSRF atakuje coś takiego:

  // make sure there is no CSRF attack attempt
  $csrf_token = $this->session->userdata("csrf_token");
  if (empty($csrf_token) || $csrf_token !== $this->input->post("csrf_token")) {
    die("Some message here!!");
  }

I to działa całkiem dobrze. Ale jak widzisz, generuję losowy token dla każdej strony zawierającej formularz, aw niektórych przypadkach powoduje to problem, jeśli na przykład otworzyłem inną kartę w przeglądarce, aby wykonać inną akcję. Rozważmy następujący scenariusz:

otworzyłemadd.php strona, aby dodać nowy element.Wypełniłem wszystkie wymagane dane, ale nie przesłałem formularza.Teraz postanowiłem otworzyćedit.php strona na innej karcie w przeglądarce, aby edytować istniejący element.Potem wróciłem doadd.php strona, która została wypełniona i próbowała przesłać dane.

W tym momencie dostanę błąd, ponieważ wartość tokena, który został zapisany w sesji po otwarciuadd.php strona została zmieniona i zastąpiona innym tokenem, gdy otworzęedit.php strona. Jak mogę rozwiązać ten problem? Czy powinienem wygenerować po jednym żetonie dla każdego użytkownika, gdy uda mu się zalogować, a następnie użyć tego żetonu na wszystkich stronach, którymi może się zajmować? Czy to podejście ma jakiekolwiek ryzyko lub wady?

questionAnswers(2)

yourAnswerToTheQuestion