Ce wikiHow vous apprend comment empêcher une attaque de type Cross Site Request Forgery (CSRF) dans une application Web PHP en incluant un jeton aléatoire à chaque requête ou en utilisant un nom aléatoire pour chaque champ de formulaire. Une CSRF (Cross Site Request Forgery) L'attaque exploite une vulnérabilité d'application Web dans laquelle la victime exécute involontairement un script dans son navigateur qui tire parti de sa session connectée à un site particulier. Les attaques CSRF peuvent être effectuées sur des requêtes GET ou POST.
Première partie de cinq:
Vue d'ensemble des méthodes
Nous utiliserons deux méthodes pour empêcher les attaques CSRF sur vos requêtes GET et POST:
- 1 Y compris un jeton aléatoire à chaque demande. C'est une chaîne unique générée pour chaque session. Nous générons le jeton et l'incluons ensuite dans chaque forme comme une entrée cachée. Le système vérifie ensuite si le formulaire est valide en comparant le jeton avec celui stocké dans la variable de session de l'utilisateur. Un attaquant ne pourra pas générer de requête sans connaître la valeur du jeton.
- 2 Utiliser un nom aléatoire pour chaque champ de formulaire. La valeur du nom aléatoire pour chaque champ est stockée dans une variable de session. Une fois le formulaire soumis, le système génère une nouvelle valeur aléatoire. Pour réussir, un attaquant devrait deviner ces noms de formulaires aléatoires.
- Par exemple une demande qui ressemblait à ceci:
- Va maintenant ressembler à ceci:
- Par exemple une demande qui ressemblait à ceci:
Deuxième partie de cinq:
Création du fichier de classe CSRF
-
1 Créer csrf.class.php. C'est le fichier qui contiendra toutes les fonctions qui seront utilisées pour empêcher les attaques CSRF.
<? php classe csrf
- 2 Enregistrez le fichier.
- Tout le code des parties 2 et 3 sera ajouté à la fin de ce fichier.
Troisième partie de cinq:
Ajouter un jeton aléatoire
-
1 Créer le get_token_id () fonction. Cette fonction extrait l'identifiant du jeton de la session d'un utilisateur et, s'il n'en a pas déjà été créé, génère un jeton aléatoire.
Publique fonction get_token_id() si(isset($ _SESSION['token_id'])) revenir $ _SESSION['token_id']; autre $ token_id = $ ceci->au hasard(10); $ _SESSION['token_id'] = $ token_id; revenir $ token_id;
-
2 Créer le get_token () fonction. Cette fonction récupère la valeur du jeton ou, si elle n’a pas été générée, génère une valeur de jeton.
Publique fonction get_token() si(isset($ _SESSION['token_value'])) revenir $ _SESSION['token_value']; autre jeton $ = hacher('sha256', $ ceci->au hasard(500)); $ _SESSION['token_value'] = jeton $; revenir jeton $;
-
3 Créer le check_valid () fonction. Cette fonction détermine si l'ID de jeton et la valeur de jeton sont tous deux valides. Cela se fait en vérifiant les valeurs de la requête GET ou POST par rapport aux valeurs stockées dans la variable SESSION de l'utilisateur.
Publique fonction check_valid(méthode $) si(méthode $ == 'poster' || méthode $ == 'obtenir') $ post = $ _POST; $ obtenir = $ _GET; si(isset($méthode $[$ ceci->get_token_id()]) && ($méthode $[$ ceci->get_token_id()] == $ ceci->get_token())) revenir vrai; autre revenir faux; autre revenir faux;
Partie quatre de cinq:
Génération d'un nom aléatoire pour chaque champ de formulaire
-
1 Créer le form_names () fonction. Cette fonction génère des noms aléatoires pour les champs de formulaire.
Publique fonction noms_formulaires($ noms, $ régénérer) valeurs $ = tableau(); pour chaque ($ noms comme $ n) si($ régénérer == vrai) non défini($ _SESSION[$ n]); $ s = isset($ _SESSION[$ n]) ? $ _SESSION[$ n] : $ ceci->au hasard(10); $ _SESSION[$ n] = $ s; valeurs $[$ n] = $ s; revenir valeurs $;
-
2 Créer le au hasard fonction. Cette fonction génère une chaîne aléatoire en utilisant le fichier aléatoire Linux pour créer plus d'entropie.
privé fonction au hasard($ len) si (function_exists('openssl_random_pseudo_bytes')) $ byteLen = intval(($ len / 2) + 1); $ retour = substr(bin2hex(openssl_random_pseudo_bytes($ byteLen)), 0, $ len); sinon (@is_readable('/ dev / urandom')) $ f=fopen('/ dev / urandom', 'r'); $ urandom=fread($ f, $ len); fclose($ f); $ retour = "; si (vide($ retour)) pour ($ i=0;$ i<$ len;++$ i) si (!isset($ urandom)) si ($ i%2==0) mt_srand(temps()%2147 * 1000000 + (double)microtime() * 1000000); $ rand=48+mt_rand()%64; autre $ rand=48+ord($ urandom[$ i])%64; si ($ rand>57) $ rand+=7; si ($ rand>90) $ rand+=6; si ($ rand==123) $ rand=52; si ($ rand==124) $ rand=53; $ retour.=chr($ rand); revenir $ retour;
-
3 Ferme la classe csrf support.
- 4Fermer la csrf.class.php fichier.
Partie cinq de cinq:
Utilisation du fichier de classe CSRF
-
1 Ajoutez le fichier de classe CSRF à un formulaire POST. Le code illustré ici montre comment ajouter le fichier de classe CSRF à un formulaire POST afin d'empêcher une attaque CSRF.
<? php session_start(); comprendre 'csrf.class.php'; $ csrf = Nouveau csrf(); // Génère un identifiant de jeton et valide $ token_id = $ csrf->get_token_id(); $ token_value = $ csrf->get_token($ token_id); // Génère des noms de formulaire aléatoires $ form_names = $ Csrf->noms_formulaires(tableau('utilisateur', 'mot de passe'), faux); si(isset($ _POST[$ form_names['utilisateur']], $ _POST[$ form_names['mot de passe']])) // Vérifiez si l'identifiant du jeton et la valeur du jeton sont valides. si($ Csrf->check_valid('poster')) // Récupère les variables du formulaire. $ utilisateur = $ _POST[$ form_names['utilisateur']]; $ mot de passe = $ _POST[$ form_names['mot de passe']]; // La fonction de formulaire va ici // Régénère une nouvelle valeur aléatoire pour le formulaire. $ form_names = $ Csrf->noms_formulaires(tableau('utilisateur', 'mot de passe'), vrai); ?>
Facebook
Twitter
Google+