Page 1 sur 1

eviter l'injection de code dans les formulaires.

Posté : 11 oct. 2007, 08:23
par stakanof
Je récupère des données dans un formulaire, que j'envoie dans la base MySQL,
puis ces données sont réaffichées dans une page html.

Je voudrais savoir quelles sont les fonctions à utiliser pour
éviter l'introduction de code ( sql et html ) dans les formulaires.

Re: eviter l'injection de code dans les formulaires.

Posté : 11 oct. 2007, 08:56
par Tracker
Je récupère des données dans un formulaire, que j'envoie dans la base MySQL,
puis ces données sont réaffichées dans une page html.

Je voudrais savoir quelles sont les fonctions à utiliser pour
éviter l'introduction de code ( sql et html ) dans les formulaires.
Alors coté sql (si tu utilises mysql)
Utilise systématiquement mysql_[real_]escape_string( $param ) si tu n'utilises pas PDO, sinon prépare les queries et utilises bindParam(...) pour inserer les valeurs.
Pour les autres bases cherche un équivalent de la fonction d'échappement

Coté production HTML:
htmlentities( $str, quote_style = ENT_COMPAT|ENT_QUOTES|ENT_NOQUOTES, charset )
Le quote_style dépend du context d'utilisation de la chaine produite, en général
- pour écrire du HTML brute, on utilise ENT_NOQUOTES
- pour écrire l'intérieur d'un attribut ex:value = "<?php echo htmlentities(...) ?>", on utilise ENT_COMPAT
ENT_COMPAT Convertit les guillemets doubles, et ignore les guillemets simples
ENT_QUOTES Convertit les guillemets doubles et les guillemets simples
ENT_NOQUOTES Ignore les guillemets doubles et les guillemets simples
Dernière chose, afin de stocker en base le contenu saisi par l'utilisateur sans déformation, il faut faire attention au paramétrage des magic_quotes (échappement automatique des quotes dans les tableaux $_GET, $_POST, $_COOKIE == GPC).
Tu peux donc utiliser ce type de code:
function getValue($arr, $key)
{
   ...
   if(get_magic_quotes_gpc()) return stripslashes($arr[$key]);
   else return $arr[$key];
}
...
$sql = "insert tablex values ('".mysql_escape_string(getValue($_POST, 'variable'))."')";
if(mysql_query($sql))
{
   ...
Au suivant :wink:

Posté : 11 oct. 2007, 10:28
par Ryle
En complément, si htmlentities() te permet de convertir les caractères html pour qu'ils ne soient pas interprétés mais seulement affichés par le navigateur, tu peux aussi utiliser strip_tags() pour supprimer toutes les balises html d'une chaine :)

Concernant l'injection, le principe est le même quel que soit la base de données : l'utilisateur malveillant va tenter de refermer une chaine sql pour que le reste de sa saisie soit interprétée par le parseur sql.
En gros, si par exemple dans ton code tu vérifies qu'un utilisateur est bien présent dans ta base :
$sql = "SELECT ... FROM ... WHERE login = '".$_POST['donnee_formulaire']."'";
Un utilisateur malveillant peut saisir dans le formulaire la chaine : " ' OR 1=1 ", ce qui aura pour effet de générer la requête suivante :

Code : Tout sélectionner

SELECT ... FROM ... WHERE login = '' OR 1=1
qui te retournera tous les enregistrement de la base (puisque même si le champ login n'est pas vide, la valeur 1 sera toujours égale à 1)

Pour te prémunir de l'injection, il te suffit donc de t'assurer que l'utilisateur ne puisse pas refermer tes chaines en protégeant tes variables. Sous MySQL il suffit d'un antislash pour qu'une apostrophe soit considérée comme un caractère et non comme une fin de chaine. C'est ce que fait mysql_real_escape_string() (ainsi que quelques autres bricoles). La requête deviendrait alors :

Code : Tout sélectionner

SELECT ... FROM ... WHERE login = '\' OR 1=1'
ce qui ne retournera pas de résultat :)