2009-04-20 16 views

risposta

5

HTML Purifier è uno degli strumenti migliori per la sanificazione HTML con PHP.

14

Anche se ci sono modi migliori, si potrebbe effettivamente striscia argomenti da tag html con un'espressione regolare:

<?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; 
} 
?> 

È possibile che questo potrebbe essere probabilmente scritto in meno caratteri, ma fa il lavoro (rapido e sporco) .

-1

Si potrebbe anche guardare nel depuratore html. È vero, è piuttosto gonfio, e potrebbe non adattarsi alle tue esigenze se solo concepisce questo specifico esempio, ma offre una purificazione più o meno "a prova di proiettile" di un possibile html ostile. Inoltre è possibile scegliere di consentire o disabilitare determinati attributi (è altamente configurabile).

http://htmlpurifier.org/

9

Striscia attributi usando SimpleXML (Standard in 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

Questa grande opera, ma solo se il tuo input html è formato correttamente xml. Altrimenti dovrai eseguire un pre-cleanup dell'ingresso html prima di analizzare. Questo può essere piuttosto noioso da disinfettare se non si ha il controllo dell'input html di origine. –

7

Ecco una funzione che vi permetterà di striscia tutti gli attributi ad eccezione di quelli che si desidera:

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; 
} 

Nell'esempio sarebbe:

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

o se si ad es. vuole mantenere attributo "class":

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

O

supponendo che stanno per inviare un messaggio a una casella di posta e si compone il messaggio con CKEditor, è possibile assegnare la funzione come segue ed eco al $ messaggio variabile prima dell'invio. Notare che la funzione con il nome stripAttributes() rimuoverà tutti i tag html che non sono necessari. L'ho provato e funziona bene. ho visto solo la formattazione che ho aggiunto come grassetto e.t.c.

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

o si può echo $message; per l'anteprima.

5

Onestamente, penso che l'unico modo corretto per farlo è quello di utilizzare un tag e una lista di attributi con nella libreria HTML Purifier. Esempio di script qui:

<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> 

Questo produce il seguente pulita, su standard conformi HTML frammento:

<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> 

Nel tuo caso la lista bianca sarebbero:

$config->set('HTML.Allowed', 'p'); 
Problemi correlati