8791 sujets

Développement web côté serveur, CMS

Bonjour,
Mon problème est le suivant : Je veux éviter la faille XSS et la saisie de langage html dans un textarea pour un l'envoi de message sur un forum. La solution serait donc d'utiliser la fonction htmlspecialchar lors de l'affichage du message...

Seulement voilà, je gère également des smileys dans mon textarea, c'est a dire qu'une fonction en javascript traduit le clique sur un smiley par une chaîne de caractère bien spécial qui entre dans le message en cours (comme le fait également Alsacréation pour la rédaction d'un message). Lors de l'appel du message, la fonction str_replace cherche ses fameuses chaîne et si elle les trouvent, elles les remplace par :
<img src="images/[i]mon_smiley[/i].gif" alt="smiley" />


Je me retrouve donc avec un gros soucis car j'aimerais bien gérer les balises <img>, mais bloquer toutes les autres...

Une idée? je coince la Smiley sweatdrop
Salut, il doit y avoir plusieurs solutions mais le plus simple est peut-être de faire :


$text = "blablablabla";
$text = htmlspecialchars($text);

str_replace(toto, tata, $text);


Comme ça tu traites d'abord tes injections d'html et ensuite tu remplaces tes smileys ?

Mais je peux me planter, qqun pour valider ?
Intéressant, je n'y avais pas penser sur le coup, je tente pour voir si cela fonctionne, mais je doute que je puisse faire quelque chose une fois la fonction htmlspecialchar($text) aura fait effet. J'essai néanmoins. Merci du conseil.
Je viens de rejeter un oeil à la doc php (je n'en fais plus beaucoup en ce moment) :

a écrit :

Description
string htmlspecialchars ( string $string [, int $flags = ENT_COMPAT | ENT_HTML401 [, string $charset [, bool $double_encode = true ]]] )
Certains caractères ont des significations spéciales en HTML, et doivent être remplacés par des entités HTML pour être affichés. htmlspecialchars() remplace tous ces caractères par leur équivalent dans la chaîne string. Cette conversion est très pratique pour la programmation web. Si vous devez remplacer tous les caractères, utilisez plutôt htmlentities() à la place.

htmlspecialchars() est pratique pour éviter que des données fournies par les utilisateurs contiennent des balises HTML, comme pour un forum ou un chat.

Les remplacements effectués sont :

"&" (et commercial) devient "&amp;"
""" (guillemets doubles) devient "&quot;" lorsque ENT_NOQUOTES n'est pas utilisée.
"'" (guillemet simple) devient &#039; uniquement lorsque ENT_QUOTES est utilisée.
"<" (inférieur à) devient "&lt;"
">" (supérieur à) devient "&gt;"



si tes smileys avant transformation contiennent 1 de ces caractères ça ne fonctionnera évidemment pas !
Modifié par PanPan50 (26 Jan 2012 - 14:06)
Oui, c'est bien ça le problème, raison pour laquelle je pense contourner le soucis en ne me servant pas de la fonction htmlspecialchars() mais en créant moi même une condition qui bloque tous les caractères '<' et '>' sauf si il sont rencontrer comme ceci : '<img src="" alt="" />'. Je poste dès que j'ai trouvé la solution.
Généralement pour la gestion des smiley on places des raccourcis type ": )" qui sont enregistrés en BDD et passent donc la validation htmlspecialchars(). On remplace par la suite ces raccourcis par le code HTML à l'affichage.
Modifié par moust (26 Jan 2012 - 14:22)
J'ai une solution à mon problème, je la poste en me disant que peut être un jour cela donnera des idées à quelqu'un :
$text =  preg_replace("!<!" , ":", $text);

Cette ligne remplace tous les '<' par des ':', on obtient par exemple :
<table> devient :table>
mais surtout :
<img devient :img
Puis j'applique :
$text =  preg_replace("!:img!" , "<img", $text);

Cette ligne me remplace les :img à nouveau par des <img se qui me conviens! Smiley biggrin

Seulement je pense qu'il a bien mieux que ma bricole actuelle... Smiley ohwell si quelqu'un a mieux je prend.
salut...

La réponse de Moust est la solution ...

On retourve des smileys sous différentes formes :

[:)] [ Smiley smile ] Smiley smile Smiley smile voici 4 des façons les plus courantes pour un bête sourire...les deux premières étant plutôt BBcode

cela se stocke en bdd sans aucun problèmes.. c'est seulement à l'affichage que l'on remplace par une img... pas avant de stocker !! Donc il n'y a normalement aucun problème...
Simple bétise de ma part, c'est bien ce que je faisais....mais a l'envers... Smiley sweatdrop
D'abord le preg_match, puis le htmlspecialchars. Merci de vos réponses pclhj et Moust! Je suis bien bête!
La solution que tu évoques en remplaçant les "<" par des ":" se rapporte à l'usage du BBCode que l'on retrouve sur les forum par exemple.
Il me semble qu'une solution plus "propre" (et plus simple) consiste à utiliser la fonction strip_tags() en autorisant uniquement les balises <img>, comme ceci :
$text=strip_tags($text,'<img>');
Très mauvaise idée car tu laisse ainsi passer les attaque XSS classiques qui consistent à insérer un lien frauduleux dans l'attribut src d'une image.

Exemple :
<img src="http://domaine.tld/scriptpirate.php" />

Ce bout de code passera la validation et sera afficher sur la page du visiteur dont le navigateur fera une requête vers l'url indiquée et exécutant le script frauduleux au passage.
Au passage, il est parfaitement possible d'avoir une url en .gif qui soit frauduleuse ... Il y a actuellement des petits malins qui font ça à grande échelle avec des .gif via les balises des phpbb. Image transparente (donc sans regarder la source, dure de le déceler).

D'où l'intérêt de s'inscrire à webmaster tools qui vous signale ça comme un malware (et bloque vos pages sur son moteur de recherche).

J'ai détecté un cas sur mes sites récemment, supprimé avant qu'ils commencent à faire des dégâts, et j'ai pu trouver ce bout de code sur énormément de forum phpBB. A savoir qu'un collègue a eu le coup également, sauf que lui, l'effet avait déjà commencé (dans son cas, affichage de pop-up en masse sur la page avec le gif transparent + bloquage par Google pour malware).

le code ressemblait à ça : [img=http://lklklk.info/g.gif] (lklklk = plein de NDD différent)
@moust, @kenor

Ma réponse se focalisait uniquement sur la question pratique posée à ce niveau de la discussion : la façon la plus simple d'éliminer toute balise sauf les images.
Et certes je vois bien que ça ne vaut rien, globalement, par rapport aux risques d'attaque.

Mais ce que je ne comprends pas, c'est que les solutions précédentes n'ont pas déclenché la même remarque, alors qu'elles reviennent strictement au même (après avoir remplacé "<" par ":", puis ":img" par <img", on n'a pas éliminé le risque non plus).

J'ai loupé quelque chose ?
Pour dire vrai, je repondais principalement à la remarque au dessus. Ceci afin de preciser que meme en n'autorisant que les extensions images, ont ete pas à l'abri d'une attaque.
Kikimagik a clairement indiqué dans son premier message qu'il souhaitais éviter les risques d'attaques XSS, d'où l'évocation du problème avec la méthode strip_tags(). Bien qu'il est vrai que le problème n'a pas été relevé pour la méthode de BBCode où c'est effectivement également le cas.

De manière générale il vaut mieux ne pas laisser la possibilité à l'utilisateur d'entrer lui même du HTML quelque en soit la forme. Comme le dis la bonne vielle doctrine "don't trust the user" Smiley smile