PROTECTION CONTRE LE XSS ET L'SQL INJECTION

FhX Messages postés 2350 Date d'inscription mercredi 13 octobre 2004 Statut Membre Dernière intervention 18 avril 2015 - 29 janv. 2007 à 22:37
Buildos Messages postés 1 Date d'inscription mercredi 6 avril 2011 Statut Membre Dernière intervention 30 juin 2011 - 30 juin 2011 à 15:27
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/41312-protection-contre-le-xss-et-l-sql-injection

Buildos Messages postés 1 Date d'inscription mercredi 6 avril 2011 Statut Membre Dernière intervention 30 juin 2011
30 juin 2011 à 15:27
Je suis un des plus débutants dans le PHP , je voudrais savoir ou mettre ce code? est ce que en bas de toutes les pages que j'utilise ou ?
djshaker Messages postés 4 Date d'inscription jeudi 13 novembre 2003 Statut Membre Dernière intervention 3 juin 2010
3 juin 2010 à 12:27
Bonjour,

Concernant les injections SQL je vous recommande d'utiliser la classe PHP PDO,
qui avec les méthode prépare / bind_param / execute permet de se prémunir contre tous types d'injections SQL.

Bon dev ;)
kankrelune Messages postés 1293 Date d'inscription mardi 9 novembre 2004 Statut Membre Dernière intervention 21 mai 2015
26 mai 2007 à 11:02
@ 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°
cs_PuLP Messages postés 16 Date d'inscription dimanche 9 mars 2003 Statut Membre Dernière intervention 26 mai 2007
26 mai 2007 à 00:37
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 ?
gfpl Messages postés 172 Date d'inscription samedi 11 août 2012 Statut Membre Dernière intervention 9 avril 2011
19 mai 2007 à 18:22
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
kankrelune Messages postés 1293 Date d'inscription mardi 9 novembre 2004 Statut Membre Dernière intervention 21 mai 2015
8 mai 2007 à 12:58
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']).'
';
}

Voili voilou... .. .

@ tchaOo°
kegi Messages postés 164 Date d'inscription jeudi 23 octobre 2003 Statut Membre Dernière intervention 25 août 2008
8 mai 2007 à 12:41
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
coucou747 Messages postés 12303 Date d'inscription mardi 10 février 2004 Statut Membre Dernière intervention 30 juillet 2012 44
8 févr. 2007 à 21:33
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
kankrelune Messages postés 1293 Date d'inscription mardi 9 novembre 2004 Statut Membre Dernière intervention 21 mai 2015
8 févr. 2007 à 13:13
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°
FhX Messages postés 2350 Date d'inscription mercredi 13 octobre 2004 Statut Membre Dernière intervention 18 avril 2015 3
7 févr. 2007 à 20:39
sauf si on transtype :)

Le transtypage annule tout effet de surprise au niveau des entiers ^^ (ou flottant, c'est pareil :))
Kdecherf Messages postés 96 Date d'inscription mardi 9 janvier 2007 Statut Membre Dernière intervention 18 avril 2007
7 févr. 2007 à 19:23
Ok merci coucou747, je prends note
coucou747 Messages postés 12303 Date d'inscription mardi 10 février 2004 Statut Membre Dernière intervention 30 juillet 2012 44
7 févr. 2007 à 18:49
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...
Kdecherf Messages postés 96 Date d'inscription mardi 9 janvier 2007 Statut Membre Dernière intervention 18 avril 2007
7 févr. 2007 à 18:37
Le Magicquote de Apache/PHP suffit-il pour contrer les injections MySQL ?
cs_caviar Messages postés 329 Date d'inscription samedi 4 janvier 2003 Statut Membre Dernière intervention 29 mars 2015 2
6 févr. 2007 à 16:37
merci pour le links ...ça vas me faire de la lecture ;)
++
kankrelune Messages postés 1293 Date d'inscription mardi 9 novembre 2004 Statut Membre Dernière intervention 21 mai 2015
1 févr. 2007 à 12:37
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°
cs_iomega Messages postés 144 Date d'inscription jeudi 24 avril 2003 Statut Membre Dernière intervention 1 septembre 2008
31 janv. 2007 à 17:23
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
kankrelune Messages postés 1293 Date d'inscription mardi 9 novembre 2004 Statut Membre Dernière intervention 21 mai 2015
31 janv. 2007 à 15:25
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°
cs_iomega Messages postés 144 Date d'inscription jeudi 24 avril 2003 Statut Membre Dernière intervention 1 septembre 2008
31 janv. 2007 à 15:10
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
malalam Messages postés 10839 Date d'inscription lundi 24 février 2003 Statut Membre Dernière intervention 2 mars 2010 25
31 janv. 2007 à 15:09
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.
kankrelune Messages postés 1293 Date d'inscription mardi 9 novembre 2004 Statut Membre Dernière intervention 21 mai 2015
31 janv. 2007 à 15:06
@ 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°
cs_iomega Messages postés 144 Date d'inscription jeudi 24 avril 2003 Statut Membre Dernière intervention 1 septembre 2008
31 janv. 2007 à 14: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
psykocrash Messages postés 240 Date d'inscription vendredi 14 juin 2002 Statut Membre Dernière intervention 17 mars 2009
31 janv. 2007 à 14:39
FhX:
Mais l'objectif c'est justement que ça passe !

IOMEGA: "le" ? De quoi tu parles ?
cs_iomega Messages postés 144 Date d'inscription jeudi 24 avril 2003 Statut Membre Dernière intervention 1 septembre 2008
31 janv. 2007 à 14:23
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+
kankrelune Messages postés 1293 Date d'inscription mardi 9 novembre 2004 Statut Membre Dernière intervention 21 mai 2015
31 janv. 2007 à 14:04
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°
FhX Messages postés 2350 Date d'inscription mercredi 13 octobre 2004 Statut Membre Dernière intervention 18 avril 2015 3
31 janv. 2007 à 13:59
"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.
psykocrash Messages postés 240 Date d'inscription vendredi 14 juin 2002 Statut Membre Dernière intervention 17 mars 2009
31 janv. 2007 à 13:53
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.
kankrelune Messages postés 1293 Date d'inscription mardi 9 novembre 2004 Statut Membre Dernière intervention 21 mai 2015
31 janv. 2007 à 13:31
@ 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°
cs_iomega Messages postés 144 Date d'inscription jeudi 24 avril 2003 Statut Membre Dernière intervention 1 septembre 2008
31 janv. 2007 à 08:19
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
webdeb Messages postés 488 Date d'inscription samedi 5 avril 2003 Statut Membre Dernière intervention 31 mars 2009 4
31 janv. 2007 à 01:47
>> Vrai, sauf si tu utilises htmlentities() qui te converti tout.

En sortie, pas en entrée ! Normalement un htmlspecialchars() fait largement l'affaire.
FhX Messages postés 2350 Date d'inscription mercredi 13 octobre 2004 Statut Membre Dernière intervention 18 avril 2015 3
30 janv. 2007 à 21:01
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 ^^) !
psykocrash Messages postés 240 Date d'inscription vendredi 14 juin 2002 Statut Membre Dernière intervention 17 mars 2009
30 janv. 2007 à 20:44
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 !
coucou747 Messages postés 12303 Date d'inscription mardi 10 février 2004 Statut Membre Dernière intervention 30 juillet 2012 44
30 janv. 2007 à 17:03
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...
cs_iomega Messages postés 144 Date d'inscription jeudi 24 avril 2003 Statut Membre Dernière intervention 1 septembre 2008
30 janv. 2007 à 15:43
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
kankrelune Messages postés 1293 Date d'inscription mardi 9 novembre 2004 Statut Membre Dernière intervention 21 mai 2015
30 janv. 2007 à 14:45
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°
cs_iomega Messages postés 144 Date d'inscription jeudi 24 avril 2003 Statut Membre Dernière intervention 1 septembre 2008
30 janv. 2007 à 14:08
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
webdeb Messages postés 488 Date d'inscription samedi 5 avril 2003 Statut Membre Dernière intervention 31 mars 2009 4
30 janv. 2007 à 13:55
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.
FhX Messages postés 2350 Date d'inscription mercredi 13 octobre 2004 Statut Membre Dernière intervention 18 avril 2015 3
30 janv. 2007 à 12:24
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.

:)
kankrelune Messages postés 1293 Date d'inscription mardi 9 novembre 2004 Statut Membre Dernière intervention 21 mai 2015
30 janv. 2007 à 11:25
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°
cs_boakim Messages postés 8 Date d'inscription samedi 26 août 2006 Statut Membre Dernière intervention 14 juin 2010
30 janv. 2007 à 10:59
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...
webdeb Messages postés 488 Date d'inscription samedi 5 avril 2003 Statut Membre Dernière intervention 31 mars 2009 4
30 janv. 2007 à 10:24
Logiquement, on ne fait pas de htmlspecialchars() avant envoi en BDD mais en sortie.
cs_iomega Messages postés 144 Date d'inscription jeudi 24 avril 2003 Statut Membre Dernière intervention 1 septembre 2008
30 janv. 2007 à 08:58
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
malalam Messages postés 10839 Date d'inscription lundi 24 février 2003 Statut Membre Dernière intervention 2 mars 2010 25
30 janv. 2007 à 08:13
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...
psykocrash Messages postés 240 Date d'inscription vendredi 14 juin 2002 Statut Membre Dernière intervention 17 mars 2009
29 janv. 2007 à 23:34
Oui j'avais bien compris ;)
FhX Messages postés 2350 Date d'inscription mercredi 13 octobre 2004 Statut Membre Dernière intervention 18 avril 2015 3
29 janv. 2007 à 23:29
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 :)
psykocrash Messages postés 240 Date d'inscription vendredi 14 juin 2002 Statut Membre Dernière intervention 17 mars 2009
29 janv. 2007 à 22:38
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 :)
FhX Messages postés 2350 Date d'inscription mercredi 13 octobre 2004 Statut Membre Dernière intervention 18 avril 2015 3
29 janv. 2007 à 22:37
Ajout :
mysql_real_escape_string() ne marche que si une connection mysql est active.
Rejoignez-nous