我有一个表单,用户可以使用TinyMCE进行样式输入描述。因此,我的用户可以插入HTML。我使用strip_tags
已经剥离几乎所有的HTML元素,但用户仍然可以输入恶意数据,比如这一个:从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();
这是几乎等同于我先前发布的代码。我的代码(和你的代码)插入了HTML实体和'html'和'body'标签,这正是我试图阻止的。我需要一个不使用DOMDocument的解决方案,并且不会尝试“修复”HTML(因为HTML并不是整个文档)。 –
为了公平起见,我在现有页面上运行了这段代码,发现没有任何问题 - 当我按照“原样”运行它时,没有找到现有的html标记,就像你说的那样,它已经为自己添加了所有的HTML标记。 – RamRaider