Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

PROTECTION CONTRE LE XSS ET L'SQL INJECTION


Information sur la source



Description

Voici un petit code sans grande prétention. Il se charge de traiter les données envoyées par formulaire dans les tableaux $_GET et $_POST pour éviter le XSS et l'SQL Injection.
 

Source

  • <?php
  • function secureArray (&$item)
  • {
  • if (is_array($item)) array_walk ($item, 'secureArray');
  • else
  • {
  • $item = htmlspecialchars($item);
  • $item = mysql_real_escape_string($item);
  • }
  • }
  • secureArray($_POST);
  • secureArray($_GET);
  • ?>
<?php
function secureArray (&$item)
{
   if (is_array($item)) array_walk ($item, 'secureArray');
   else
   {
      $item = htmlspecialchars($item);
      $item = mysql_real_escape_string($item);
   }
}
secureArray($_POST);
secureArray($_GET);
?>

Commentaires et avis

signaler à un administrateur
Commentaire de FhX le 29/01/2007 22:37:04

Ajout :
mysql_real_escape_string() ne marche que si une connection mysql est active.

signaler à un administrateur
Commentaire de psykocrash le 29/01/2007 22:38:48

Si y'a SQL Injection, c'est qu'il y a connexion à base de donnée... Ca me semblait logique, mais merci de le faire remarquer :)

signaler à un administrateur
Commentaire de FhX le 29/01/2007 23:29:45

Ce ue je voulait dire, c'est que la connection à la bdd doit être active AVANT d'utiliser mysql_real_escape_string() et non pas après :)

signaler à un administrateur
Commentaire de psykocrash le 29/01/2007 23:34:03

Oui j'avais bien compris ;)

signaler à un administrateur
Commentaire de malalam le 30/01/2007 08:13:36 administrateur CS

Hello,

ce n'est pas contre les SQL injections, mais contre les MYSQL injections, ça.
Sinon, ça aurait plus sa place sur codyx.org qu'ici, mais bon...

signaler à un administrateur
Commentaire de iomega le 30/01/2007 08:58:03

Bonjour à vous tous,
pourriez-vous m'expliquer ce que signifie une connexion à la bdd doit être active ? et aussi pourriez-vous expliquer un peu votre code ? merci beaucoup je suis novice et j'aime bien comprendre

signaler à un administrateur
Commentaire de webdeb le 30/01/2007 10:24:23

Logiquement, on ne fait pas de htmlspecialchars() avant envoi en BDD mais en sortie.

signaler à un administrateur
Commentaire de boakim le 30/01/2007 10:59:15

Je me pose la même question qu'IOMEGA.  Une petite explication permettrait d'éviter que le code et les commentaires ne soient destinés qu'aux spécialistes...

signaler à un administrateur
Commentaire de kankrelune le 30/01/2007 11:25:46

Bah la connection doit être déjà existante sinon l'utilisation de mysql_real_escape_string() plantera et génèrera un beau warning... .. .

Sinon le code est, à mon sens, inutile car il traite tout le tableau ce qui n'est pas nécessaire vu que généralement on ne se sert que d'une ou deux valeur pour une requete sql ou pour un affichage... qui plus est en se qui concerne le mysql_real_escape_string() tu ne vérifie pas si magic_quotes est activé ou non... .. .

@ tchaOo°

signaler à un administrateur
Commentaire de FhX le 30/01/2007 12:24:26

En faite, il faut sécuriser les données AVANT l'envoi dans une base de donnée... et pas quand on le recoit dans POST.

Si on recoit dans POST ou GET, ca veut pas forcément dire qu'on va les mettres en BDD.

De plus, il aurait été judicieux d'utiliser mysql_real_escape_string() que pour du type chaine. Bah vi, y'a que sur ca que ca fonctionne cette fonction.

:)

signaler à un administrateur
Commentaire de webdeb le 30/01/2007 13:55:30

Tu fais un mysql_real_escape_string() sur tes valeurs avant l'envoi en BDD et c'est tout. Pour te protéger des failles XSS, tu fais le htmlspecialchars() lorsque tu affiches les données dans tes pages.

signaler à un administrateur
Commentaire de iomega le 30/01/2007 14:08:18

FhX a dit "En faite, il faut sécuriser les données AVANT l'envoi dans une base de donnée... et pas quand on le recoit dans POST."

Peux-tu nous donner des exemples ?
Merci beaucoup

signaler à un administrateur
Commentaire de kankrelune le 30/01/2007 14:45:55

Bah tout dépend de ce que tu insert... il n'y a d'ailleurs pas que les données à inserer qui sont à protéger... tout les données provenant de l'exterieur et entrant dans la composition d'une requetes sql doivent être vérifiées... prenons l'exemple d'un select avec clause where...

si tu utilise un int tu fais...

'SELECT ... .. . WHERE id='.(int)$id

si tu utilise une chaine de charactère il faut la passer dans mysql_real_escape_string()... mais attention au magic_quotes si elle sont activées

function escapeDatas($data)
{
    if(is_numeric($data))
        return $data;
    
    if (get_magic_quotes_gpc())
        $data = stripslashes($data);
  
     return mysql_real_escape_string($data);
}

'SELECT ... .. . WHERE nom=\''.escapeDatas($nom).'\''

Etc... fais une recherche sur le net tu trouvera bon nombre de doc traitant du sujet... .. .

@ tchaOo°

signaler à un administrateur
Commentaire de iomega le 30/01/2007 15:43:21

Et super merci beaucoup kankrelune..si d'autres personnes ont d'autres méthodes pour sécuriser leurs bd contre les injections mysql qu'ils n'hésitent pas à donner un exemple..

Merci

signaler à un administrateur
Commentaire de coucou747 le 30/01/2007 17:03:17

webdeb, ça dépend de ce que l'on fait... mais ici, ça le fait sur tout les champs, et ça c'est pas bon...

sinon, deux array_walk, ça aurait été plus rapide...

signaler à un administrateur
Commentaire de psykocrash le 30/01/2007 20:44:35

Apparemment ça intéresse du monde, donc je préfère vous prévenir : CETTE PROTECTION N'EST PAS SUFFISANTE !

C'est une protection "de base" à compléter. Pour le XSS, du code javascript sans apostrophes ni balises peut être passé et exécuté. Pour l'SQL Injection, les injections sans apostrophes (avec des calculs arithmétiques) peuvent passer aussi. Il faut compléter cette protection avec à coup de vérifications comme is_numeric pour l'sql injection par exemple...

Je le répète : Une protection générique n'est JAMAIS suffisante !

signaler à un administrateur
Commentaire de FhX le 30/01/2007 21:01:12

Vrai, sauf si tu utilises htmlentities() qui te converti tout.

Pour le reste, mysql_real_escape_string() fonctionne très bien, à condition de bien s'en servir ( genre sur des entiers ou des objets... moyen moyen ^^) !

signaler à un administrateur
Commentaire de webdeb le 31/01/2007 01:47:10

>> Vrai, sauf si tu utilises htmlentities() qui te converti tout.

En sortie, pas en entrée ! Normalement un htmlspecialchars() fait largement l'affaire.

signaler à un administrateur
Commentaire de iomega le 31/01/2007 08:19:58

Hello à vous tous, y-a-t'il quelqu'un qui peut ajouter un exemple complet(avec des commentaires !!) car apparement cela interesse beaucoup de monde.
Merci à vous tous

signaler à un administrateur
Commentaire de kankrelune le 31/01/2007 13:31:12

@ Iomega... fais des recherches sur le net tu trouvera ton bonheur... .. !

@ Psykocrash...

"Pour l'SQL Injection, les injections sans apostrophes (avec des calculs arithmétiques) peuvent passer aussi."

faux... si tu n'utilise pas les quotes dans ta requete c'est soit qu'elle est mal construite (et donc ça plantera) soit que tu utilise un int et dans ce cas un cast fera l'affaire et le pirate pourra passer ce qu'il veut en arguments ça changera rien... et si tu utilise les quote (pour une string donc) mysql_real_escape() string se chargera d'échapper les quotes et le pirate pourra passer ce qu'il veut (avec ou sans quote) ça sera considéré comme texte... example...

si je passe  jean peaul';DROP TABLE pwet#  dans  WHERE nom=\''.$nom.'\'' pour faire une injection avec mysql_real_escape_string ça donnera

WHERE nom='jean peaul\';DROP TABLE pwet#'

aucune chance que ça passe...

en fait la plus grosse erreur que font les codeur et qui peut créer des failles c'est de ne pas prendre en compte magic_quotes

@ tchaOo°

signaler à un administrateur
Commentaire de psykocrash le 31/01/2007 13:53:11

kankrelune :
"tu utilise un int et dans ce cas un cast fera l'affaire et le pirate pourra passer ce qu'il veut en arguments ça changera rien..."

Je ne sais pas ce que tu entends par "un cast", donc je donne quelques infos :
-> On peut ajouter à la protection générique un is_numeric() comme je l'ai dit plus haut.
-> Si on ne le fait pas, un pirate peut très bien faire ça :
1 or 1<2;#
Ce qui aura pour effet de valider la requête. Cette faille permet de faire énormément de choses dans utiliser d'apostrophe.

signaler à un administrateur
Commentaire de FhX le 31/01/2007 13:59:38

"1 or 1<2;#"

Non, soit c'est du type string... donc entre quote, soit c'est du type (int) et dans ce cas la le résultat de "1 or 1<2;#" ==> 1

Aucune chance que ca passe.

signaler à un administrateur
Commentaire de kankrelune le 31/01/2007 14:04:05

Un cast ou transtypage c'est une conversion de type... essaye...

$maVar = '1 or 1<2;#';
var_dump((int)$maVar);

Ton pirate il pourra passer ce qu'il veut en argument, il pourra croire au père noel ou avoir vu la vierge à poil les mains dans les poches ça n'y changera rien... .. . ;o)

@ tchaOo°

signaler à un administrateur
Commentaire de iomega le 31/01/2007 14:23:05

Re salut kankrelune je sais que je peux faire une recherche sur internet...je voulais simple qu'un de vous (les pros du php) le mettent à disposition sur ce thread
Merci A+

signaler à un administrateur
Commentaire de psykocrash le 31/01/2007 14:39:06

FhX:
Mais l'objectif c'est justement que ça passe !

IOMEGA: "le" ? De quoi tu parles ?

signaler à un administrateur
Commentaire de iomega le 31/01/2007 14:43:43

Salut FhX ,
Je voulais dire par cela "une recherche sur un tuto qui donnent des exemples sur sécurisé ces données..." et le partager à tout le monde vu que cela intéresse du monde..
Merci

signaler à un administrateur
Commentaire de kankrelune le 31/01/2007 15:06:59

@ Iomega... Des tutos il y en a déja un paquet sur ce site et sur le net en général... c'est pour ça que je te dis de faire une recherche car ça n'a pas vraiment sa place dans les commentaires de cette source... et si tu as des question en plus au sujet des tutos que tu aura lu n'hésite pas à poster dans le forum... .. . ;o)

@ psykocrash... FhX à mal formuler son commentaire je pense... ou plutot il l'a formulé de façon subtile le (int) voulant dire faire un cast... .. . ;o)

@ tchaOo°

signaler à un administrateur
Commentaire de malalam le 31/01/2007 15:09:58 administrateur CS

Psykocrash => FhX et Kankrelune t'explique que si tu fais du transtypage, ta variable chaîne '1 or 1<2;#' se tranformera, après transtypage en int, en : 1. L'entier 1. Donc, tu n'auras plus ta clause OR, ni rien, juste 1, ce qui n'est pas franchement dangereux.

signaler à un administrateur
Commentaire de iomega le 31/01/2007 15:10:48

Ok Ok Ok Kankrelune c'est une simple sugestion...mais sache que des débutants comme moi ne seront pas lesquelles des tutos est bien ou pas !! Par contre si tu as le lien d'un tuto vraiment peux-tu en faire partager ?
Merci beaucoup et bonne journée

signaler à un administrateur
Commentaire de kankrelune le 31/01/2007 15:25:04

Il n'y a pas de tutos parfait... déjà parce que la perfection n'est pas de ce monde et ensuite parce que les failles vont et viennent au grès des versions de php et/ou des script php... les 3/4 des connaissances que j'ai en la matière je me les suis faites sur le tas d'une part en grappillant des infos à gauche/à droite (un tutos est rarement complet et ne traite pas forcement de tous les sujets) et d'autre part en progressant en programmation (éviter des failles c'est avant tout comprendre comment elles fonctionnent c'est pas juste savoir qu'il ne faut pas faire ci ou ça)... .. .

un peu de lecture...

http://www.phpsecure.info/v2/zone/pArticle

(tout n'est pas à jour)

@ tchaOo°

signaler à un administrateur
Commentaire de iomega le 31/01/2007 17:23:39

Et merci beaucoup kankrelune !! je viens de visiter le site et il est très sympas.
J'ai une question concernant les dates faut-il aussi ajouter mysql_escape_real_string ? ou bien autres choses ?
Merci à vous tous

signaler à un administrateur
Commentaire de kankrelune le 01/02/2007 12:37:09

Ca dépend de sa provenance... si c'est une date soumise par l'internaute oui il faut sinon si le format est "normal" tu peux t'en passer... .. .

@ tchaOo°

signaler à un administrateur
Commentaire de caviar le 06/02/2007 16:37:08

merci pour le links ...ça vas me faire de la lecture ;)
++

signaler à un administrateur
Commentaire de Kdecherf le 07/02/2007 18:37:33

Le Magicquote de Apache/PHP suffit-il pour contrer les injections MySQL ?

signaler à un administrateur
Commentaire de coucou747 le 07/02/2007 18:49:10

prèsque... et le magicquote n'est pas d'apache/php mais de php tout seul...
une légende raconte qu'il reste quelques failles... mais je ne sais pas ou coté échapements...

une chose est sure : sans parler de quotes, on peut parfois passer un truc genre UNION SELECT log, pass FROM admin dans un champ numérique...

signaler à un administrateur
Commentaire de Kdecherf le 07/02/2007 19:23:27

Ok merci coucou747, je prends note

signaler à un administrateur
Commentaire de FhX le 07/02/2007 20:39:47

sauf si on transtype :)

Le transtypage annule tout effet de surprise au niveau des entiers ^^ (ou flottant, c'est pareil :))

signaler à un administrateur
Commentaire de kankrelune le 08/02/2007 13:13:16

Magic quotes est loin d'être suffisant et efficace et c'est d'ailleurs pour ça qu'il ne sera plus implémenté dans php6 (y en a qui vont faire la gueule) ça fout plus la merde qu'autre chose et donne une illusion de sécurité au développeur... .. .

@ tchaOo°

signaler à un administrateur
Commentaire de coucou747 le 08/02/2007 21:33:41

FHX, c'est une solution efficace... mais pas toujours utile, et parfois lente, et peu occasionner des pertes de précisions quand ça se passe sur des floats

signaler à un administrateur
Commentaire de kegi le 08/05/2007 12:41:33

Bonjour,
Je ne comprend pas quand certain disent qu'il faut effectuer les vérifications en sortie de bd, on ne bloque pas les injections dans ce cas il me semble...


$data = addslashes($data);

$trans = get_html_translation_table(HTML_ENTITIES);
$data = strtr(trim($data), $trans);

$data = mysql_escape_real_string($data);



Je vous demande: j'en met trop ? pas assez ? c'est infaillible ?
Je vous propose de modifier la vérification pour qu'elle couvre un maximum de type d'injection.

Cordialement,
Kevin

signaler à un administrateur
Commentaire de kankrelune le 08/05/2007 12:58:19

Ce n'est pas les vérifications qu'il faut faire en sortie de BDD mais la suppression/conversion des tags html... mysql n'étant pas sensible au php, html, javascript & Co ça ne sert à rien d'appliquer un htmlentities() à l'insertion... .. .

Pour ton code...

/* avant une requete */
if(get_magic_quotes_gpc())
    $data = stripslashes($data);

$data = mysql_escape_real_string($data);

// on effectue la requete... .. .

----------------------------------

/* après une requete */
// on effectue et on traite la requete... .. .

while(false !== ($data = mysql_fetch_assoc($result)))
{
    echo htmlentities($data['myField']).'<br />';
}

Voili voilou... .. .

@ tchaOo°

signaler à un administrateur
Commentaire de gfpl le 19/05/2007 18:22:10

je cherche une protection contre ca mais j ai rien trouver
index.php?>'><ScRiPt%20%0a%0d>alert(1687822802)%3B</ScRiPt>
une soluce je m arrache les cheveux

signaler à un administrateur
Commentaire de PuLP le 26/05/2007 00:37:16

Moi non plus je ne comprend pas trop cette histoire de htmlspecialchars uniquement pour un cas, que ce soit une insertion de donnée ou une extraction, dans les deux cas il y a un requete mysql, et c'est la requete qu'on sécurise.

D'ailleurs mysql_escape_real_string, ça protege de l'injection avec quotes avec des slash, la methode d'injection est la meme que ce soit INSERT ou SELECT ca change rien vu que le but c'est de faire un UNION, non?

autre chose KANKRE je comprend pas trop ton code avec get_magic_quotes_gpc(), tu verifie si il y a des slash, pour les enlever, et finaler les remettres, enfin les remettres uniquement aux char concerner par la fonction mysql_escape_real_string ok, mais ça sert à quoi ? si ya magic quotes tu fais rien tout simplement..
Ou alors c'est que magic quotes a une faille que mysql_escape_real_string n'a pas ?

signaler à un administrateur
Commentaire de kankrelune le 26/05/2007 11:02:36

@ GFPL => $maVar = strip_tags(urldecode($maVar));

@ Pulp... le htmlspecialchars(), htmlentities() ou strip_chars() est inutile pour une requête SQL en effet les base de données ne sont pas sensible au html, javascript, php, etc... au final tu ne fais que surcharger ta base de données en caractères supplémentaires... .. .

Concernant l'injection SQL... tout d'abord le but dépend du pirate et donc de ce qu'il veut faire... .. .

Pour ce qui est du traitement des données magic_quotes n'échappe que des caractères généraliste ça n'est ni suffisant ni portable selon la SGDB utilisée ce qui ne fait que donner une illusion de sécurité... c'est d'ailleurs pour ça qu'elle n'existera plus à partir de PhP6... cependant certain caractères non échappés par magic_quotes doivent l'être avec certaines SGDB... il faut donc au préalable virer l'échappement de magic_quotes pour ne pas échapper les caractères d'échappement (lol) ce qui reviendrait à ne rien échapper du tout... d'où le stripslashes()... .. .

Un autre avantage de cette façon de procéder est que mysql_real_escape_string() n'est pas une fonction généraliste comme addslashes() ou magic_quotes... étant spécialisé dans le traitement de données destinées à MySQL si cette dernière évolue tu est sur que tes données seront toujours traitées comme il se doit... .. . ;o)

@ tchaOo°

Ajouter un commentaire

Discussions en rapport avec ce code source dans le forum

Protection contre injections sql et xss [ par slaxswf ] Bonsoir tout le monde ;)Je voudrais savoir si ce code était valide à 100% contre toutes les injections sql et xss possible et connues à ce jour.Merci SQL Injection [ par thebigbang ] bonjour à tous,Je cherche des infos sur la méthode du SQL Injection.. Si vous vous y connaissez un peu, merci de m'aider, me renseigner ... me donner Contrer SQL Injection [ par cocom84 ] Bonjour,Je viens de me rendre compte que mon site est vuln&#233;rable &#224; SQL Injection.J'avais dans l'id&#233;e de ne pas autoriser les caract&#23 Requête SQL PHP-Access [ par fgiuliano ] Bonjour &#224; tout,J'ai un petit probl&#232;me. Je d&#233;bute dans la programmation en PHP et j'aimerai savoir pour commencer comment effectuer une sql avec différence [ par jackrichard ] bonjour a tous je viens du SGBD oracle et j'ai appris a faire des diff&#233;rence maintenant sur mysql je ne parviens pas a trouver la syntaxe corresp passer une ligne lors d'un formulaire PHP/SQL [ par jiojioforever ] j'ai un formulaire de type textarena&nbsp;et je mets le contenu dans un champ d'un tablemais pour remplir le formulaire j'ai besoin de passer des lign Administrer MySQL [ par chris81 ] bonjour, existe t'il une appli permettant de gerer MySQL, un peu come SQL manager pour le SQL server mercihttp://www.correzeweb.comhttp://www.localet requetes sql [ par billy67000 ] table1 categories cat_id&nbsp;&nbsp; cat_images&nbsp;&nbsp; parent_id 1&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; images1&nbsp;&nbsp; & probleme sql guillemet formulaire [ par yoh76 ] Bonjour je suis un neophite du php j'ai un probleme je voudari enlever tout guillemet ou apostrophe lors de la saisie dans la base de donn&#233;e voir Date d une table SQL francisé ... [ par Teclis01 ] Je cherche a francis&#233; l ordre d une date pour la faire aparaitre francis&#233; mais jy arrives pas pourtant c bien partit mais bon ... $arraydate


Nos sponsors

Sondage...

CalendriCode

Juillet 2009
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
2728293031  

Consulter la suite du CalendriCode

Comparez les prix Nouvelle version

Photothèque Nouveau !



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 0,359 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.