Php Token Anti CSRF

Résolu/Fermé
Patate - 22 nov. 2022 à 13:59
 Patate - 24 nov. 2022 à 13:56

Bonjour, me revoilà avec mes tokens anti CSRF je déploie ces tokens sur tous les formulaires de mon appli et là je rencontre l'erreur undefined index sur mes tokens.

Je m'explique : dans ma vue qui contient mon formulaire je génère un token et je met un champ caché dans le formulaire qui prend pour valeur le token.

<?php
ob_start();
$token = generer_token('mail_rs');   //Je génère mon token
?>

<form method="POST" enctype="multipart/form-data" action="<?= URL ?>rs/mailRsValid">
    <div class="row">
        <div class="form-group col-6 p-2">
            <label for="depot_de_plainte">Liste de diffusion</label>
            <select class="form-control" name="id">
                <?php
                for ($i = 0; $i < count($rs2); $i++) : ?>
                    <option value="<?php echo htmlentities($rs2[$i]->getId()); ?>"><?= htmlentities($rs2[$i]->getNom()); ?> </option>
                <?php endfor; ?>
            </select>
        </div>
        <div class="form-group col-6 p-2">
            <label for="travaux">Action en cours</label>
            <select class="form-control" name="actions">
                <?php
                for ($i = 0; $i < count($actions); $i++) : ?>
                    <option value="<?php echo htmlentities($actions[$i]->getDescriptionAction()); ?>"><?= htmlentities($actions[$i]->getDescriptionAction()); ?> </option>
                <?php endfor; ?>
            </select>
        </div>


        <div class="form-group col-6 p-2">
            <label for="formFile" class="form-label">Ajout de fichier(s)</label>
            <input class="form-control" name='fichier' id='fichier' type="file">
        </div>

        <div class="form-group col-6 p-2">
            <label for="tech" class="form-label">Tech</label>
            <select class="selectpicker " multiple aria-label="multiple select example" id="cmblmail" name="cmbl[]" data-size="8" data-width="100%" multiple data-live-search="true" data-actions-box="true" title="" data-style="btn-white border">
                <optgroup label="Normandie">
                    <?php for ($i = 0; $i < count($cmbl); $i++) {
                        if ($cmbl[$i]->getZone() == "Normandie") { ?>
                            <option value="<?= $cmbl[$i]->getNom() ?>"><?= $cmbl[$i]->getNom() ?></option>
                        <?php } ?>
                    <?php } ?>
                </optgroup>
                <optgroup label="Centre-Val de Loire">
                    <?php for ($i = 0; $i < count($cmbl); $i++) {
                        if ($cmbl[$i]->getZone() == "Centre-Val de Loire") { ?>
                            <option value="<?= $cmbl[$i]->getNom() ?>"><?= $cmbl[$i]->getNom() ?></option>
                        <?php        } ?>
                    <?php        } ?>
                </optgroup>
            </select>
        </div>
        <div class="form-group col-6 p-2">
            <label  class="form-label">Ajout derco ou ticket père</label>
            <input class="form-control" name='derco'  type="text">
        </div>
    </div>
    <input type="hidden" name="ville" value="<?= htmlentities($rs->getVille_id()); ?>">
    <input type="hidden" name="cable" value="<?= htmlentities($rs->getTypeDeCables()); ?>">
    <input type="hidden" name="type" value="<?= htmlentities($rs->getTypeAlerte()); ?>">
    <input type="hidden" name="datefin" value="<?= htmlentities($rs->getDateDeRetablissement()); ?>">
    <input type="hidden" name="date" value="<?= htmlentities($rs->getDatesHeuresAlarme()); ?>">
    <input type="hidden" name="pilote" value="<?= htmlentities($rs->getPilote()); ?>">
    <input type="hidden" name="nb_de_clients_impactes" value="<?= htmlentities($rs->getNbDeClientsImpactes()); ?>">


    <div class="form-group col-md-8">
        <br>
        <button type="submit" class="btn btn-primary bouton border-0" id="baseN2" data-mdb-ripple-color="dark" data-bs-toggle="modal" data-bs-target="#referencer">Envoyer</button>
    </div>
    <input type="hidden" name="token" id="token" value="<?php echo $token; ?>"/>    // Mon champ caché qui a pour valeur le token 
</form>
<?php
$content = ob_get_clean();
$titre = "Envoi de mail - " . htmlentities($rs->getTypeAlerte());
require "views/template.php";
?>

Dans une autre page php (RsManager.class.php) qui gère ici l'envoi d'un mail je met une condition pour vérifier que mon token est valide

public function mailRsBd($id, $ville, $cmbl, $fichier) {

if(verifier_token(600, 'http://localhost/portail/rs/mailrs/' . $id, 'mail_rs')) 
{
  //Requete sql qui permet de sélectionner un utilisateur 
  //Création du mail 
  //Envoi du mail 
}
else { // Pour afficher mes messages d'erreurs 

            var_dump($_SESSION['mail_rs']);
            echo '<br><br>';
            var_dump($_POST['token']);
            echo '<br><br>';
            var_dump($_SESSION['mail_rs_time']);
            echo '<br><br>';
            echo time();
            echo '<br><br>';
            var_dump($_SERVER['HTTP_REFERER']);
            echo '<br><br>';
            if(isset($_SESSION['mail_rs']) && isset($_SESSION['mail_rs_time']) && isset($_POST['token'])){
                if($_SESSION['mail_rs'] == $_POST['token']){
                    if($_SESSION['mail_rs_time'] >= (time() - 600)){
                        if($_SERVER['HTTP_REFERER'] == 'http://localhost/portail/rs/mail/59'){
                            echo 'token bien vérifié';
                        }
                        else{
                            echo 'problème avec http_referer != http://localhost/portail/rs/mail/59';
                        }
                    }
                    else{
                        echo 'problème avec le time';
                    }
                }
                else{
                    echo '$_SESSION["mail_rs_token"] != $_POST["token"]';
                }
            }
            else{
                echo 'mail_rs, mail_rs_time, token ne sont pas tous isset';
            }
 
        }
}

Les fonctions verfier_token et generer_token dans mon index.php

function generer_token($nom = '')
{
	
	$token = uniqid(rand(), true);
	$_SESSION[$nom.'_token'] = $token;
	$_SESSION[$nom.'_token_time'] = time();
	return $token;
}

function verifier_token($temps, $referer, $nom = '')
{

    if(isset($_SESSION[$nom.'_token']) && isset($_SESSION[$nom.'_token_time']) && isset($_POST['token'])){
        if($_SESSION[$nom.'_token'] == $_POST['token']){
            if($_SESSION[$nom.'_token_time'] >= (time() - $temps)){
                if($_SERVER['HTTP_REFERER'] == $referer){
                    return true;
                }
            }
        }       
    }
    else{
        return false;
    }    
}

Et les message d'erreurs :

Notice: Undefined index: mail_rs in C:\Applications\wamp64\www\portail\models\RsManager.class.php on line 893
NULL

string(31) "31792904637cc5e35b3ca3.88068889"


Notice: Undefined index: mail_rs_time in C:\Applications\wamp64\www\portail\models\RsManager.class.php on line 897
NULL

1669121518

string(43) "http://localhost/portail/rs/mailrs/59"

mailRs_token, mailRs_token_time, token ne sont pas tous isset

Comment avoir accès à mon token générer dans ma vue ?

3 réponses

jordane45 Messages postés 38350 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 26 décembre 2024 4 719
22 nov. 2022 à 20:02

Bonjour,

Dans ton fichier RsManager.class.php, à la ligne , fais donc des var_dump de $_POST et de $_SESSION ... et regarde ce que ça t'affiche...


0

Merci de ton retour, 

var_dump($_POST)

array(12) { ["id"]=> string(2) "31" ["actions"]=> string(13) "AUCUNE ACTION" ["cmbl"]=> array(1) { [0]=> string(16) "Guy" } ["derco"]=> string(5) "DERCO" ["ville"]=> string(28) "Le Desert - - 14 - Calvados" ["cable"]=> string(6) "électrique" ["type"]=> string(7) "Dommage" ["datefin"]=> string(10) "2022-11-23" ["date"]=> string(10) "2022-11-22" ["pilote"]=> string(13) "Guy" ["client_impacte"]=> string(3) "100" ["token"]=> string(33) "2030131701637dcb9aba3957.86973164" }

var_dump($_SESSION)

array(7) { ["connexion_token"]=> string(33) "2128277159637dca42944d97.16366661" ["connexion_token_time"]=> int(1669188162) ["profil"]=> array(7) { ["login"]=> string(8) "AAAA2727" ["bd"]=> string(1) "1" ["dist"]=> string(1) "1" ["admin"]=> string(1) "1" ["demande"]=> string(1) "1" ["pilote"]=> string(1) "1" ["rs"]=> string(1) "1" } ["create_rs_token"]=> string(33) "2125239567637dcb963a2949.53656776" ["create_rs_token_time"]=> int(1669188502) ["mail_rs_token"]=> string(33) "2030131701637dcb9aba3957.86973164" ["mail_rs_token_time"]=> int(1669188506) } 

On peut voir que j'ai bien mes deux token de mail pourtant : 

 ["mail_rs_token"]=> string(32) "700426528637dce26774477.88740088" ["mail_rs_token_time"]=> int(1669189158) 
0
jordane45 Messages postés 38350 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 26 décembre 2024 4 719 > Patate
23 nov. 2022 à 12:02

Et maintenant, regarde la ligne correspondant à tes messages d'erreur .... (compare le nom des variables avec ceux que tu as en session... )

0
Patate > jordane45 Messages postés 38350 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 26 décembre 2024
23 nov. 2022 à 14:19

Si tu fais allusion à 

["mail_rs_token"]

comparé à  

if(verifier_token(600, 'http://localhost/portail/rs/mailrs/' . $id, 'mail_rs')) 

C'est normal sur tous mes autres token c'est pareil et ça fonctionne, si tu regarde ces deux fonctions : 

function generer_token($nom = '')
{
	
	$token = uniqid(rand(), true);
	$_SESSION[$nom.'_token'] = $token;
	$_SESSION[$nom.'_token_time'] = time();
	return $token;
}

function verifier_token($temps, $referer, $nom = '')
{

    if(isset($_SESSION[$nom.'_token']) && isset($_SESSION[$nom.'_token_time']) && isset($_POST['token'])){
        if($_SESSION[$nom.'_token'] == $_POST['token']){
            if($_SESSION[$nom.'_token_time'] >= (time() - $temps)){
                if($_SERVER['HTTP_REFERER'] == $referer){
                    return true;
                }
            }
        }       
    }
    else{
        return false;
    }    
}

J'ai quand même essayé ça pour être sur mais ça ne fonctionne pas : 

if(verifier_token(600, 'http://localhost/portail/rs/mailrs/' . $id, 'mail_rs_token')) 
0
jordane45 Messages postés 38350 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 26 décembre 2024 4 719 > Patate
23 nov. 2022 à 14:50

Il faut bien garder mail_rs dans l'appel de ta fonction

¨Par contre, je parlais des messages d'erreurs liés à tes var_dump .. pas du fonctionnement de ta fonction.

Pour ta fonction, ajoutes y des else et du debug pour comprendre ce qui n'est pas bon.

par exemple

function verifier_token($temps, $referer, $nom = 'mail_rs')
{
  $s_token = !empty($_SESSION[$nom.'_token']) ? $_SESSION[$nom.'_token'] : NULL;
  $s_token_time = !empty($_SESSION[$nom.'_token_time']) ? $_SESSION[$nom.'_token_time'] : NULL;
  $p_token = !empty($_POST['token']) ? $_POST['token'] : NULL;
  
  
    if( $s_token && $s_token_time && $p_token ){
        if($s_token == $p_token){
            if($s_token_time >= (time() - $temps)){
                if($_SERVER['HTTP_REFERER'] == $referer){
                    return true;
                }else{
                  echo "SERVER['HTTP_REFERER'] != referer ";
                  echo "<br>" . $_SERVER['HTTP_REFERER'] ;
                  echo "<br>" . $referer ;
                }
            }else{
              echo "<br>" . " s_token_time < temps " . $s_token_time . "-".$temps;  //le temps du debug
            }
        } else{
          echo "<br>" . "Variables session et post différentes! "; //le temps du debug
        }
    } else{
      echo "<br>" .  "Variables non renseignées ! "; //le temps du debug
    } 

     return false; // si aucune condition bonne
}
0
Patate > jordane45 Messages postés 38350 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 26 décembre 2024
Modifié le 23 nov. 2022 à 15:24

J'ai changé ma fonction par la tienne, 

Voici le résultat : 

SERVER['HTTP_REFERER'] != referer
http://localhost/portail/rs/mailrs/59
http://localhost/portail/rs/mailrs/31
Notice: Undefined index: mail_rs in C:\Applications\wamp64\www\portail\models\RsManager.class.php on line 893
NULL

string(33) "1386178879637e2a4432d304.93825408"


Notice: Undefined index: mail_rs_time in C:\Applications\wamp64\www\portail\models\RsManager.class.php on line 897
NULL

1669212749

string(43) "http://localhost/portail/rs/mailrs/59"

array(12) { ["id"]=> string(2) "31" ["actions"]=> string(13) "TOUJOURS RIEN" ["cmbl"]=> array(1) { [0]=> string(16) "Guy" } ["derco"]=> string(4) "TEST" ["ville"]=> string(28) "Le Desert - - 14 - Calvados" ["cable"]=> string(6) "electrique" ["type"]=> string(7) "Dommage" ["datefin"]=> string(10) "2022-11-23" ["date"]=> string(10) "2022-11-22" ["pilote"]=> string(15) "Guy" ["nb_de_clients_impactes"]=> string(3) "100" ["token"]=> string(33) "1386178879637e2a4432d304.93825408" }

array(17) { ["connexion_token"]=> string(33) "2128277159637dca42944d97.16366661" ["connexion_token_time"]=> int(1669188162) ["profil"]=> array(7) { ["login"]=> string(8) "AAAA2727" ["bd"]=> string(1) "1" ["dist"]=> string(1) "1" ["admin"]=> string(1) "1" ["demandevalidation"]=> string(1) "1" ["pilote"]=> string(1) "1" ["rs"]=> string(1) "1" } ["create_rs_token"]=> string(33) "2125239567637dcb963a2949.53656776" ["create_rs_token_time"]=> int(1669188502) ["mail_rs_token"]=> string(33) "1386178879637e2a4432d304.93825408" ["mail_rs_token_time"]=> int(1669212740) ["create_user_token"]=> string(33) "1554851162637dd12b178e18.04492781" ["create_user_token_time"]=> int(1669189931) ["update_user_token"]=> string(33) "1867447902637dd2134bd543.38206207" ["update_user_token_time"]=> int(1669190163) ["create_listemail_token"]=> string(33) "1237212366637decdccdab78.53906800" ["create_listemail_token_time"]=> int(1669197020) ["update_listemail_token"]=> string(33) "2135006987637dfcbac768a0.91016414" ["update_listemail_token_time"]=> int(1669201082) ["update_rs_token"]=> string(32) "720301184637dfd42e3d3a6.67284650" ["update_rs_token_time"]=> int(1669201218) }

mailRs_token, mailRs_token_time, token ne sont pas tous isset

J'comprend pas bien à ce moment là on dirait qu'il prend plusieurs mails 

SERVER['HTTP_REFERER'] != referer
http://localhost/portail/rs/mailrs/59  // 59 = id du rs 59 dans ma bdd
http://localhost/portail/rs/mailrs/31  // 31 = id du rs 31 dans ma bdd
0

Okay j'ai essayé de mettre l'id en statique dans mon if au lieux de 

'http://localhost/portail/rs/mailrs/' . $id

J'ai mis 

'http://localhost/portail/rs/mailrs/59' 

Et ça m'a bien envoyé mon mail de l'id 59 mais mtn j'aimerais mettre $id mais j'ai toujours ce 31 qui reviens et je ne sais pas du tout à quoi il correspond il y a aucun id 31 en plus dans ma table. 

0
jordane45 Messages postés 38350 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 26 décembre 2024 4 719
23 nov. 2022 à 16:39

Faudrait regarder ( et nous montrer ? ) comment tu fais appel à ta fonction 

mailRsBd
0
Patate > jordane45 Messages postés 38350 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 26 décembre 2024
Modifié le 24 nov. 2022 à 09:22

J'ai capté en fait pour remettre dans le contexte je choisis quelque chose qui a un id pcq c dans ma bdd que j'envois à une liste de diffusion qui a aussi un id et en fait au lieux de prendre l'id de mon truc que j'envois, celui qui est dans la barre d'url, il prend l'id de la liste de diffusion à laquelle j'envois le mail.

L'appel de ma fonction mailRsBd dans mon controller 

public function mailRsValidation()
    {

        $this->rsManager->mailRsBd(
            $_POST['id'],
            $_POST['clients_impactes'],
            $_POST['pilote'],
            $_POST['actions'],
            $_POST['der'],
            $_POST['date'],
            $_POST['type'],
            $_POST['cable'],
            $_POST['datefin'],
            $_POST['ville'],
            $_POST['bml'],
            $_FILES["fichier"]
        );
        //header('Location: ' . URL . "rs", "X-XSS-Protection: 1; mode=block");
    }


Du coup l'id que j'ai dans les paramètres de ma fonction mailRsBd est celui de la liste de diffusion et non pas de mon rs 

public function mailRsBd($id, $ville, $cmbl, $fichier) {}

A noter : je reprend du code qui n'est pas le miens donc je déchiffre peu à peu ce qui a été fait.

EDIT : Je viens d'afficher le $_POST['id'] qu'il y a dans le Controller pcq je pensais que lui prenais l'id de mon RS mais nan il prend aussi l'id de la liste de diffusion. WTF comment il sait quoi envoyer ??

0

Ok j'ai finis par réussir à corriger ça, merci pour l'aide :)

0