Trieur Organisé de Solutions et de Ressources Informatiques

logo du site TOSRI

Développement › PHP

Article(s) du 3 juin 2011

Niveau : personne ayant des bases en informatique (terminologie, principe)

Sécuriser ses variables avec PHP

Readme

Cet article vous donne un moyen sûr de vous prémunir des injections SQL en PHP.

En informatique la sécurité est plus qu'un droit : c'est un devoir ; il est de la responsabilité du détenteur du site de mettre tout en oeuvre pour protéger les données de son site, dans le cas contraire il peut s'exposer à des poursuites pénales.

Les données envoyées par le client au serveur doivent être traitrées avec beaucoup de prudence car elles ne correspondent pas toujours à ce que vous voulez. Si aucun mécanisme de protection n'est mis en place une simple chaîne de caractères peut permettre de lire des données ou de les modifier.

Vous devez absoluement posséder une base de données active et un serveur PHP.

Fonction php avec MySQL

La fonction mysql_real_escape_string() requiert une connexion à une base de données MySQL pour récupérer le jeu de caractères autorisés.
<?php
    /**
     * Sécurisation des valeurs passées contre les injections SQL/JS et encodage des caractères spéciaux
     * /!\ Nécessite une connexion à la base pour récupérer le jeu de caractères
     * Entrée : la valeur à sécuriser et l'identifiant de connexion
     * Sortie : la valeur sécurisée ou false en cas d'échec de connexion ou de transformation
     */
    function safe($value, $connex){
        if ( !$connex )
            return false;
           
        if( is_string($value) )
            $value = mysql_real_escape_string(htmlspecialchars($value));
       
        if( is_array($value) )
            array_walk($value, create_function('&$n', '$n = mysql_real_escape_string(htmlspecialchars($n));') );

        return $value;
    }

Vous n'utilisez pas MySQL ?

La fonction mysql_real_escape_string() employée dans ce script est spécifique à MySQL. Voici les équivalences pour les gestionnaires de base de données les plus courants :
Gest. BDFonction à utiliser
MySQL mysql_real_escape_string()
Oracle Ne possède pas de fonction d'échapement : utilisez addslashes()
PostgreSQL pg_escape_string()
SQLite sqlite_escape_string()

Exemple d'utilisation

Lorsque vous devez utiliser des données issues d'un formulaire, vous pouvez appliquer la fonction safe() sur la variable $_POST (ou $_GET). Voici deux possibilités :
  • passer la variable en référence pour qu'elle soit modifiée : safe(&$_POST, $connex);
  • ou récupérer la contenu dans une nouvelle variable : $resultat = safe($_POST, $connex);

Remarques

  • Emploi : les données stockées dans les cookies peuvent êtres modifiés côté client, il peut être utile de contrôler leur contenu ; à contrario il est inutile d'utiliser safe() sur des variables affectées au niveau du serveur ;
  • Test : ce script a été testé mais il vous incombe de faire vos propres tests de vérification afin de vous assurer qu'il correspond bien à votre but ;
  • Évitez les redondances : si vous avez fait une vérification de la validité de l'identifiant de connexion avant de le passer en paramêtre alors vous pouvez supprimer les 3 premières lignes de safe().

Article(s) du 4 mai 2011

Niveau : personne ayant des bases en informatique (terminologie, principe)

variables PHP, fonction = récupération + initialisation


Bonjour,

Aujourd'hui une petite fonction de PHP toute simple auquel on ne pense pas forcément :
Lorsque l'on récupère des variables via les méthodes POST, GET, SESSION et autres il vaut mieux que vos variables existent ou vous risquez certaines erreurs. Pour vous assurer d'avoir des variables correctes le mieux est de tester leur existence et, au besoin, de les initialiser.
La fonction ici présente est courte, mais sert à faire les deux opérations en une seule fois.

<?php
function getVar($lib, $def="", $method="request"){
    $method = strtoupper($method);    // mise en majuscule de la méthode
    // on recherche la valeur exacte dans le tableau correspondant
    eval('$resu = isset($_'.$method.'[\''.$lib.'\']) ? $_'.$method.'[\''.$lib.'\'] : $def;');
    return $resu;    // et on revoit le résultat
}
?>


Juste pour info : eval sert à exécuter une chaine de caractères comme une ligne de code normale. Les deux lignes suivantes font la même chose :

<?php
    eval('$resu = isset($_GET[\'maVar\']) ? $_GET[\'maVar\'] : $def;');
    $resu = isset($_GET['maVar']) ? $_GET['maVar'] : $def;
?>


Utilistation :
Url utilisée = http://localhost/SCRIPTS/get_var.php?maVar1=123&maVar2=456

<?php
// recherche de maVar1 par GET, défaut : "789"
echo "recherche de maVar1 par GET : '" . getVar("maVar1", "789", "get") . "'<br />";

// recherche de maVar2 par REQUEST, défaut : "789"
echo "recherche de maVar2 par REQUEST : '" . getVar("maVar2", "789") . "'<br />";

// recherche de maVar3 par REQUEST (n'existe pas), défaut : 789
echo "recherche de maVar3 par REQUEST : '" . getVar("maVar3", "789") . "'<br />";

// recherche de maVar4 par REQUEST (n'existe pas), défaut : chaine vide
echo "recherche de maVar4 par REQUEST : '" . getVar("maVar4") . "'<br />";

// recherche de PHP_SELF par SERVER, défaut : chaine vide
echo "recherche de PHP_SELF par SERVER : '" . getVar("PHP_SELF", "", "server") . "'<br />";
?>


Résultat :

recherche de maVar1 par GET : '123'
recherche de maVar2 par REQUEST : '456'
recherche de maVar3 par REQUEST : '789'
recherche de maVar4 par REQUEST : ''
recherche de PHP_SELF par SERVER : '/SCRIPTS/get_var.php'


Sur de petits sites où il y a peu de variables elle peut être inutile, en revanche quand vous manipulez de grandes quantités de données je vous certifie que vous serez content de l'avoir.


Article(s) du 7 décembre 2010

Niveau : personne ayant des bases en informatique (terminologie, principe)

Fonction de debug pour PHP

Temps : compréhension de 20 lignes de codes
Domaine : php

Bonjour,

Lorsque vous codez en PHP, vous manipulez parfois des variables assez complexes comme des objets ou encore des résultats de validation de formulaires. Alors à un instant t vous ne savez plus ce que contient une ou plusieurs variables. Pour pallier à ce problème il existe des fonctions php qui permettent de visualiser le contenu des variables print_r() et var_dump(). Lors d'un projet sur lequel je travaillais avec un collègue de travail il a eu l'idée de cette fonction très simple :


function pre($objet)
{
    echo"<pre>";
    print_r($objet);
    echo"</pre>";
}


Grâce au formatage de la balise <pre> on obtient un résultat clair à l'écran. Après avoir travaillé encore et encore avec cette fonction je n'ai pas cessé de l'améliorer et j'ai obtenu le résultat suivant :

function pre($var, $nAff=false){
    ob_start();
    echo '<pre style="text-align: left; white-space: pre;">';
   
    switch(gettype($var)){
    case "array": case "object":
        print_r($var);
        break;
    default:
        var_dump($var);
    }
    echo '</pre>';
   
    $resu = ob_get_contents();
    ob_end_clean();
   
    if(!$nAff)
        echo $resu;
   
    return $resu;
}

Maintenant une petite explication serait utile non ?

L'entête :

function pre($var, $nAff=false){

Il s'agit d'une fonction curieux n'est-ce pas ? Son nom pre lui vient des balises dans lesquelles sont placés l'affichage pour avoir un bon formatage (saut de lignes, tabulations, ...) et parce qu'il est court et simple...
$var c'est la variable que l'on veux étudier, par définition on y met m'importe quoi.
$nAff ce paramètre a été ajouté pour une raison très précise. Par défaut ce booléen est à Faux, cela signifie : "ne bloque pas l'affichage des informations". Donc si on met Vrai en second paramètre rien ne s'affichera.
Quelle est l'utilité ? Vous êtes surchargé de texte à afficher, l'idée vous viens de stocker le résultat dans un fichier, vous n'affichez rien et vous récupérez le tout en chaine de caractères avec le retour de fonction.

ob_start();

C'est quoi ça ?
Pour info : ob_start().
Définition : "Enclenche la tamporisation de sortie".
Définition humaine : "Place tout affichage suivant cette fonction en mémoire tampon sans l'afficher".
En gros l'affichage des informations qui nous intéressent est placé en mémoire sans être affiché.

echo '<pre style="text-align: left; white-space: pre;">';

Ici on affiche donc la balise de pré-formatage du texte avec un alignement à gauche et au cas où on replace la commande de pré-formatage.

    switch(gettype($var)){
    case "array": case "object":
        print_r($var);
        break;
    default:
        var_dump($var);
    }

Le selon est assez facile à comprendre si on sait le lire : gettype()  retourne une chaine de caractères indiquant le type de la variable et dans le cas d'un tableau ou d'un objet on utilise print_r et dans tous les autres cas var_dump. Si on utilise print_r pour les tableaux et objets c'est parce que var_dump est moins lisible.

echo '</pre>';

On termine l'affichage du formatage du texte.

$resu = ob_get_contents();

Maintenant on place dans une chaine de caractères les affichage de la mémoire tampon. ob_get_contents()

ob_end_clean();

On stoppe le stockage des affichages dans la mémoire tampon et on vide la mémoire tampon. ob_end_clean()

    if(!$nAff)
        echo $resu;

On choisit d'afficher ou pas le résultat.

return $resu;

On retourne le résultat pour l'utiliser au besoin, comme pour l'écrire dans un fichier.

Voilà voilà cette fonction ne sert que pendant la réalisation de votre code, elle est vouée à en disparaître mais elle vous aidera lors de vos tests. Pour finir une petite démonstration :

l'url de ma page : http://localhost/site/pre.php?a=12593

Le code :

<?php

$var1 = array(1, "quatre" => "test", "plop");
$var2 = false;
$var3 = null;
$var4 = "youpi";
$var5 = $_GET;

pre($var1);
pre($var2);
pre($var3);
$texteVar4 =  pre($var4, true);
pre($var5);

echo $texteVar4;

// juste pour le fun :

echo $var1;
print_r($var1);
var_dump($var1);
?>

Et son résultat HTML :

Array
(
    [0] => 1
    [quatre] => test
    [1] => plop
)

bool(false)

NULL

Array
(
    [a] => 12593
)

string(5) "youpi"


ArrayArray ( [0] => 1 [quatre] => test [1] => plop ) array(3) { [0]=> int(1) ["quatre"]=> string(4) "test" [1]=> string(4) "plop" }

Si vous avez besoin de plus d'explications n'hésitez pas à laissez des commentaires.

page 2 de 2 -