Как защититься от атак с использованием межсайтовой подделки запроса (CSRF) в php

Загрузить PDFЗагрузить PDF

Атака с использованием межсайтовой подделки запроса (CSRF) – это тип уязвимости веб-приложения, когда жертва непреднамеренно запускает скрипт в своем браузере, который использует текущую сессию авторизованного пользователя в определенном сайте. Атаки CSRF могут производиться через GET или POST запросы. Данная статья покажет вам, как защитить свое веб-приложение от атак CSRF.

Метод

Мы будем использовать два метода для защиты от CSRF атак ваших GET и POST запросов.

Первый метод заключается в использовании случайного ключа при каждом запросе, это уникальная строка, генерируемая для каждой сессии. Мы генерируем ключ, а затем включаем его в каждую форму в виде скрытого поля. Далее, система проверяет валидность формы, сравнивая ключ и значение, хранимое в сессионной переменной пользователя. То есть, если злоумышленник захочет сгенерировать запрос, он должен будет знать значение ключа.

Второй метод – это использование случайных названий для каждого поля формы. Значение случайного имени для каждого поля хранится в сессионной переменной и после того, как форма отправлена (произошел сабмит), система генерирует новые случайные названия полей. То есть, если злоумышленник захочет произвести атаку, ему нужно будет знать эти случайные названия полей формы.

К примеру, запрос, который раньше выглядел вот так:

How.com.vn Русский: Passwordscsrf.png

Будет выглядеть вот так:

How.com.vn Русский: Protectedrequestcsrf.png
Метод 1
Метод 1 из 2:

создание файла csrf.class.php

Загрузить PDF

Это основной файл, который будет содержать все методы, необходимые для предотвращения атак CSRF.

  1. How.com.vn Русский: Step 1 Создайте файл csrf.class.php.
    Начните, создав файл, и сохраните его со следующим содержимым:

    <?phpclass csrf {
    Весь код в этой секции руководства будет добавлен в конце этого файла.
  2. How.com.vn Русский: Step 2 Создайте метод get_token_id().

    Эта функция получает id ключа (токен) из сессионной переменной, если же он еще не был создан, то она генерирует случайный токен.

    public function get_token_id() {if(isset($_SESSION['token_id'])) { return $_SESSION['token_id'];} else {$token_id = $this->random(10);$_SESSION['token_id'] = $token_id;return $token_id;}}
  3. How.com.vn Русский: Step 3 Создайте метод get_token().

    Эта функция получает значение токена, если же значение еще не было сгенерировано, то оно генерируется.

    public function get_token() {if(isset($_SESSION['token_value'])) {return $_SESSION['token_value']; } else {$token = hash('sha256', $this->random(500));$_SESSION['token_value'] = $token;return $token;}}
  4. How.com.vn Русский: Step 4 Создайте метод check_valid().

    Эта функция проверяет на валидность id и значение токена. Проверка происходит путем сравнения значений, полученных при GET или POST запросах со значениями, хранимыми в сессионной переменной пользователя.

    public function check_valid($method) {if($method == 'post' || $method == 'get') {$post = $_POST;$get = $_GET;if(isset(${$method}[$this->get_token_id()]) && (${$method}[$this->get_token_id()] == $this->get_token())) {return true;} else {return false;}} else {return false;}}


  5. How.com.vn Русский: Step 5 Создайте метод form_names().

    Это вторая защита против атак CSRF, описанная в этой статье. Эта функция генерирует случайные имена для полей формы.

    public function form_names($names, $regenerate) {$values = array();foreach ($names as $n) {if($regenerate == true) {unset($_SESSION[$n]);}$s = isset($_SESSION[$n]) ? $_SESSION[$n] : $this->random(10);$_SESSION[$n] = $s;$values[$n] = $s;}return $values;}


  6. How.com.vn Русский: Step 6 Создайте метод random().

    Эта функция генерирует случайную строку, используя случайный фал linux для большей хаотичности значений.

    private function random($len) {        if (function_exists('openssl_random_pseudo_bytes')) {                $byteLen = intval(($len / 2) + 1);                $return = substr(bin2hex(openssl_random_pseudo_bytes($byteLen)), 0, $len);        } elseif (@is_readable('/dev/urandom')) {$f=fopen('/dev/urandom', 'r');$urandom=fread($f, $len);fclose($f);                $return = '';        }        if (empty($return)) {for ($i=0;$i<$len;++$i) {if (!isset($urandom)) {if ($i%2==0) {                                             mt_srand(time()%2147 * 1000000 + (double)microtime() * 1000000);                                }$rand=48+mt_rand()%64;} else {                                $rand=48+ord($urandom[$i])%64;                        }if ($rand>57)$rand+=7;if ($rand>90)$rand+=6;if ($rand==123) $rand=52;if ($rand==124) $rand=53;$return.=chr($rand);}}return $return;}


  7. How.com.vn Русский: Step 7 Закончите класс закрывающей скобкой.

    Это завершит класс csrf.

    }
    Теперь вы можете закрыть файл csrf.class.php, так как мы с ним закончили.
    Реклама
Метод 2
Метод 2 из 2:

защита страниц при помощи csrf.class.php

Загрузить PDF

Эти шаги покажут вам, как использовать класс CSRF для защиты от атак CSRF.

  1. How.com.vn Русский: Step 1 Защита POST формы.

    Приведенный ниже код показывает использование класса csrf для формы.

    <?phpsession_start();include 'csrf.class.php';$csrf = new csrf();// Генерация id и значения токена$token_id = $csrf->get_token_id();$token_value = $csrf->get_token($token_id);// Генерация случайных названий для полей формы$form_names = $csrf->form_names(array('user', 'password'), false);if(isset($_POST[$form_names['user']], $_POST[$form_names['password']])) {// Проверяем являются ли валидными id и значение токена.if($csrf->check_valid('post')) {// Получаем переменные формы.$user = $_POST[$form_names['user']];$password = $_POST[$form_names['password']];// Метод формы идет тут}// Генерируем новое случайное значение для формы.$form_names = $csrf->form_names(array('user', 'password'), true);}?><form action="index.php" method="post"><input type="hidden" name="<?= $token_id; ?>" value="<?= $token_value; ?>" /><input type="text" name="<?= $form_names['user']; ?>" /><br/><input type="text" name="<?= $form_names['password']; ?>" /><input type="submit" value="Login"/></form>


Об этой статье

How.com.vn работает по принципу вики, а это значит, что многие наши статьи написаны несколькими авторами. При создании этой статьи над ее редактированием и улучшением работали авторы-волонтеры. Количество просмотров этой статьи: 9516.
Эту страницу просматривали 9516 раз.

Была ли эта статья полезной?

⚠️ Disclaimer:

Content from Wiki How Русский language website. Text is available under the Creative Commons Attribution-Share Alike License; additional terms may apply.
Wiki How does not encourage the violation of any laws, and cannot be responsible for any violations of such laws, should you link to this domain, or use, reproduce, or republish the information contained herein.

Notices:
  • - A few of these subjects are frequently censored by educational, governmental, corporate, parental and other filtering schemes.
  • - Some articles may contain names, images, artworks or descriptions of events that some cultures restrict access to
  • - Please note: Wiki How does not give you opinion about the law, or advice about medical. If you need specific advice (for example, medical, legal, financial or risk management), please seek a professional who is licensed or knowledgeable in that area.
  • - Readers should not judge the importance of topics based on their coverage on Wiki How, nor think a topic is important just because it is the subject of a Wiki article.

Реклама