Як захиститися від атак з використанням межсайтовой підробки запиту (csrf) в php
Атака з використанням межсайтовой підробки запиту (CSRF) - це тип вразливості веб-додатки, коли жертва ненавмисно запускає скрипт в своєму браузері, який використовує поточну сесію авторизованого користувача в певному сайті. Атаки CSRF можуть проводитися через GET або POST запити. Дана стаття покаже вам, як захистити своє веб-додаток від атак CSRF.
метод
Ми будемо використовувати два методи для захисту від CSRF атак ваших GET і POST запитів.
Перший метод полягає в використанні випадкового ключа при кожному запиті, це унікальна рядок, що генерується для кожної сесії. Ми генеруємо ключ, а потім включаємо його в кожну форму у вигляді прихованого поля. Далі, система перевіряє валідність форми, порівнюючи ключ і значення, збережене в сесійному змінної користувача. Тобто, якщо зловмисник захоче згенерувати запит, він повинен буде знати значення ключа.
Другий метод - це використання випадкових назв для кожного поля форми. Значення випадкового імені для кожного поля зберігається в сесійному змінної і після того, як форма відправлена (стався сабміт), система генерує нові випадкові назви полів. Тобто, якщо зловмисник захоче провести атаку, йому потрібно буде знати ці випадкові назви полів форми.
Наприклад, запит, який раніше виглядав ось так:
Буде виглядати ось так:
кроки
Це основний файл, який буде містити всі методи, необхідні для запобігання атак CSRF.
Ця функція отримує 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-}}
Ця функція отримує значення токена, якщо ж значення ще не було згенеровано, то воно генерується.
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-}}
Ця функція перевіряє на валідність 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-}}
Це другий захист проти атак 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-}
Ця функція генерує випадкову рядок, використовуючи випадковий фал 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-}
Це завершить клас csrf.
}
Ці кроки покажуть вам, як використовувати клас CSRF для захисту від атак CSRF.
Наведений нижче код показує використання класу csrf для форми.