Kuidas vältida saidiüleste taotluste võltsimise (CSRF) rünnakuid PHP-s

See Selgitatud õpetab, kuidas vältida saidiülese päringu võltsimise (CSRF) rünnakut PHP veebirakenduses, lisades iga päringu juurde juhusliku märgi või kasutades iga vormivälja jaoks juhuslikku nime. Saididevahelise taotluse võltsimise (CSRF) rünnak kasutab veebirakenduse haavatavust, mille puhul ohver käivitab tahtmatult oma brauseris skripti, mis kasutab ära tema sisselogimise seanssi konkreetsele saidile. CSRF-i ründeid saab sooritada GET- või POST-päringute kaudu.

1
Mõistke kahte meetodit, mis aitavad vältida CSRF-i rünnakuid teie GET- ja POST-päringutele: juhusliku märgi lisamine igale päringule. See on kordumatu string, mis luuakse iga seansi jaoks. Loome märgi ja lisame selle seejärel peidetud sisestuseks igale kujule. Seejärel kontrollib süsteem, kas vorm on kehtiv, võrreldes märgi kasutaja seansimuutujas talletatuga. Ründaja ei saa taotlust genereerida ilma loa väärtust teadmata. Iga vormivälja jaoks juhusliku nime kasutamine. Iga välja juhusliku nime väärtus salvestatakse seansi muutujasse. Pärast vormi esitamist genereerib süsteem uue juhusliku väärtuse. Edu saavutamiseks peab ründaja need juhuslikud vorminimed ära arvama. Näiteks taotlus, mis kunagi nägi välja selline: näeb nüüd välja selline:

2
Looge csrf.class.php. See on fail, mis sisaldab kõiki funktsioone, mida kasutatakse CSRF-i rünnakute vältimiseks.juhuslik(10); $_SESSION[‘token_id’] = $token_id; tagasta $token_id; }}

5
Looge funktsioon get_token(). See funktsioon hangib loa väärtuse või kui seda pole genereeritud, genereerib token value.public function get_token() { if(isset($_SESSION[‘token_value’])) { return $_SESSION[‘token_value’]; } else { $token = hash(‘sha256’, $this->random(500)); $_SESSION[‘token_value’] = $märk; tagasta $märk; }}

6
Looge funktsioon check_valid(). See funktsioon määrab, kas loa ID ja märgi väärtus on mõlemad kehtivad. Selleks kontrollitakse GET- või POST-päringu väärtusi kasutaja SESSION-muutujasse salvestatud väärtustega.public function check_valid($method) { if($method == ‘post’ || $method == ‘get’) { $postitus = $_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; }}

7
Looge funktsioon form_names(). See funktsioon genereerib vormiväljadele juhuslikud nimed.public function form_names($names, $regenerate) { $values ​​= array(); foreach ($nimed kui $n) { if($regenerate == true) { unset($_SESSION[$n]); } $s = isset($_SESSION[$n]) ? $_SESSION[$n] : $see->juhuslik(10); $_SESSION[$n] = $s; $väärtused[$n] = $s; } tagasta $väärtused;}

8
Loo juhuslik funktsioon. See funktsioon genereerib Linuxi juhusliku faili abil juhusliku stringi, et luua rohkem entropy.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 (@ on_loetav(‘/dev/urandom’)) { $f=fopen(‘/dev/urandom’, ‘r’); $urandom=fread($f, $len); fclose($f); $tagasi = ”; } if (tühi($return)) { for ($i=0;$i<$len;++$i) { if (!isset($urandom)) { if ($i%2==0) { mt_srand(aeg()%2147 * 1000000 + (double)mikroaeg() * 1000000); } $rand=48+mt_rand()%64; } else { $rand=48+ord($urandom[$i])%64; } if ($rand>57) $rand+=7; kui ($rand>90) $rand+=6; kui ($rand==123) $rand=52; kui ($rand==124) $rand=53; $tagasi.=chr($rand); } } tagasta $tagasi;}

9
Sulgege klassi csrf sulg.}

10
Sulgege fail csrf.class.php.

11
Lisage CSRF-klassi fail POST-vormi. Siin pildil olev kood näitab, kuidas lisada CSRF-i klassi fail POST-vormile, et vältida CSRF-i rünnakut.get_token_id();$token_value = $csrf->get_token($token_id);// Genereeri juhuslikud vorminimed$form_names = $csrf->vormi_nimed(massiivi(‘kasutaja’, ‘password’), false);if(isset($_POST[$vormi_nimed[‘kasutaja’]], $_POST[$vormi_nimed[‘parool’]])) { // Kontrollige, kas loa ID ja loa väärtus on kehtivad. if($csrf->check_valid(‘post’)) { // Hangi vormimuutujad. $kasutaja = $_POST[$vormi_nimed[‘kasutaja’]]; $parool = $_POST[$vormi_nimed[‘parool’]]; // Vormi funktsioon läheb siia } // Vormi uue juhusliku väärtuse taasloomine. $form_names = $csrf->vormi_nimed(massiiv(‘kasutaja’, ‘parool’), true);}?>