首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PHP删除HTML标记中的所有HTML事件属性

PHP删除HTML标记中的所有HTML事件属性
EN

Stack Overflow用户
提问于 2013-06-24 09:24:32
回答 3查看 1.9K关注 0票数 0

我想删除所有事件属性(例如,从基于Event reference list的所有事件中)。

在PHP的DOMDocument类中有一个可以识别事件属性的函数吗?

我试过使用RegEx,但单引号和双引号让它变得很复杂:

代码语言:javascript
复制
preg_replace('/on*[a-z]+=".*?"/i', '', $html); // Doesn't match onclick="alert(\"hello\");"

我尝试了一个名为HTMLPurifier的外部库,但它没有删除所有事件属性的选项。

你知道该采取什么方向或一个简单的解决方案吗?

EN

回答 3

Stack Overflow用户

发布于 2013-06-25 04:48:11

如果你想要真正安全的代码,可以使用白名单方法(“只允许这些东西:...”)通常比黑名单方法更可靠(“不允许这些事情:……”)。

您提到了HTML Purifier和“它没有删除所有事件属性的选项”。

那是..。这在技术上是正确的,因为您不能告诉它删除事件属性。不过,原因在于它的卖点:它会自动做到这一点。“缺失”的选项是配置HTML Purifier以允许事件属性的能力。这是故意犯错的。HTML Purifier (顾名思义)有一个很强的安全焦点。

有一些‘不安全的HTML’方面,您可以允许使用HTML Purifier配置(默认配置是故意挑剔的),但事件属性不在其中。(好吧,如果您成功了,您可以教HTML Purifier接受它们,但这需要很大的努力。)

如果你想接受用户HTML,我建议你再试一试。这是一个已经被很多人测试过的相当成熟的工具。

有一些非常棘手的方法来打破超文本标记语言并注入JavaScript。例如,您知道可以使用srchref属性注入JavaScript吗?您知道在某些浏览器中可以使用style标签注入JavaScript吗?看看this XSS cheatsheet吧。它可能会让你大致了解你面对的是什么,以及为什么白名单通常被认为更有效。

无论哪种方式,祝你好运!

票数 1
EN

Stack Overflow用户

发布于 2021-01-28 14:36:01

代码语言:javascript
复制
function filterText($value)
{
  if(!$value) return $value;

  return escapeJsEvent(removeScriptTag($value));

}

function escapeJsEvent($value){
  return preg_replace('/(<.+?)(?<=\s)on[a-z]+\s*=\s*(?:([\'"])(?!\2).+?\2|(?:\S+?\(.*?\)(?=[\s>])))(.*?>)/i', "$1 $3", $value);        
}

function removeScriptTag($text)
{
   $search = array("'<script[^>]*?>.*?</script>'si",
         "'<iframe[^>]*?>.*?</iframe>'si");

  $replace = array('','');

  $text = preg_replace($search, $replace, $text);

  return preg_replace_callback("'&#(\d+);'", function ($m) {
    return chr($m[1]);
  }, $text);
}


echo filterText('<img src=1 href=1 onerror="javascript:alert(1)"></img>');
票数 1
EN

Stack Overflow用户

发布于 2013-06-24 15:38:28

加载HTML文档,遍历所有元素,然后遍历它们的所有属性(嵌套),如果属性以on开头,则删除属性

代码语言:javascript
复制
$doc = new DOMDocument();
$doc->loadHTML($html);

foreach ($doc->getElementsByTagname('*') as $element) 
{
    foreach (iterator_to_array($element->attributes) as $name => $attribute)
    {
        if (substr_compare($name, 'on', 0, 2, TRUE) === 0)
        {
            $element->removeAttribute($name);
        }
    }
}

您可能还希望抓取已知属性名称的列表,并在发现未知属性名称时给出警告(或具有您允许的属性的白名单)。希望这会有所帮助,代码很快就会被输入,可能会有一些小错误。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17266896

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档