[英]Stripping all tag attributes from a HTML string except style
我有一個表單,用戶可以使用TinyMCE進行樣式輸入描述。 因此,我的用戶可以插入HTML。 我已經使用strip_tags
剝離了幾乎所有HTML元素,但是用戶仍然可以輸入惡意值,例如:
<strong onclick="window.location='http://example.com'">Evil</strong>
我想通過從style
除去所有標簽中的所有屬性來阻止用戶執行此操作。
我只能找到去除所有屬性或僅去除指定屬性的解決方案。 我只想保留style
屬性。
我已經嘗試了DOMDocument,但似乎自己添加了DOCTYPE
和html
標簽,將其輸出為整個HTML文檔。 此外,有時似乎會隨機添加HTML實體,例如上下顛倒的問號。
這是我的DOMDocument實現:
//Example "evil" input
$description = "<p><strong onclick=\"alert('evil');\">Evil</strong></p>";
//Strip all tags from description except these
$description = strip_tags($description, '<p><br><a><b><i><u><strong><em><span><sup><sub>');
//Strip attributes from tags (to prevent inline Javascript)
$dom = new DOMDocument();
$dom->loadHTML($description);
foreach($dom->getElementsByTagName('*') as $element)
{
//Attributes cannot be removed directly because DOMNamedNodeMap implements Traversable incorrectly
//Atributes are first saved to an array and then looped over later
$attributes_to_remove = array();
foreach($element->attributes as $name => $value)
{
if($name != 'style')
{
$attributes_to_remove[] = $name;
}
}
//Loop over saved attributes and remove them
foreach($attributes_to_remove as $attribute)
{
$element->removeAttribute($attribute);
}
}
echo $dom->saveHTML();
這是DOMDocument :: loadHtml()的兩個選項,可以解決該問題。
$dom->loadHTML($description, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
但是它們僅在libxml> = 2.7.8中可用。 如果您使用的是舊版本,則可以嘗試其他方法:
如果您知道期望一個片段,則可以使用該片段並僅保存body
元素的子元素。
$description = <<<'HTML'
<strong onclick="alert('evil');" style="text-align:center;">Evil</strong>
HTML;
$dom = new DOMDocument();
$dom->loadHTML($description);
foreach($dom->getElementsByTagName('*') as $element) {
$attributes_to_remove = iterator_to_array($element->attributes);
unset($attributes_to_remove['style']);
foreach($attributes_to_remove as $attribute => $value) {
$element->removeAttribute($attribute);
}
}
foreach ($dom->getElementsByTagName('body')->item(0)->childNodes as $node) {
echo $dom->saveHTML($node);
}
輸出:
<strong style="text-align:center;">Evil</strong>
我不知道這或多或少是您的意思...
$description = "<p><strong onclick=\"alert('evil');\">Evil</strong></p>";
$description = strip_tags( $description, '<p><br><a><b><i><u><strong><em><span><sup><sub>' );
$dom=new DOMDocument;
$dom->loadHTML( $description );
$tags=$dom->getElementsByTagName('*');
foreach( $tags as $tag ){
if( $tag->hasAttributes() ){
$attributes=$tag->attributes;
foreach( $attributes as $name => $attrib ) $tag->removeAttribute( $name );
}
}
echo $dom->saveHTML();
/* Will echo out `Evil` in bold but without the `onclick` */
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.