71 votes

supprimer la balise script du contenu HTML

J'utilise HTML Purifier (http://htmlpurifier.org/)

Je veux juste enlever <script> uniquement. Je ne veux pas supprimer la mise en forme en ligne ou toute autre chose.

Comment puis-je y parvenir ?

Une dernière chose : existe-t-il un autre moyen de supprimer les balises script du HTML ?

3 votes

N'oubliez pas que les balises script ne sont pas les seules parties vulnérables du HTML.

0 votes

Oui, je sais qu'il y a d'autres parties vulnérables aussi, mais j'ai juste besoin d'enlever les balises script.

3 votes

Lire este . Il vous aidera à

155voto

webarto Points 11803

Parce que cette question est étiquetée avec regex Je vais répondre par la solution du pauvre dans cette situation :

$html = preg_replace('#<script(.*?)>(.*?)</script>#is', '', $html);

Cependant, les expressions régulières ne servent pas à analyser le HTML/XML, même si vous écrivez la commande parfait expression qui finira par casser, cela ne vaut pas la peine, bien que, dans certains cas, il soit utile de corriger rapidement un balisage, et comme c'est le cas avec les corrections rapides, oubliez sécurité . N'utilisez les regex que sur le contenu/marquage auquel vous faites confiance.

Rappelez-vous, tout ce que l'utilisateur saisit doit être considéré pas sûr .

Meilleur La solution ici serait d'utiliser DOMDocument qui est conçu pour cela. Voici un extrait qui montre à quel point il est facile, propre (par rapport aux expressions rationnelles), (presque) fiable et (presque) sûr de faire la même chose :

<?php

$html = <<<HTML
...
HTML;

$dom = new DOMDocument();

$dom->loadHTML($html);

$script = $dom->getElementsByTagName('script');

$remove = [];
foreach($script as $item)
{
  $remove[] = $item;
}

foreach ($remove as $item)
{
  $item->parentNode->removeChild($item); 
}

$html = $dom->saveHTML();

J'ai supprimé le HTML intentionnellement car même celui-ci peut bork .

13 votes

-1 pour la solution RegExp. Voir cette discussion .

54 votes

J'ai vu cette discussion il y a longtemps, vous devriez la lire, pas seulement la voir.

11 votes

Bien que j'apprécie votre réponse distante, mon raisonnement pour désapprouver votre réponse est solide. Voir cette phrase pour une balise script qui contourne votre regex. En toute équité, on peut dire que c'est plus un défaut de votre expression régulière particulière qu'une raison d'abandonner complètement la regex. Mais, intéressant pour moi tout de même.

43voto

Alex Points 5764

Utilisez l'application PHP DOMDocument parser.

$doc = new DOMDocument();

// load the HTML string we want to strip
$doc->loadHTML($html);

// get all the script tags
$script_tags = $doc->getElementsByTagName('script');

$length = $script_tags->length;

// for each tag, remove it from the DOM
for ($i = 0; $i < $length; $i++) {
  $script_tags->item($i)->parentNode->removeChild($script_tags->item($i));
}

// get the HTML string back
$no_script_html_string = $doc->saveHTML();

Cela a fonctionné pour moi en utilisant le document HTML suivant :

<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <title>
            hey
        </title>
        <script>
            alert("hello");
        </script>
    </head>
    <body>
        hey
    </body>
</html>

Gardez à l'esprit que le DOMDocument nécessite PHP 5 ou plus.

5 votes

+0 J'en ai marre d'entendre cette discussion sur les regex et le HTML. Dans un peu de Pour des occasions très spéciales, il est possible d'utiliser des expressions rationnelles. Dans mon cas, j'obtiens cette erreur : Warning: DOMDocument::loadHTML() [domdocument.loadhtml]: Tag myCustomTag invalid in Entity . J'ai tout essayé. Tout ce que je veux faire, c'est supprimer les balises script pour une toute petite partie de l'application ( sans de passer plus de temps dessus). Je vais utiliser preg_replace et c'est tout. Je ne veux plus rien entendre à ce sujet :)

2 votes

Voir mon commentaire sur la meilleure réponse choisie. Je préférerais que les codeurs couvrent les cas généraux, car les utilisateurs malveillants peuvent être très malins. Toutefois, vous avez raison : dans le cadre du développement d'une application interne, par exemple, on pourrait considérer qu'il est acceptable d'ignorer ces vulnérabilités et d'utiliser des expressions rationnelles.

0 votes

@Xeoncross Merci ! Je vais essayer la prochaine fois que j'aurai l'occasion de travailler sur ce projet. En ce moment, je suis occupé avec d'autres codes et je ne veux pas avoir à déterrer ces trucs :).

6voto

prasanthnv Points 99
$html = <<<HTML
...
HTML;
$dom = new DOMDocument();
$dom->loadHTML($html);
$tags_to_remove = array('script','style','iframe','link');
foreach($tags_to_remove as $tag){
    $element = $dom->getElementsByTagName($tag);
    foreach($element  as $item){
        $item->parentNode->removeChild($item);
    }
}
$html = $dom->saveHTML();

0 votes

J'ai upvoted cette réponse parce que d'une part elle est propre et simple, et d'autre part elle m'a rappelé que les iframes pouvaient aussi me causer des problèmes.

1 votes

De plus, je viens de réaliser que cela ajoute les balises doctype, html et body, ce qui est correct pour la question actuelle, mais ne l'était pas pour moi, mais je n'ai dû changer qu'une seule ligne (comme le dit le commentaire du haut de la page saveHTML php.net) : $dom->loadHTML($html,LIBXML_HTML_NOIMPLIED|LIBXML_HTML_NODEF‌​DTD);

4voto

José Carlos PHP Points 789

Un moyen simple de manipuler les chaînes de caractères.

$str = stripStr($str, '<script', '</script>');

function stripStr($str, $ini, $fin)
{
    while(($pos = mb_stripos($str, $ini)) !== false)
    {
        $aux = mb_substr($str, $pos + mb_strlen($ini));
        $str = mb_substr($str, 0, $pos).mb_substr($aux, mb_stripos($aux, $fin) + mb_strlen($fin));
    }

    return $str;
}

0 votes

@Someone_who_likes_SE Oui, bien sûr. Vous pouvez utiliser stripos et substr au lieu de mb_stripos et mb_substr, mais je préfère utiliser les fonctions MB, elles sont plus fiables.

0 votes

Tout cela est très bien, mais il y a un sérieux défaut ici. Attention, vous ne savez pas quelle entrée vous avez. Si $fin n'est pas dans $str (ou $aux), vous avez une boucle parfaite ici. Bon débogage ! Il y a plusieurs options pour modifier ce code afin de corriger cette faille. Je vous laisse le soin de le corriger.

0 votes

@kklepper Je l'ai modifié, maintenant si $fin n'est pas trouvé, il coupe de $ini à la fin de la chaîne. Salutations !

3voto

ctf0 Points 3640
  • c'est une fusion des deux ClandestineCoder & Binh WPO .

le problème avec les flèches du tag script est qu'elles peuvent avoir plus d'une variante

ex. (< = &lt; = &amp;lt; ) & ( > = &gt; = &amp;gt; )

Ainsi, au lieu de créer un tableau de motifs avec un bazillion de variantes, je pense qu'une meilleure solution serait

return preg_replace('/script.*?\/script/ius', '', $text)
       ? preg_replace('/script.*?\/script/ius', '', $text)
       : $text;

cela supprimera tout ce qui ressemble à script.../script quel que soit le code de la flèche/variante et vous pouvez le tester ici. https://regex101.com/r/lK6vS8/1

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