Bonjour,
J'ai suivi un tuto traitant des expressions régulières qui apprend à réaliser son propre BBCode. Il faut dire que mon objectif est surtout de stocker en BDD du texte html contenant quelques balises de base (<strong>, <em>, <br />, <span>, <div>, <p>, etc.) sans guerre plus, sans définition de styles ou autres. Stocker du html très basique sous forme de BBCode, pour éviter les problèmes de sécurité (faille XSS).
Mon intention est alors de remplacer simplement les chevrons < et > par les crochets [ et ], de stocker le texte avec les crochets en BDD après lui avoir appliqué htmlspecialchars par exemple. Je transforme ensuite les crochets en chevrons, juste avant l'affichage. Cela neutralise ainsi une éventuelle injection de code avec des chevrons, mais en préservant mon texte formaté avec les crochets.
Concrètement, je fais simplement par exemple pour le texte à mettre en BDD :
$texte = str_replace("<", "[", $texte);
$texte = str_replace(">", "]", $texte);
et l'inverse à la restitution du texte pour l'afficher.
Mais je me suis vite rendu compte que cela ne résolvait pas vraiment le problème de sécurité lié à l'injection de code javascript par exemple. En effet, si le pirate a eu l'idée d'injecter son code avec les crochets à la place des chevrons, l'attaque marche...
Voici par exemple ce que le tuto préconise, avec la fonction preg_replace, pour mettre une portion de texte en gras :
$texte = preg_replace("#\[b\](.+)\[/b\]#isU", "<strong>$1</strong>", $texte);
Mais je voudrais faire plus simple que cela, mais un peu plus compliqué que mon idée originale, toujours avec la fonction str_replace.
Je veux écrire tout mon texte à mettre en BBD en remplaçant une balise du genre <machin> en balise [ machin ], et celle de fermeture </machin> simplement par [ / machin ]. Et à la restitution du texte, je fais l'opération inverse (j'espace exprès les caractères, car je me suis rendu compte que le BBCode du présent forum marche avec certains des mots-clefs que j'emploie, ce qui cause un problème d'affichage...).
Cela donnerait donc par exemple :
$texte = str_replace("[ strong ]", "<strong>", $texte);
$texte = str_replace("[ / strong ]", "</strong>", $texte);
deux lignes au lieu d'une comme précédemment. Mais l'avantage est que je conserve exactement mes habitudes et réflexes html, puisque je ne fais que remplacer les chevrons par les crochets et vice-versa pour l'opération inverse.
J'ai beau examiner la nouvelle solution, je ne vois pas comment il peut subsister un risque d'attaque XSS. Mais d'un autre côté, je me dis que si les "pro" et ce tuto délaissent cette solution simple pour le genre de solution mentionné, c'est qu'il doit y avoir une bonne raison qui m'échappe, et qui rendrait peu recommandable la deuxième solution.
Si oui, alors quelles raisons ? Merci de votre éclairage.
Modifié par somdina (26 Jan 2011 - 00:48)
J'ai suivi un tuto traitant des expressions régulières qui apprend à réaliser son propre BBCode. Il faut dire que mon objectif est surtout de stocker en BDD du texte html contenant quelques balises de base (<strong>, <em>, <br />, <span>, <div>, <p>, etc.) sans guerre plus, sans définition de styles ou autres. Stocker du html très basique sous forme de BBCode, pour éviter les problèmes de sécurité (faille XSS).
Mon intention est alors de remplacer simplement les chevrons < et > par les crochets [ et ], de stocker le texte avec les crochets en BDD après lui avoir appliqué htmlspecialchars par exemple. Je transforme ensuite les crochets en chevrons, juste avant l'affichage. Cela neutralise ainsi une éventuelle injection de code avec des chevrons, mais en préservant mon texte formaté avec les crochets.
Concrètement, je fais simplement par exemple pour le texte à mettre en BDD :
$texte = str_replace("<", "[", $texte);
$texte = str_replace(">", "]", $texte);
et l'inverse à la restitution du texte pour l'afficher.
Mais je me suis vite rendu compte que cela ne résolvait pas vraiment le problème de sécurité lié à l'injection de code javascript par exemple. En effet, si le pirate a eu l'idée d'injecter son code avec les crochets à la place des chevrons, l'attaque marche...

Voici par exemple ce que le tuto préconise, avec la fonction preg_replace, pour mettre une portion de texte en gras :
$texte = preg_replace("#\[b\](.+)\[/b\]#isU", "<strong>$1</strong>", $texte);
Mais je voudrais faire plus simple que cela, mais un peu plus compliqué que mon idée originale, toujours avec la fonction str_replace.
Je veux écrire tout mon texte à mettre en BBD en remplaçant une balise du genre <machin> en balise [ machin ], et celle de fermeture </machin> simplement par [ / machin ]. Et à la restitution du texte, je fais l'opération inverse (j'espace exprès les caractères, car je me suis rendu compte que le BBCode du présent forum marche avec certains des mots-clefs que j'emploie, ce qui cause un problème d'affichage...).
Cela donnerait donc par exemple :
$texte = str_replace("[ strong ]", "<strong>", $texte);
$texte = str_replace("[ / strong ]", "</strong>", $texte);
deux lignes au lieu d'une comme précédemment. Mais l'avantage est que je conserve exactement mes habitudes et réflexes html, puisque je ne fais que remplacer les chevrons par les crochets et vice-versa pour l'opération inverse.
J'ai beau examiner la nouvelle solution, je ne vois pas comment il peut subsister un risque d'attaque XSS. Mais d'un autre côté, je me dis que si les "pro" et ce tuto délaissent cette solution simple pour le genre de solution mentionné, c'est qu'il doit y avoir une bonne raison qui m'échappe, et qui rendrait peu recommandable la deuxième solution.
Si oui, alors quelles raisons ? Merci de votre éclairage.
Modifié par somdina (26 Jan 2011 - 00:48)