2009-04-20 8 views

Répondre

5

HTML Purifier est l'un des meilleurs outils pour aseptiser HTML avec PHP.

14

Bien qu'il existe de meilleures façons, vous pouvez dépouiller réellement des arguments de balises HTML avec une expression régulière:

<?php 
function stripArgumentFromTags($htmlString) { 
    $regEx = '/([^<]*<\s*[a-z](?:[0-9]|[a-z]{0,9}))(?:(?:\s*[a-z\-]{2,14}\s*=\s*(?:"[^"]*"|\'[^\']*\'))*)(\s*\/?>[^<]*)/i'; // match any start tag 

    $chunks = preg_split($regEx, $htmlString, -1, PREG_SPLIT_DELIM_CAPTURE); 
    $chunkCount = count($chunks); 

    $strippedString = ''; 
    for ($n = 1; $n < $chunkCount; $n++) { 
     $strippedString .= $chunks[$n]; 
    } 

    return $strippedString; 
} 
?> 

Ce qui précède pourrait probablement être écrit en moins de caractères, mais il fait le travail (rapide et sale) .

-1

Vous pouvez également regarder dans le purificateur html. Certes, il est assez gonflé, et pourrait ne pas convenir à vos besoins s'il ne concevait que cet exemple spécifique, mais il offre une purification plus ou moins «à l'épreuve des balles» du html hostile possible. Vous pouvez également choisir d'autoriser ou de refuser certains attributs (il est hautement configurable).

http://htmlpurifier.org/

9

Strip attributs à l'aide SimpleXML (Standard PHP5)

<?php 

// define allowable tags 
$allowable_tags = '<p><a><img><ul><ol><li><table><thead><tbody><tr><th><td>'; 
// define allowable attributes 
$allowable_atts = array('href','src','alt'); 

// strip collector 
$strip_arr = array(); 

// load XHTML with SimpleXML 
$data_sxml = simplexml_load_string('<root>'. $data_str .'</root>', 'SimpleXMLElement', LIBXML_NOERROR | LIBXML_NOXMLDECL); 

if ($data_sxml) { 
    // loop all elements with an attribute 
    foreach ($data_sxml->xpath('descendant::*[@*]') as $tag) { 
     // loop attributes 
     foreach ($tag->attributes() as $name=>$value) { 
      // check for allowable attributes 
      if (!in_array($name, $allowable_atts)) { 
       // set attribute value to empty string 
       $tag->attributes()->$name = ''; 
       // collect attribute patterns to be stripped 
       $strip_arr[$name] = '/ '. $name .'=""/'; 
      } 
     } 
    } 
} 

// strip unallowed attributes and root tag 
$data_str = strip_tags(preg_replace($strip_arr,array(''),$data_sxml->asXML()), $allowable_tags); 

?> 
+0

Cela fonctionne très bien, mais seulement si votre entrée html est correctement formé xml. Sinon, vous devrez faire un pré-nettoyage de l'entrée html avant l'analyse. Cela peut être assez fastidieux à désinfecter si vous n'avez pas tout à fait le contrôle de l'entrée html d'origine non plus. –

7

Voici une fonction qui vous permettra de dépouiller tous les attributs sauf ceux que vous voulez:

function stripAttributes($s, $allowedattr = array()) { 
    if (preg_match_all("/<[^>]*\\s([^>]*)\\/*>/msiU", $s, $res, PREG_SET_ORDER)) { 
    foreach ($res as $r) { 
    $tag = $r[0]; 
    $attrs = array(); 
    preg_match_all("/\\s.*=(['\"]).*\\1/msiU", " " . $r[1], $split, PREG_SET_ORDER); 
    foreach ($split as $spl) { 
     $attrs[] = $spl[0]; 
    } 
    $newattrs = array(); 
    foreach ($attrs as $a) { 
     $tmp = explode("=", $a); 
     if (trim($a) != "" && (!isset($tmp[1]) || (trim($tmp[0]) != "" && !in_array(strtolower(trim($tmp[0])), $allowedattr)))) { 

     } else { 
      $newattrs[] = $a; 
     } 
    } 
    $attrs = implode(" ", $newattrs); 
    $rpl = str_replace($r[1], $attrs, $tag); 
    $s = str_replace($tag, $rpl, $s); 
    } 
    } 
    return $s; 
} 

Dans l'exemple ce serait:

echo stripAttributes('<p class="one" otherrandomattribute="two">'); 

ou si vous par exemple. voulez garder attribut « class »:

echo stripAttributes('<p class="one" otherrandomattribute="two">', array('class')); 

Ou

Si vous souhaitez vous envoyer un message à une boîte de réception et vous composé votre message avec ckeditor, vous pouvez assigner la fonction comme suit et l'écho au $ variable de message avant l'envoi. Notez que la fonction avec le nom stripAttributes() supprimera toutes les balises html inutiles. Je l'ai essayé et ça marche bien. J'ai seulement vu la mise en forme j'ai ajouté comme gras e.t.c.

$message = stripAttributes($_POST['message']); 

ou vous pouvez echo $message; pour la prévisualisation.

5

Je pense sincèrement que la seule façon rationnelle de le faire est d'utiliser une balise d'attributs et avec la bibliothèque HTML Purifier. Exemple de script ici:

<html><body> 

<?php 

require_once '../includes/htmlpurifier-4.5.0-lite/library/HTMLPurifier/Bootstrap.php'; 
spl_autoload_register(array('HTMLPurifier_Bootstrap', 'autoload')); 

$config = HTMLPurifier_Config::createDefault(); 
$config->set('HTML.Allowed', 'p,b,a[href],i,br,img[src]'); 
$config->set('URI.Base', 'http://www.example.com'); 
$config->set('URI.MakeAbsolute', true); 

$purifier = new HTMLPurifier($config); 

$dirty_html = " 
    <a href=\"http://www.google.de\">broken a href link</a 
    fnord 

    <x>y</z> 
    <b>c</p> 
    <script>alert(\"foo!\");</script> 

    <a href=\"javascript:alert(history.length)\">Anzahl besuchter Seiten</a> 
    <img src=\"www.example.com/bla.gif\" /> 
    <a href=\"http://www.google.de\">missing end tag 
ende 
"; 

$clean_html = $purifier->purify($dirty_html); 

print "<h1>dirty</h1>"; 
print "<pre>" . htmlentities($dirty_html) . "</pre>"; 

print "<h1>clean</h1>"; 
print "<pre>" . htmlentities($clean_html) . "</pre>"; 

?> 

</body></html> 

Cela donne le nettoyage suivant, standards conformes fragment HTML:

<a href="http://www.google.de">broken a href link</a>fnord 

y 
<b>c 
<a>Anzahl besuchter Seiten</a> 
<img src="http://www.example.com/www.example.com/bla.gif" alt="bla.gif" /><a href="http://www.google.de">missing end tag 
ende 
</a></b> 

Dans votre cas, la liste blanche serait:

$config->set('HTML.Allowed', 'p'); 
Questions connexes