javascript unbind dom события - PullRequest
       12

javascript unbind dom события

2 голосов
/ 25 августа 2011

Я работаю над веб-фреймворком и пытаюсь встроить в него предотвращение XSS.Я настроил его так, что он будет избегать входящих данных для хранения в базе данных, но иногда вы хотите сохранить HTML, который генерирует пользователь.Я пытаюсь создать пользовательский тег, который будет препятствовать выполнению любого javascript, вот мой первый взлом:

<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?

Ответы [ 4 ]

4 голосов
/ 25 августа 2011

Вы проблема в том, что вы делаете это не с того конца - вы должны фильтровать весь пользовательский ввод потенциально враждебного контента при его получении .

Первое эмпирическое правило при этом: «всегда белый список, никогда не черный» Вместо того, чтобы разрешать какие-либо и все атрибуты в вашем сгенерированном пользователем HTML, просто сохраните список разрешенных атрибутов и удалите все остальные, когда вы получите HTML (возможно, на стороне клиента - определенно на стороне сервера).

О, и HTML не является обычным языком. Вы захотите использовать анализатор HTML, а не регулярное выражение для этой задачи.

2 голосов
/ 25 августа 2011

.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);
        }
    });
});

Демо.

1 голос
/ 25 августа 2011

Проблема в том, что у вас встроенные обработчики.unbind не может удалить встроенные обработчики.

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

Чтобы удалить встроенные обработчики, используйте removeAttr

$("preventjs").find("*").removeAttr('onclick');
$("preventjs").find("*").removeAttr('onmouseover');
0 голосов
/ 25 августа 2011

Вы можете отменить привязку событий по отдельности:

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

Если вы хотите отменить привязку других событий, например указателей мыши, вы должны добавить их в этот список:

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

Конечно, вы 'Я захочу использовать селектор, отличный от $('p'), я просто не хочу ставить другой, потому что preventjs не является тегом HTML

...