Codec d'obfuscation de lien html (php5)

Contenu du snippet

Il est souvent dangereux d'envoyer en clair les paramètres d'appels d'une pages html car celà donne des indications à tout le monde sur comment ils sont formés et comment on peut les exploiter pour trouver des failles dans le script.

Les mettre en base64 n'empêche toujours pas d'en connaitre la nature, mais ça complique un peut les choses, et un hacker ou un pirate, c'est un flemmard : s'il n'y a pas grand chose à piquer, il préfèra aller ailleur où c'est moins sécurisé et/ou là où il y a plus a prendre ;)

(parceque se taper une page de lien à décoder puis à mettre en action et à recoder avant de les injecter dans le browser, ça demande du temps...)

Un niveau supérieur de sécurité est prévu : mélange des paramètres en base64 avec une chaine aléatoire et stockée dans la base de données en correspondance avec le numéro de session
(ex: table session(id_session:char(255),not null;chaine_cryptage:char(255)))

J'y reviendrais plus tard quand je serais devenu plus parano

Source / Exemple :


<?php

/*
///////////////////////////////////
// Copyright LE DREFF Nicolas 2009
// Libre d'utilisation à condition de conserver cette mention
// Merci
// http://www.phpcs.com/codes/CODEC-OBFUSCATION-LIEN-HTML_49615.aspx
/////////////////////////////////
// Classe 'codec' permettant de gérer des liens au format base64
// Exemple d'utilisation:
////////////////////////////////
// ex 1:
// custumization des paramètres; Vous pouvez y mettre ce que vous voulez
///////////////////////////////
<?php
        $anchor_html = new anchor_html();

        $anchor_html->anchor_web_page = 'upload_document.php';

        $anchor_html->anchor_parameters[] = array('anchor_parameter_name'=>'doc_type','anchor_parameter_value'=>DOC_IMAGE);
        $anchor_html->anchor_parameters[] = array('anchor_parameter_name'=>'to_do','anchor_parameter_value'=>'scale');
        $anchor_html->anchor_parameters[] = array('anchor_parameter_name'=>'img_landscape_max_width','anchor_parameter_value'=>800);
        $anchor_html->anchor_parameters[] = array('anchor_parameter_name'=>'img_portrait_max_height','anchor_parameter_value'=>800);
        $anchor_html->anchor_parameters[] = array('anchor_parameter_name'=>'thumbnails_div','anchor_parameter_value'=>'');
        $anchor_html->anchor_parameters[] = array('anchor_parameter_name'=>'id_image','anchor_parameter_value'=>'image_big');
        $anchor_html->anchor_parameters[] = array('anchor_parameter_name'=>'accepted_mimes','anchor_parameter_value'=>'jpg::gif::png');

        $anchor_64_base = $anchor_html->get_anchor_html();
        //echo $anchor_html->anchor_parameters_64_base;
        //echo base64_decode($anchor_html->anchor_parameters_64_base);
        //exit;
        $anchor_html->reset_anchor();
?>
  <iframe id="image_upload" width="600px" height="50px" src="<?php echo $anchor_64_base;?>" frameborder="0"></iframe>
//////////////////////////////////////
// ex 2:
// le lien provient d'une base de données et est donc 'figé'. !!!!!!DOIT DEJA ETRE ASSAINI AVEC rawurlencode()!!!!!!!
/////////////////////////////////////
        $menus_html_anchor_array = new anchor_html();
        $menus_html_anchor_array = explode('?',$this->menus_list[$this->index_menus_list]['menus_lien']);
        $anchor_html->anchor_fil_arianne = $_SERVER['REQUEST_URI'];
        $anchor_html->anchor_web_page = $menus_html_anchor_array[0];
        $anchor_html->anchor_parameters_html = $menus_html_anchor_array[1];
        $anchor_64_base = $anchor_html->get_menus_anchor_html();

        $this->user_menus_content .= '<p class="' . $this->menu_deep_array[($this->menus_deep*2)-1] . '" basic_class="' . $this->menu_deep_array[($this->menus_deep*2)-1] . '" href="' . $anchor_64_base . '" target="iframe_content" type="' . MENUS_DATA_TYPE_ANCHOR_LABEL . '" style="cursor:pointer" onmouseover="this.setAttribute(\'class\',\'' . $this->menu_deep_array[($this->menus_deep*2)-1] . '_over\')" onmouseout="this.setAttribute(\'class\',\'' . $this->menu_deep_array[($this->menus_deep*2)-1] . '\')" id="' . $id_link . '" >' . $label_to_display_root . $this->menus_list[$this->index_menus_list]['menus_label'] . '</p>' . "\n";

//////////////////////////////////////
// dans la page appellée il faut ajouter ceci pour avoir la liste des paramètres sous forme de variables globales (unserialized) du même nom
/////////////////////////////////////

<?php

        if(test_param($_GET['param'],TEST_ALPHA)){
                $anchor_html = new anchor_html();
                $anchor_html->anchor_parameters_64_base = $_GET['param'];
                $anchor_html->get_anchor_parameters();
                foreach($anchor_html->anchor_parameters as $anchor_parameters_index=>$anchor_parameters_value){
                        $name = $anchor_parameters_value['anchor_parameter_name'];
                        $value = $anchor_parameters_value['anchor_parameter_value'];
                        $$name = $value;
                }
        }
?>

  • /
class anchor_html { public $anchor_web_page; // la page vers où je veux faire pointer mon lien public $anchor_parameters; // un tableau d'élements 'ancre' => array(array('anchor_parameter_name'=>'doc_type','anchor_parameter_value'=>DOC_IMAGE),array(...)); public $anchor_parameters_html; // la chaine contenant les paramètres d'appels assainis avec rawurlencode et séparés par des '&' public $anchor_parameters_64_base; // la chaine contenant les paramètres d'appels au format base64 public $anchor_html; // l'ancre complète avec la page d'appel et les paramètres en base64 public $anchor_fil_arianne; // possibilité d'inserer une lien de retour en base64 function __construct() // no comments { $this->anchor_web_page = ''; $this->anchor_parameters = NULL; $this->anchor_parameters_html = ''; $this->anchor_html = ''; $this->anchor_fil_arianne = ''; $this->anchor_parameters_64_base = ''; } // cette fonction permet de nettoyer l'objet pour une deuxième utilisation function reset_anchor() { $this->__construct(); } // on assemble les morceaux pour avoir une url propre function build_anchor_parameters_html() { $this->anchor_parameters_html = ''; // juste pour le cas où... $head_char = ''; // le premier paramètre d'appel ne sera pas précédé du '&' if(!empty($this->anchor_parameters)) // des paramètres d'appels? { $nb_paramters = count($this->anchor_parameters); // oui? combien? for($boucle_parameters = 0;$boucle_parameters < $nb_paramters;$boucle_parameters++) // on boucle { $this->anchor_parameters_html .= $head_char . $this->anchor_parameters[$boucle_parameters]['anchor_parameter_name'] . '=' . rawurlencode($this->anchor_parameters[$boucle_parameters]['anchor_parameter_value']); //construction du paramètre assaini $head_char = '&'; // si paramètre suivant il y a, le '&' le précèdera... } } if(!empty($this->anchor_fil_arianne)) //url de retour? { $this->anchor_parameters_html .= $head_char . 'fil_arianne=' . base64_encode($this->anchor_fil_arianne); // on rajoute le tout au lien en cours } //echo '-à-' . $this->anchor_parameters_html . '-à-'; //exit(); return($this->anchor_parameters_html); // byebye } // demande d'assemblage de l'ancre finale function build_anchor_html() { $this->anchor_html = $this->anchor_web_page . '?param='; // début du lien $this->anchor_html .= $this->encode_anchor_parameters_64_base(); // ajout des paramètres en base64 return($this->anchor_html); } // demande d'assemblage de l'ancre finale pour les menus stocké en BDD qui ont donc une liste de paramètres déja assemblé function build_menus_anchor_html() { $this->anchor_html = $this->anchor_web_page . '?param='; // début du lien $this->anchor_html .= $this->encode_menus_anchor_parameters_64_base(); // ajout des paramètres en base64 return($this->anchor_html); } // demande d'encodage des paramètres function encode_anchor_parameters_64_base() { $this->anchor_parameters_64_base = base64_encode($this->build_anchor_parameters_html()); // assemblage et conversion des paramètres return($this->anchor_parameters_64_base); } // demande d'encodage des paramètres déjà assemblé function encode_menus_anchor_parameters_64_base() { $this->anchor_parameters_64_base = base64_encode($this->anchor_parameters_html); // conversion des paramètres return($this->anchor_parameters_64_base); } // demande de décodage des paramètres base64 function decode_anchor_64_base() { $this->anchor_parameters_html = base64_decode($this->anchor_parameters_64_base); // decodage de l'ancre return($this->anchor_parameters_html); } // demande de restitution des paramètres base64 en tableau function get_anchor_parameters() { $anchor_html_array = explode('&',$this->decode_anchor_64_base()); // on découpe les paramètres $this->anchor_parameters = NULL; // on vide le tableau pour éviter les surprises if(!empty($anchor_html_array)) // des paramètres? { $nb_paramters = count($anchor_html_array); // oui? combien? for($boucle_parameters = 0;$boucle_parameters < $nb_paramters;$boucle_parameters++) // on boucle { $anchor_parameter = explode('=',$anchor_html_array[$boucle_parameters]); // séparation des paramètres et de leur valeur $this->anchor_parameters[] = array('anchor_parameter_name'=>$anchor_parameter[0],'anchor_parameter_value'=>rawurldecode($anchor_parameter[1])); // remplissage du tableau } } return($this->anchor_parameters); } function get_anchor_html() { return($this->build_anchor_html()); // restitution de la variable $anchor_html } function get_menus_anchor_html() { return($this->build_menus_anchor_html()); // restitution de la variable $menus_anchor_html } } ?>

Conclusion :


Il est clair que c'est du basic mais ça marche plutôt pas mal.
Outre de ralentir le processus de hackage, ça présente l'avantage de permettre de former des url complexes avec autant de paramètres que l'on veux avec sans se prendre la tête à mettre du rawurlencode() partout.

Reste à faire:
-possibilité de passer des tableaux ou des objets (si, si, c'est possible comme ça)
-possibilité de choisir le mode soit obfuscation, soit cryptage, soit en clair

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.