Eternelle problème avec htmlentities !

WRInaute passionné
Bonjour,

Je permet aux utilisateurs de poster des messages contenant du html.
L'interface est en utf-8 et tout s'enregistre correctement en bd (pas de caractères bizarre ou autre, juste le texte comme il est écrit).
Mon soucis est à la sortie...
Supposons $sortie = $contenue; .
Si je fais $sortie = htmlentities($contenue); ,sa m'encode toutes les balises html et ce n'est pas le but recherché. Je veux juste éviter l'exécution de script à la con du genre :
Code:
<script type='text/javascript'>
  window.location = 'http://www.exemple.com/'
  </script>
Ou c'est que j'ai merdé la ?
Merci
 
WRInaute accro
salut tryan,

c'est normal, htmlentities($contenue) va transformer tout ce qui est < et > en &lt; et &gt; donc toutes les balise html vont apparaître sous la forme de leur 'code source'.

dans ton cas, si tu veux laisser passer le HTML tu dois explicitement filtrer ce qui est indésirable genre <script ....
ou si tu as peut de balise HTML autorisées, tu peut aussi faire htmlentities($contenue); et ensuite réverser ce traitement pour rétablir ce qui est autorisé.

genre :

$contenue = eregi_replace("&lt;b&gt;","<b>",$contenue);
$contenue = eregi_replace("&lt;/b&gt;","</b>",$contenue); etc ...

Edit : il me semble qu'il est plus facile de rétablir ce qui est autorisé que de prévoir tous les coups tordus que tu risque de rencontrer.
 
WRInaute passionné
oki, oki, merci de vos réponses :D .
Je vais donc utiliser la forme:
$contenue = eregi_replace("&lt;b&gt;","<b>",$contenue);

Ce qui m'amène à une autre question.
Sachant que mysql n'interprète pas le code php enregistré en bd (donc théoriquement pas de soucis de ce côté la), quelles sont les autres coups tordus aux quelles je peux m'attendre ?

Merci bien
 
Nouveau WRInaute
Hello,

perso je vais passer par : html_entity_decode()
pour réafficher le html,

mais avant, bien sur tu fais un eregi_replace() pour virer tout type de "<script>" & autres variables dont tu ne voudrais pas entendre parler.

c'est ce qui a de plus sur, & plus rapide, surtout en terme de ressources pour les gros sites.

Chears
 
Nouveau WRInaute
Hello,

passe par ma solution,
comme ça tu es sur qu'en base de donnée il ne pourra jamais rien se passer.

Eventuellement uniquement au réaffichage pour l'utilisateur final.
 
WRInaute accro
tryan a dit:
Je vais donc utiliser la forme:
$contenue = eregi_replace("&lt;b&gt;","<b>",$contenue);
$sortie = htmlentities($contenue);
et ensuite :
$sortie = eregi_replace("&lt;b&gt;","<b>",$sortie);[/quote]
tryan a dit:
Ce qui m'amène à une autre question.
Sachant que mysql n'interprète pas le code php enregistré en bd (donc théoriquement pas de soucis de ce côté la), quelles sont les autres coups tordus aux quelles je peux m'attendre ?

a priori rien si tu ne rétablie que du code sans risque et que tu l'envoie au navigateur via un echo ou un print.
Il ne faudrais pas en revanche faire un include de ce contenu car la tu ouvrirai la porte au injections php.
 
WRInaute accro
hummm !!! après reflexion, pense aux injections SQL quand tu va enregistrer le message en base.
 
WRInaute passionné
Him a dit:
Hello,

perso je vais passer par : html_entity_decode()
pour réafficher le html,

mais avant, bien sur tu fais un eregi_replace() pour virer tout type de "<script>" & autres variables dont tu ne voudrais pas entendre parler.

En faisant sa, sa sous entend alors que tu utilise htmlentities() avant d'enregistrer en bd. Donc à la finale, l'action qui est faite si je ne me plante pas est:
htmlentities()->eregi_replace()->html_entity_decode() .
Autant faire juste un eregi_replace() , c'est plus rapide ...non ?
 
WRInaute passionné
zeb a dit:
$sortie = htmlentities($contenue);
et ensuite :
$sortie = eregi_replace("&lt;b&gt;","<b>",$sortie);

En gros sur ton code, faut que je me tape des eregi_replace pour toutes les balises html dans ce cas ..c'est bien sa ?

Je vais me renseigner sur ce qu'est exactement une injections SQL .
Merci
 
WRInaute discret
N'oubliez pas que si vous encodez tout et filtrez à l'affichage, vous allez devoir le faire à chaque fois.

Il vaut bien mieux filtrer dès le début ce qui est acceptable, transformer ou supprimer le reste. Ainsi à chaque affichage ultérieur, il n'y a plus besoin de faire de traitements compliqué. on se contente d'afficher ce qu'il y a dans la base.
 
WRInaute passionné
htmlspecialchars me convertit également des éléments qu'il ne faut pas.

Supposons un code php proposé comme tuto de la part d'un membre et utilisant une coloration syntaxique, htmlspecialchars fout la merde, mais merci quand même :)

Edit:
Si je fais
$contenue = eregi_replace("<script","&lt;script",$contenue); couplé à
mysql_real_escape_string pour éviter les injections ... j'ai bon là ?
 
WRInaute passionné
De mon coté je préfère de loin cette approche :
1) nettoyage du texte. S'il y a des choses qu'on ne souhaite pas, comme des tags JS ou autre on les dégage de suite. => strip_tags voir preg_replace
(les fonctions ereg* sont déconseillées depuis PHP 4.0 non ? et elles seront complètement supprimées de PHP 6)

2) insertion en base de données, à moins d'utiliser PDO ou autre système de "protection" des variables => mysql_real_escape_string

3) lors de l'affichage un simple htmlentities ou htmlspecialchars suffira.
Je ne fais jamais le htmlentities lors de l'insertion en base de données, souhaitant conserver la possibilité d'éditer et rechercher le contenu "normalement". Idem pour les traitements de type "bbcode" d'ailleurs.
 
Discussions similaires
Haut