salut à tous!
pour des besoins de securisation des données transmises via les formulaires du site que je developpe ence moment, j'ai codé cette function qui fait bien ce qu'on lui demande de faire sauf que je trouve que le traitement des donnée est un peu long. alors si qqu'un peut mes suggerer une piste pour l'optimiser, je suis preneur. merci pour votre aide.

/**
* sécurise les données du formulaire avec la possibilité
* de les convertir en objet ainsi apres soumission du formulaire, on pourra l'utiliser coe ceci:
*
* if(!empty($_POST)) $this->data = sanitize($_POST); // ici $this->data est un tableau
* et les données sont de la forme: pour le champs 'nom', $this->data'nom']
*
* if(!empty($_POST)) $this->data = sanitize($_POST, true); // ici $this->data est un objet
* et les données sont de la forme: pour le champs 'nom', $this->data->nom
* 
**/
function sanitize($var, $toObject = false){
    $isJson = false;
    $banlist = '(execute|exec|sp_executesql|request|select|distinct|having|replace|handler|like|insert|union|declare|procedure|group by|drop|delete|create|alter|update|order|char|set|cast|convert|meta|script|truncate)';
    $eventHandlers = array('^a-z_\-]on\w*','style', 'xmlns');
    ob_start();
    if(is_array($var)){
        //converti au format json pour eviter les foreach
         $var = json_encode($var, JSON_HEX_APOS);
         $isJson = true;
        }
     # protege contre les injections SQL
    $var = preg_replace('#' . $banlist . '#i', '[removed]', $var);
    $var = str_replace(array('<?php', '<?PHP', '<?', '?'.'>'), array('<?php', '<?PHP', '<?', '?>'), $var);
    //supprime les images contenant du javascript
    $var = preg_replace('#<img.+?src=.*?(alert\(|alert&\#40;|javascript\:|window\.|document\.|\.cookie|<script|<xss).*?\>#si', '', $var);
    //protege contre les atacks js ou xss
    if (preg_match('/script/i', $var) OR preg_match('/xss/i', $var)) {      
                $var = preg_replace('#<(/*)(script|xss)(.*?)\>#si', '[removed]', $var);
            }
        $var = preg_replace("#<(^><]+?)(" . implode('|', $eventHandlers) . ")(\s*=\s*^><]*)(><]*)#i", "<\\1\\4", $var); 
        $var = preg_replace('#(alert|cmd|passthru|eval|exec|expression|system|fopen|fsockopen|file|file_get_contents|readfile|unlink)(\s*)\((.*?)\)#si', "\\1\\2(\\3)", $var);
        ob_end_clean();
        //debug($var); die();
        if($isJson) $var = json_decode($var, true);
if(!$toObject){
return Html_entities($var);
}
if(is_array($var))  return (object) array_map( __FUNCTION__ , Html_entities($var));
return (object) Html_entities($var);
}
/**
*
*
**/
function Html_entities($var){
if(!is_callable('filter_var')){
if(is_array($var)) return array_map('Html_entities', $var);
return  htmlentities(trim($var), ENT_QUOTES, 'UTF-8');
}
if(is_array($var)) return array_map('Html_entities', $var);
return  filter_var(trim($var), FILTER_SANITIZE_SPECIAL_CHARS);
}

6 réponses


Je suis loin d'être un expert en matière de sécurité, mais pourquoi le pas utiliser les filtres de validation ?
( http://php.net/manual/fr/book.filter.php ).

iriven
Auteur

salut HalfJo pour ton intervention, il ne s'agit pas ici d'une function de validation des donnée soumises , mais je dirais plutot d'une function de nettoyage de premier niveau des données qui transitent par votre site. elle se charge uniquement de neutraliser les données malvaillantes (attacks) qui pouraient eventuellement etre soumises indépendemment du type de donnée que vous aurez souhaité avoir pour chaque champs du formulaire. c'est donc juste comme un pare feu ou un antivirus. et apres vous aurez à valider vos champs comme d'habitude.
ainsi, on pourrait se proteger en inserant au debut de sa page index.php ce code:
if(!empty($_POST)) $DATA_POST = sanitize($_POST);
if(!empty($_GET)) $DATA_GET = sanitize($_GET);
if(!empty($_REQUEST)) $DATA_REQUEST = sanitize($_REQUEST);

et tout le long du site, utiliser plutôt les 3 variables $DATA_POST, $DATA_GET, $DATA_REQUEST au lieu de $_POST, $_GET, $_REQUEST

ha ok, je comprends mieux :).
Je testerai sa dans la semaine (et te donnerai mon retour). J'essayerai de voir si on peut faire mieux, mais c pas un sujet que je maitrise :|

Je viens de tester sur un de mes sites ( qui tourne avec laravel ), le framework semble fonctionner en partie avec ce genre de classe, si sa peux aider ;)

http://php.net/manual/fr/function.htmlspecialchars.php

iriven
Auteur

merci pour le lien mais je pense que c'est ce que fait cette function :

function Html_entities($var){
if(!is_callable('filter_var')){
if(is_array($var)) return array_map('Html_entities', $var);
return  htmlentities(trim($var), ENT_QUOTES, 'UTF-8');
}
if(is_array($var)) return array_map('Html_entities', $var);
return  filter_var(trim($var), FILTER_SANITIZE_SPECIAL_CHARS);
}

et qui est lancée à la sortiede la function "sanitize"

iriven
Auteur

salut pierre .
puisque tu as testé ce script peux tu me dire si le site rame un peu plus lors de la soumission d'un formulaire?
car normalement tant qu'on ne poste pas de données il n’y a aucun changement au niveau rapidité de chargement des pages. merci