iT邦幫忙

3

CSP(Content Security Policy)與$.html()的...意外?

因為Mozilla最近推出了一個網站安全設定檢測的服務:OBSERVATORY,所以就用它來檢測一下,並且嘗試根據他的建議調整伺服器設定(在測試機上)。

這些設定其實大部分只要設定標頭就可以做到,Contnet Security Policy就是其中一個,只要設定好Content-Security-Policy標頭,支援的瀏覽器就會依照這個指定的政策來做來源的控管。例如:

Content-Security-Policy: default-src 'self' 'unsafe-inline' cdnjs.cloudflare.com

這樣指定以後,除了來自網站本身的資源、還可以使用cdnjs來的js檔以及在html元素中使用javascript來處理事件或是用style屬性指定樣式。例如:

...
<link type="text/css" rel="stylesheet" href="/style/main.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
...
<!-- 設定'unsafe-inline',下面這行才會動 -->
<a href="#" onclick="alert('oh no');return false" style="display:inline-block;height:48px;width:48px">Don't Click</div>
<!-- 設定'unsafe-inline',才允許在script tag中寫javascript -->
<script>
$(function() {
    $('#btn').click(function(e) {e.preventDefault(); console.log('btn clicked')};
});
</script>

因為拿掉'unsafe-inline'規則的話,勢必要大改...所以就加上去,心想我應該沒有在Javascript中使用eval()才對,不知道多少年沒這樣用了...所以沒有加上'unsafe-eval',心想應該沒問題。

測試一下發現...用來當做MessageBox的fancybox全掛了/images/emoticon/emoticon02.gif

關鍵:如果用fancybox載入的內容,含有script tag就一律掛:

<script>
$('#msg').click(function() {...});
</script>

甚至

<script src="/js/popup.js"></script>

都一樣。

追了一下fancybox跟jQuery運作的過程,發現:

  1. 如果不設定使用iframe,fancybox會用$.ajax()的方式取得內容,然後用$.html(內容)的方式來顯示
  2. jQuery會剖析傳給$.html()的內容,把script tag內的Javascript程式,用eval()來執行
  3. jQuery會剖析傳給$.html()的內容,把script tag指定的來源檔案用$.ajax()的方式抓下來,然後用eval()來執行

就是這樣...因為要透過$.html()動態顯示的內容中有script tag,所以jQuery用eval()幫你執行了......回想當初沒用iframe,是因為fancybox不一定抓得到iframe內容的寬與高來自動調整,為了偷懶所以沒使用的啊XD(改用iframe的話,只好讓這些popup在載入完成後,document.body.scrollWidth及document.body.scrollHeight確定了,再呼叫外層的函數來調整大小及位置)

總之,$.html()不僅僅是innerHTML的包裝,他還多做了許多事情,會在你不知道的地方使用eval()喔。(其實在使用innerHTML的時候,頁面是會reflow,但是Script並不會被執行的哪。也因為這樣,所以jQuery幫你做了XD)


1 則留言

0
海綿寶寶
iT邦大神 1 級 ‧ 2016-09-18 11:23:30

雖然我不懂您
但是我謝謝您
/images/emoticon/emoticon41.gif

我要留言

立即登入留言