57 votes

Strip_tags () est-il vulnérable aux attaques de scripts?

Est-il connu XSS ou autre attaque que fait passé une

$content = "some HTML code";
$content = strip_tags($content);

echo $content;

?

Le manuel a un avertissement:

Cette fonction ne modifie pas les attributs sur les balises qui vous permettent d'utiliser allowable_tags, y compris le style et le onmouseover attributs d'un utilisateur malicieux peut les abus lors de l'affichage de texte qui sera affiché pour les autres utilisateurs.

mais qui est liée à l'utilisation de l' allowable_tags paramètre uniquement.

Avec pas permis tags set, est - strip_tags() vulnérables à toute attaque?

Chris Shiflett semble dire que c'est sûr:

De Maturité Des Solutions

Lorsque cela est possible, de maturité, de solutions existantes, au lieu d'essayer de créer votre propre. Des fonctions comme strip_tags() et htmlentities() sont de bons choix.

est-ce correct? Veuillez, si possible, de citer les sources.

Je sais à propos de HTML purificateur, htmlspecialchars (), etc.- Je suis pas à la recherche de la meilleure méthode pour nettoyer le code HTML. Je veux juste savoir à propos de cette question spécifique. C'est une question théorique qui est venu jusqu' ici.

Référence: strip_tags() mise en œuvre dans le code source PHP

54voto

Lekensteyn Points 22873

Comme son nom l'indique, strip_tags devez supprimer toutes les balises HTML. La seule façon que nous avons la preuve qu'il est en analysant le code source. La prochaine analyse s'applique à un strip_tags('...') appel, sans un deuxième argument pour la liste blanche des balises.

Tout d'abord, un peu de théorie sur les balises HTML: une balise commence avec un < suivie par les caractères espace. Si cette chaîne commence par un ?, il ne devrait pas être analysée. Si cette chaîne commence par un !--, il est considéré comme un commentaire et le texte suivant doit pas être analysée. Un commentaire est terminée avec une -->, à l'intérieur d'un tel commentaire, des personnages comme < et > sont autorisés. Les attributs peuvent se produire dans les tags, leurs valeurs peuvent éventuellement être entouré par une citation de caractères (' ou "). Si une telle citation existe, il doit être fermé, sinon, si un > est rencontré, la balise n'est pas fermée.

Le code <a href="example>xxx</a><a href="second">text</a> est interprété dans Firefox:

<a href="http://example.com%3Exxx%3C/a%3E%3Ca%20href=" second"="">text</a>

La fonction PHP strip_tags est référencé dans la ligne de 4036 de ext/standard/chaîne.c. Cette fonction appelle la fonction interne php_strip_tags_ex.

Deux tampons existent, l'un pour la sortie, l'autre pour "a l'intérieur des balises HTML". Un compteur" depth détient le nombre de crochets (<).
La variable in_q contient le caractère guillemet (' ou ") le cas échéant, et 0 sinon. Le dernier caractère est stocké dans la variable lc.

Les fonctions détient cinq membres, trois sont mentionnés dans la description ci-dessus la fonction. Basé sur cette information et le corps de la fonction, les états suivants peuvent être tirés:

  • L'état 0 est l'état de sortie (pas dans n'importe quelle balise)
  • État 1 signifie que nous sommes à l'intérieur d'une normale balise html (le tag de la mémoire tampon contient <)
  • L'état 2 signifie que nous sommes à l'intérieur d'une balise php
  • État 3: nous sommes venus de la sortie de l'état et a rencontré l' < et ! caractères (le tag de la mémoire tampon contient <!)
  • Etat 4: à l'intérieur de commentaire HTML

Nous avons juste besoin d'être prudent que pas de balise peut être inséré. C'est, < suivie par un caractère non-blanc. Ligne 4326 vérifie un cas avec l' < personnage qui est décrit ci-dessous:

  • Si à l'intérieur des guillemets (par exemple, <a href="inside quotes">), l' < caractère est ignoré (retiré de la sortie).
  • Si le caractère suivant est un caractère d'espacement, < est ajouté à la sortie de la mémoire tampon.
  • si en dehors d'une balise HTML, l'état devient 1 ("à l'intérieur d'une balise HTML") et le dernier caractère lc est définie à l' <
  • Si, au contraire, à l'intérieur de la balise HTML, le compteur" depth est incrémenté et le caractère ignoré.

Si > est rencontré alors que la marque est ouvert (state == 1), in_q devient 0 ("pas dans un devis") et state devient 0 ("pas dans une balise"). Le tag de la mémoire tampon est mis au rebut.

Attribut de contrôle (pour les personnages comme ' et ") sont effectués sur le tag de la mémoire tampon qui est rejetée. Donc la conclusion est:

strip_tags sans une balise de liste blanche est sans danger pour l'inclusion à l'extérieur de tags, pas de balise sera autorisé.

Par "en dehors des balises", je veux dire, pas dans les balises comme en <a href="in tag">outside tag</a>. Le texte peut contenir < et > même si, comme en >< a>>. Le résultat n'est pas valide en HTML si, <, > et & doivent encore être échappé, en particulier l' &. Qui peut être fait avec htmlspecialchars().

La description pour strip_tags sans whitelist argument serait:

Permet de s'assurer qu'aucune balise HTML existent dans la chaîne renvoyée.

11voto

Matthew Points 25748

Je ne peux pas prédire l'avenir exploits, surtout depuis que je n'ai pas regardé le code source PHP pour cela. Cependant, il y a eu des exploits dans le passé en raison de navigateurs acceptant apparemment non valide tags (comme <s\0cript>). Il est donc possible que dans l'avenir, quelqu'un pourrait être en mesure d'exploiter étrange comportement du navigateur.

Cela mis à part, de les envoyer directement au navigateur, comme un bloc complet de HTML ne doit jamais être en insécurité:

echo '<div>'.strip_tags($foo).'</div>'

Cependant, ce n'est pas sûr:

echo '<input value="'.strip_tags($foo).'" />';

parce que l'on pourrait facilement la fin de la citation par " et insérer un gestionnaire de scripts.

Je pense qu'il est beaucoup plus sûr de toujours convertir errants < en &lt; (et même avec les guillemets).

1voto

kemus Points 19

Les balises de bande sont parfaitement sécurisées - si tout ce que vous faites est la sortie du texte dans le corps html.

Il n'est pas forcément sûr de le mettre dans les attributs mysql ou url.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X