2011-08-25 148 views
2

我工作的一個web框架,想建立XSS預防進去。我已經設置好了,所以它將轉義傳入的數據存儲在數據庫中,但有時候你想保存用戶生成的html。我試圖做一個自定義標籤,以防止任何JavaScript無法執行,這是我的第一次入侵吧:JavaScript的解除綁定DOM事件

<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元素的所有事件?

+0

但如果JavaScript是隻是一個腳本標籤中的內容。它會執行之前,你甚至可以嘗試清理它。 –

+0

我打算在保存數據之前刪除腳本標記,這些腳本很容易檢測到。 – regality

回答

4

你的問題是,你這樣做的事情的錯誤結局 - 你應該過濾所有用戶輸入的潛在敵對內容當你收到它

執行此操作時拇指的第一條規則是「永遠的白名單,黑名單永不」。您不必在用戶生成的HTML中允許任何屬性,只需保留允許的屬性列表,並在收到HTML時剝去所有其他屬性(可能位於客戶端 - 絕對位於服務器端)。

呵呵,HTML不是一般的語言。您需要使用HTML解析器,而不是此任務的正則表達式。

+0

你能推薦一個HTML解析器嗎?我在服務器端用PHP編碼所有東西。 – regality

+0

@regality - 看到這個問題的答案對一些好的:http://stackoverflow.com/questions/292926/robust-mature-html-parser-for-php –

1

的問題是,你已經內嵌處理器。 unbind無法刪除內聯處理程序。

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

要刪除內嵌處理器,使用removeAttr

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

FTFY:http://jsfiddle.net/mrchief/pv2U6/1/。錯誤地使用jsFiddle! – Mrchief

+0

@Joey,你需要包含jQuery,否則它不會。 – regality

+0

是啊,我沒注意 – Joe

2

.unbind將使用jQuery僅附解除綁定事件。您可以通過設置他們擺脫的內聯事件處理代碼爲null,如:

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

Demo.

編輯:這是一個邪惡的解決方案,你可以刪除所有的屬性開始用「上」:

$("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.

+0

我想這樣做類似的東西,但也有很多,我不希望追捕,跟蹤,並隨時更新晦澀的事件。 – regality

+0

@regality - 請看看我的編輯請。 – karim79

+0

這很有創意。是否有任何屬性可能通過或將被刪除,不應該? – regality

0

可以單獨取消綁定事件:

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

如果你想解除綁定其他事件,如鼠標移出你必須將它們添加到列表:

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

當然,你需要使用比$('p')其他選擇,我只是不想把你的另一個,因爲preventjs不是一個HTML標記