2

我正在研究谷歌瀏覽器擴展程序,其中應包括Facebook的sdk.js,但問題是我無法使應用程序工作,因爲內容安全策略..這是我的一部分代碼:谷歌瀏覽器擴展程序內容安全政策

的manifest.json

{ 
    "manifest_version": 2, 

    "name": "<app-name>", 
    "description": "<description>", 
    "version": "0.1", 

    "permissions": [ 
    "tabs","<all_urls>" 
    ], 
    "content_scripts": [ 
    { 
    "matches": [ 
    "http://*/*", 
    "https://*/*" 
    ], 
    "js": ["intercept_connections.js"] 
    } 
    ], 
    "content_security_policy": "script-src 'self' https://connect.facebook.net/en_US/ 'unsafe-eval'; object-src 'self'", 
    "background": { 
    "scripts" : ["background.js"] 
    }, 
    "browser_action": { 
     "default_icon": "icon.png", 
     "default_popup": "popup.html" 
    } 
    } 

popup.html

<html> 
<head> 
    <title>Facebook Mass Sharer</title> 


    <script type="text/javascript" src="popup.js"></script> 
    <script type="text/javascript" src="FbApi.js"></script> 
</head> 

<body> 
<body> 
    <h1>Post to Facebook</h1> 
    <button id="postTest">TestMe</button> 

    </body> 
</body> 
</html> 

popup.js

var handleClick = function() { 
    postToGroup(<groupID>); 
} 

var initialize = function() { 
    var test = document.getElementById('postTest'); 
    test.addEventListener("click",handleClick); 
} 

window.addEventListener("load", initialize); 

FbApi.js(我做的)

window.onload = function() { 
    window.fbAsyncInit = function() { 
     FB.init({ 
      appId  : '<appID>', 
      xfbml  : true, 
      version : 'v2.1', 
      oauth  : true 
     }); 
     }; 

     (function(d, s, id){ 
     var js, fjs = d.getElementsByTagName(s)[0]; 
     if (d.getElementById(id)) {return;} 
     js = d.createElement(s); js.id = id; 
     js.src = "https://connect.facebook.net/en_US/sdk.js"; 
     fjs.parentNode.insertBefore(js, fjs); 
     }(document, 'script', 'facebook-jssdk')); 
} 

var postToGroup = function(groupID) { 
    FB.api(
    "/"+groupID+"/feed", 
    "POST", 
    { 
     "message": "This is a test message" 
    }, 
    function (response) { 
     if (response && !response.error) { 
     /* handle the result */ 
     } 
    } 
); 
} 

事情是我不斷收到此錯誤:

Refused to execute JavaScript URL because it violates the following Content Security Policy directive: "script-src https:// 'unsafe-eval'". Either the 'unsafe-inline' keyword, a hash ('sha256-...'), or a nonce ('nonce-...') is required to enable inline execution. 

我試圖改變"content_security_policy": "script-src 'self' https://connect.facebook.net/en_US/ 'unsafe-eval'; object-src 'self'""content_security_policy": "script-src 'self'; object-src 'self'"或 「content_security_policy」:"script-src 'self' https://connect.facebook.net/en_US/ 'inline-eval'; object-src 'self'"爲在錯誤中建議,但沒有運氣。我應該嘗試什麼?

+0

你能看到什麼是拋出該錯誤?這聽起來像Facebook可能在某處使用eval。 – jmort253 2014-08-31 20:34:21

+0

在Facebook的API使用eval的一次有......看看[https://connect.facebook.net/en_US/sdk.js](here)..Just搜索EVAL,你會發現它一個time..But我正在使用'unsafe-eval',所以我不知道我的錯誤在哪裏 – csanonymus 2014-08-31 20:42:53

+0

我很確定Google認爲eval不安全。我不認爲你可以重寫它。您需要做的是使用該內容的iframe,以便無法訪問任何Chrome API。然後,您需要使用postMessage在iframe和擴展的主要部分之間進行通信。 – jmort253 2014-08-31 20:44:39

回答

2

谷歌認爲eval是一個不安全,潛在危險的操作,因爲動態內容可能會進入應用程序/擴展並自行運行,從而可以訪問整個強大的chrome世界。訪問文件系統和其他通常禁止使用普通網站JavaScript的資源。

因此,在您的擴展和應用程序使用這些CSP-違反庫的唯一辦法就是sandbox them

我們通過列出擴展包內的特定HTML文件爲被沙盒做到這一點。每當加載沙盒頁面時,它將被移動到唯一的來源,並且將被拒絕訪問chrome。* API。如果我們通過iframe將這個沙箱頁面加載到我們的擴展中,我們可以傳遞它的消息,讓它以某種方式處理這些消息,並等待它傳遞給我們一個結果。這種簡單的消息傳遞機制爲我們提供了在擴展的工作流程中安全地包含eval驅動代碼所需的一切。

總之,你需要在你的擴展中創建一個額外的組件,一個HTML文件,你的沙盒,以及加載有問題的Facebook代碼。然後,您將在沙盒頁面中添加監聽器,該監聽器可以從包含的HTML頁面接收消息,然後處理擴展中的事件。這可以保護您的用戶免受eval攻擊,因爲eval'd代碼無法訪問沙箱中的任何Chrome API。

當我使用sipml5的JavaScript SIP庫時,我遇到了同樣的問題。該庫非常寬鬆地使用eval,因此使用該庫的唯一方法是在沙箱中。我創建了一個小型庫,用於處理在沙箱和主應用程序之間同步存儲數據,稱爲Sandbox StorageAPI for Chrome™。在代碼中,你可以看到我是如何的沙箱和主網頁之間的通信:

manifest.json的:

"sandbox": { 
    "pages": ["sandbox.html" ] 
    }, 

炫魅。HTML:

<!-- Sandboxed page --> 
    <iframe height="800" width="1200" id="sandboxFrame" class="sandbox active" src="sandbox.html" style=""></iframe> 

storageAPI.js:

在這裏,我在監聽應用/擴展與沙箱「註冊」本身的主體,部分安全沙箱創建一個監聽器然後存儲參考,因此沙箱可以傳送回主模塊:

window.addEventListener('message', function(event) { 
      console.info("Message received from wrapper = " + JSON.stringify(event.data)); 
      console.info("location = " + window.location.href); 
      switch(event.data.command) { 

       case 'initStorageAPI': 
        storageAPI.storage = event.data.storage; result = "It's alive!!!"; 
        storageAPI.sandbox.window.onload(); 
        console.info("Prepare to postMessage back to the wrapper..."); 
        storageAPI.wrapper = event; 
        event.source.postMessage({'command':'initStorageComplete','result': result}, event.origin); 

這裏的地方,我們將數據發送回主模塊的例子:

storageAPI.setItem = function(key, value) { 
     if(storageAPI.CHROME_EXTENSION == false) { 
      return window.localStorage.setItem(key, value); 
     } else { 
      storageAPI.storage[key] = value; 
      // send back to the wrapper to store 
      storageAPI.wrapper.source.postMessage({'command':'writeStorage', 'storage': storageAPI.storage}, storageAPI.wrapper.origin); 

     } 

    }; 

總之,您可以使用一種類似的技術來將數據來回/從沙箱來回/從主模塊來回,將不安全的庫連接到擴展的安全,敏感的部分。有關更多詳細信息,請參閱文檔。

記住的iframe甚至可以隱藏。你真的只需要它就可以運行不安全的代碼。

免責聲明:我是沙盒StorageAPI爲Chrome™開發人員。我不隸屬於Google或Chrome,所有商標都屬於Google。

+0

CSP strict-dynamic的任何想法都無法用於Chrome擴展程序? – Pacerier 2017-08-12 14:13:14