Проблема проверки токена при выполнении AJAX.CSRF (PHP) запрос - PullRequest
0 голосов
/ 01 октября 2018

Проблема заключается в проверке токена при выполнении запроса Ajax.Я не могу понять, где я допустил ошибку.

Список каталогов:/ajax/test.php/core/csrf.php/index.php

Файл csrf.php

<?php
class ag_csrf{
  public $last_token;
  public $tkn;
  private $ses_name;

  function __construct($ses_name = 'csrf_token')
  {
    $this->ses_name = $ses_name;
    if(isset($_SESSION[$this->ses_name])) $this->last_token = $_SESSION[$this->ses_name];
    $this->tkn = $this->gen_token();
  }

  public function gen_token(){
    $tkn = sha1('-defender'.openssl_random_pseudo_bytes(30).session_id());
    $_SESSION[$this->ses_name] = $tkn;
    return $tkn;
  }
  public function check_token($token=''){
    $c = ($token === $this->last_token) ? true : false;
    return $c;
  }
  public function get_token(){
    return $this->tkn;
  }
  public function meta($name = 'csrf-token'){
    return '<meta name="'.$name.'" content="'.$this->tkn.'" />';
  }
  public function form($name = 'hash'){
    return '<input type="hidden" name="'.$name.'" value="'.$this->tkn.'">';
  }
  //$csrf->get_token();
  //$csrf->check_token($_POST['hash'])
}
?>

Файл AJAX (test.php):

<?php
if ($_SERVER['REQUEST_METHOD'] == 'POST'){
  require_once($_SERVER["DOCUMENT_ROOT"].'/core/csrf.php');
    $csrf = new ag_csrf;

    $csrf_post = $_POST['csrf'];
    if($csrf->check_token($csrf_post)){
        //code

        echo json_encode(array("status" => "1", "text" => "kek good!", "post" => $_POST['csrf']));
    }else{
        echo json_encode(array("status" => "3", "text" => "csrf", "post" => $_POST['csrf']));
    }
}
?>

index.php

<?php
  ini_set('error_reporting', E_ALL);
  ini_set('display_errors', 1);
  ini_set('display_startup_errors', 1);

  session_start();

  require_once($_SERVER["DOCUMENT_ROOT"].'/core/csrf.php');
  $csrf = new ag_csrf;

  if(isset($_POST['go'])){
    if( $csrf->check_token($_POST['hash']) ){
      echo 'Ok';
    }else{
      echo 'CSRF Err';
    }
  }
?>

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <?=$csrf->meta();?>
</head>
<body>
  <form method="post">
    <input type="text" name="usr" value="" />
    <?=$csrf->form();?>
    <input type="submit" name="go" />
  </form>

  <hr />
  <p></p>
  <button type="button" class="uj">Ajax</button>

  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
  <script>
    var csrf = $('meta[name="csrf-token"]').attr('content');

    $('.uj').click(function(){
      $.ajax({
        url: "/ajax/test.php",
        type: "POST",
        data: ({csrf:csrf}),
        dataType: "html",
        beforeSend: function(request){
          $('p').html("Обновление данных...");
        },
        success: function(data){
          console.log(data);
          data = JSON.parse(data);

          if(data['status'] == "3"){
            $('p').html(data['text']);
          }else{
            $('p').html(data['text']);
          }
        }
      });
    });
  </script>
</body>
</html>

Проверкаформ переходит на ура, а вот при выполнении Ajax токены запроса не сходятся.Где прокол?

Я думаю, что из-за повторной загрузки файла csrf.php в test.php генерируются новые токены, и этот запрос не проходит проверку.Что можно сделать?

...