Як захиститися від атак з використанням межсайтовой підробки запиту (csrf) в php

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

метод

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

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

Другий метод - це використання випадкових назв для кожного поля форми. Значення випадкового імені для кожного поля зберігається в сесійному змінної і після того, як форма відправлена (стався сабміт), система генерує нові випадкові назви полів. Тобто, якщо зловмисник захоче провести атаку, йому потрібно буде знати ці випадкові назви полів форми.

Наприклад, запит, який раніше виглядав ось так:

Зображення з назвою Passwordscsrf.jpg

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

Зображення з назвою Protectedrequestcsrf.jpg

кроки

Метод 1 з 2:
створення файлу csrf.class.php

Це основний файл, який буде містити всі методи, необхідні для запобігання атак CSRF.

  1. Зображення з назвою 2543022 1
1. Створіть файл csrf.class.php.Почніть, створивши файл, і збережіть його з наступним змістом:

Весь код в цій секції керівництва буде додано в кінці цього файлу.
  • Зображення з назвою 2543022 2
    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-}}
  • Зображення з назвою 2543022 3
    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-}}
  • Зображення з назвою 2543022 4
    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-}}
  • Зображення з назвою 2543022 5
    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-}
  • Зображення з назвою 2543022 6
    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-}
  • Зображення з назвою 2543022 7
    7. Закінчите клас закриває дужкою.
    Це завершить клас csrf.

    }
    Тепер ви можете закрити файл csrf.class.php, так як ми з ним закінчили.
  • Метод 2 з 2:
    захист сторінок за допомогою csrf.class.php

    Ці кроки покажуть вам, як використовувати клас CSRF для захисту від атак CSRF.

    Зображення з назвою 2543022 8
    1. Захист POST форми.
    Наведений нижче код показує використання класу csrf для форми.

    Cхоже