Ran*_*der 12 php xss script-tag html-parsing domdocument
我在这里使用@Alex的方法使用内置的DOMDocument从HTML文档中删除脚本标记.问题是,如果我有一个带有Javascript内容的脚本标记,然后是另一个链接到外部Javascript源文件的脚本标记,则不会从HTML中删除所有脚本标记.
$result = '
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>
hey
</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
alert("hello");
</script>
</head>
<body>hey</body>
</html>
';
$dom = new DOMDocument();
if($dom->loadHTML($result))
{
$script_tags = $dom->getElementsByTagName('script');
$length = $script_tags->length;
for ($i = 0; $i < $length; $i++) {
if(is_object($script_tags->item($i)->parentNode)) {
$script_tags->item($i)->parentNode->removeChild($script_tags->item($i));
}
}
echo $dom->saveHTML();
}
Run Code Online (Sandbox Code Playgroud)
以上代码输出:
<html>
<head>
<meta charset="utf-8">
<title>hey</title>
<script>
alert("hello");
</script>
</head>
<body>
hey
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
从输出中可以看出,只删除了外部脚本标记.有什么办法可以确保删除所有脚本标记吗?
Séb*_*uld 23
你的错误实际上是微不足道的.一个DOMNode对象(及其所有后代- ,DOMElement!DOMNodeList和其他一些),当它的父元素的变化,最明显的是当其子女人数变化自动更新.这是在PHP文档的几行中写的,但大多数都是在地毯下.
如果循环使用($k instanceof DOMNode)->length,并随后从节点中删除元素,您会注意到该length属性实际上已更改!我不得不写自己的库来抵消这个和其他一些怪癖.
解决方案:
if($dom->loadHTML($result))
{
while (($r = $dom->getElementsByTagName("script")) && $r->length) {
$r->item(0)->parentNode->removeChild($r->item(0));
}
echo $dom->saveHTML();
Run Code Online (Sandbox Code Playgroud)
我实际上并没有循环 - 只需一次弹出第一个元素.结果:http://sebrenauld.co.uk/domremovescript.php
为了避免您获得实时节点列表的惊喜- 随着删除节点而缩短 - 您可以使用以下方法将副本复制到数组中iterator_to_array:
foreach(iterator_to_array($dom->getElementsByTagName($tag)) as $node) {
$node->parentNode->removeChild($node);
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9593 次 |
| 最近记录: |