javascript 解除绑定 dom 事件

发布于 2024-12-01 11:15:16 字数 986 浏览 2 评论 0原文

我正在开发一个 Web 框架,并尝试在其中构建 XSS 预防功能。我已经将其设置为转义传入数据以存储在数据库中,但有时您想保存用户生成的 html。我正在尝试制作一个自定义标签来阻止任何 javascript 执行,这是我的第一个 hack:

<html>
  <head>
    <script type="text/javascript" src="/js/jquery.min.js"></script>
  </head>
  <body>

    <preventjs>
      <div id="user-content-area">
        <!-- evil user content -->
          <p onclick="alert('evil stuff');">I'm not evil, promise.</p>
          <p onmouseover="alert('evil stuff');">Neither am I.</p> 
        <!-- end user content -->
      </div>
    </preventjs>

    <script type="text/javascript">
      // <preventjs> tags are supposed to prevent any javascript events
      // but this does not unbined DOM events
      $("preventjs").find("*").unbind();
    </script>

  </body>
</html>

我尝试使用 jQuery 来解除所有内容的绑定,但它不会解除 DOM 中的事件绑定,这正是我想要的试图做。是否可以解除 DOM 元素的所有事件的绑定?

I'm working on a web framework and am trying to build XSS prevention into it. I have set it up so it will escape incoming data for storage in the database, but sometimes you want to save html that the user generates. I am trying to make a custom tag that will prevent any javascript from executing, here is my first hack at it:

<html>
  <head>
    <script type="text/javascript" src="/js/jquery.min.js"></script>
  </head>
  <body>

    <preventjs>
      <div id="user-content-area">
        <!-- evil user content -->
          <p onclick="alert('evil stuff');">I'm not evil, promise.</p>
          <p onmouseover="alert('evil stuff');">Neither am I.</p> 
        <!-- end user content -->
      </div>
    </preventjs>

    <script type="text/javascript">
      // <preventjs> tags are supposed to prevent any javascript events
      // but this does not unbined DOM events
      $("preventjs").find("*").unbind();
    </script>

  </body>
</html>

I tried using jQuery to unbind everything, but it doesn't unbind events in the DOM, which is exactly what I'm trying to do. Is it possible to unbind all events for a DOM element?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

风柔一江水 2024-12-08 11:15:16

你的问题是你这样做是错误的——你应该在收到潜在敌意内容时过滤所有用户输入。

执行此操作时的第一条经验法则是“始终列入白名单,绝不列入黑名单”。不要允许用户生成的 HTML 中的任何和所有属性,而只需保留允许的属性列表并在收到 HTML 时删除所有其他属性(可能在客户端 - 肯定在服务器端。)

哦,还有 HTML不是常规语言。对于此任务,您需要使用 HTML 解析器,而不是正则表达式。

You're problem is that you are doing this on the wrong end of things -- you should be filtering all user input of potentially hostile content when you receive it.

The first rule of thumb when doing this is "always whitelist, never blacklist". Rather than allowing any and all attributes in your user-generated HTML, simply keep a list of allowed attributes and strip away all others when you receive the HTML (possibly on the client side -- definitely on the server side.)

Oh, and HTML is not a regular language. You'll want to use an HTML parser, not a regular expression for this task.

鹊巢 2024-12-08 11:15:16

.unbind 只会取消绑定使用 jQuery 附加的事件。您可以通过将内联事件处理程序代码设置为 null 来摆脱它们,例如:

$("preventjs *").removeAttr("onclick").removeAttr("onmouseover");

演示。

编辑:这是一个邪恶的解决方案,您可以删除以“on”开头的所有属性:

$("preventjs *").each(function() {
    var attribs = this.attributes;
    var that = this;
    $.each(attribs, function(i, attrib) {
        if(attrib.name.indexOf("on") === 0) {
            $(that).removeAttr(attrib.name);
        }
    });
});

演示。< /strong>

.unbind will only unbind events attached using jQuery. You can get rid of inline event handler code by setting them to null, e.g.:

$("preventjs *").removeAttr("onclick").removeAttr("onmouseover");

Demo.

EDIT: Here's an evil solution, you can remove all attributes starting with "on":

$("preventjs *").each(function() {
    var attribs = this.attributes;
    var that = this;
    $.each(attribs, function(i, attrib) {
        if(attrib.name.indexOf("on") === 0) {
            $(that).removeAttr(attrib.name);
        }
    });
});

Demo.

小草泠泠 2024-12-08 11:15:16

问题是你有内联处理程序。 unbind 无法删除内联处理程序。

<p onclick="alert('evil stuff'...
   ^^^^

要删除内联处理程序,请使用 removeAttr

$("preventjs").find("*").removeAttr('onclick');
$("preventjs").find("*").removeAttr('onmouseover');

The problem is that you've inline handlers. unbind cannot remove inline handlers.

<p onclick="alert('evil stuff'...
   ^^^^

To remove inline handlers, use removeAttr

$("preventjs").find("*").removeAttr('onclick');
$("preventjs").find("*").removeAttr('onmouseover');
预谋 2024-12-08 11:15:16

您可以单独取消绑定事件:

$('p').each(function(){ this.onclick = this.onmouseover = undefined; });

如果您想取消绑定其他事件(例如 mouseout),则必须将它们添加到该列表中:

$('p').each(function(){ this.onclick = 
                          this.onmouseover = 
                            this.onmouseout = undefined; });

当然,您需要使用 $('p') 以外的选择器,我只是不想放你的另一个,因为 preventjs 不是 HTML 标签

You can unbind the events individually:

$('p').each(function(){ this.onclick = this.onmouseover = undefined; });

If you want to unbind other events like mouseout you have to add them to that list:

$('p').each(function(){ this.onclick = 
                          this.onmouseover = 
                            this.onmouseout = undefined; });

Of course you'll want to use a selector other than $('p'), I just didn't want to put your other one because preventjs is not an HTML tag

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文