CSRF - защита от подобных атак

Рейтинг: 0Ответов: 1Опубликовано: 25.04.2015

читаю про CSFR, не совсем понятно, почему не работает этот код:

<? 
   session_start(); 
   $_SESSION["sid"] = md5(time() . rand(0, 10000)); 
 ?>
<!DOCTYPE html>
<html>

<head>
  <title>FORM</title>
</head>



<body>
  <div id="wrap">
    <form action="" method="POST">
      <input type="hidden" id="sid" name="sid" value="<?= $_SESSION["sid"]; ?>">
      <textarea cols="50" name="msg" rows="10"></textarea>
      <br>
      <input type="submit" name="sub" value="Send">
    </form>

  </div>
</body>
<script type="text/javascript">
</script>


<? 
   if(isset($_POST["sub"])) { 
         if(isset($_POST["sid"]) && $_POST["sid"]==$_SESSION["sid"]{ 
               $_SESSION["sid"]="" ; 
               echo "SUCCESS!"; 
         } else { 
               echo "ERROR!"; 
         } 
    } 
 ?>

</html>

выдает ERROR, понятно, что страница перезагружается.. но как тогда правильно сделать? название "sid" = "token". Не обращайте внимания

Ответы

▲ 1

Вы генерируете CSRF-токен (который ещё зачем-то sidом назвали) каждый раз заново. Разумеется, они никогда не будут равны.

Есть 2 пути решения проблемы:

  1. Устанавливать CSRF-токен после того, как весь контент сгенерирован, но перед отправкой. Не подход в Вашем случае, поскольку у Вас HTML код перемежается с php-вставками. Если бы Вы использовали, скажем, шаблонизатор, этот подход мог бы выглядеть так:

    session_start(); 
    $response = generate_body(); // тут происходит вся обработка
    
    // тут можно выставить какие-нибудь заголовки
    $_SESSION["sid"] = md5(time() . rand(0, 10000));
    echo $response
    
  2. Запоминать предыдущее значение токена и сравнивать с ним.

    $previous_token = $_SESSION["sid"]