【问题标题】:Gmail Content Security Policy on Chrome extensions有关 Chrome 扩展程序的 Gmail 内容安全政策
【发布时间】:2014-12-16 22:26:42
【问题描述】:

Gmail 刚刚更新了其内容安全政策:http://googleonlinesecurity.blogspot.com/2014/12/reject-unexpected-content-security.html

这会为我的 Chrome 扩展程序引发错误,该扩展程序增强了 gmail。需要明确的是,我的内容脚本正在加载另一个托管在我的服务器上的脚本。这允许快速部署。

 Refused to load the script 'https://<domain-path>.js?' because it violates the following Content Security Policy directive: "script-src 'self' 'unsafe-inline' 'unsafe-eval' https://talkgadget.google.com/ https://www.googleapis.com/appsmarket/v2/installedApps/ https://www-gm-opensocial.googleusercontent.com/gadgets/js/ https://docs.google.com/static/doclist/client/js/ https://www.google.com/tools/feedback/ https://s.ytimg.com/yts/jsbin/ https://www.youtube.com/iframe_api https://ssl.google-analytics.com/ https://apis.google.com/_/scs/abc-static/ https://apis.google.com/js/ https://clients1.google.com/complete/ https://apis.google.com/_/scs/apps-static/_/js/ https://ssl.gstatic.com/inputtools/js/ https://ssl.gstatic.com/cloudsearch/static/o/js/ https://www.gstatic.com/feedback/js/ https://www.gstatic.com/common_sharing/static/client/js/ https://www.gstatic.com/og/_/js/".

这是我从内容脚本加载托管脚本的方式:

var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'https://<domain-path>.js';
(document.body || document.head || document.documentElement).appendChild(script);

有什么想法吗?

【问题讨论】:

  • 显然您可以使用 chrome 扩展 webRequest 更改 csp 响应标头。这是一种解决方法。但是我不确定这是否是一个好习惯。

标签: javascript google-chrome google-chrome-extension content-security-policy


【解决方案1】:

您不应在 Gmail 中插入外部脚本,因为它会减慢页面加载时间,并使其他人更难审核您的扩展程序。您当然应该使用 webRequest API 来删除 Content-Security-Policy 标头,因为这会降低 Gmail 的安全性。

如果您真的想在页面上下文中获取并执行最新版本的代码,请使用XMLHttpRequest 加载脚本,然后插入带有此代码的&lt;script&gt; 标记:

// NOTE: Inserting external scripts should be avoided if possible!
// Do not use this method if your extension can completely function
// without external scripts!

// Even if you have to load an external script, make sure that it is loaded over
// https:, NEVER over http: ! If you insert scripts from http:-URLs, your users'
// security can be compromised by MITM attacks.

var x = new XMLHttpRequest();
x.open('GET', 'https://example.com/script.js');
x.onload = function() {
    var s = document.createElement('script');
    s.textContent = x.responseText;
    (document.head || document.documentElement).appendChild(s);
};
x.onerror = function() {
    // Failed to load. Fallback to loading an (old version of your) script
    // that is bundled with your extension. It must be listed in the
    // "web_accessible_resources" section in your manifest file.
    var s = document.createElement('script');
    s.src = chrome.runtime.getURL('script.js');
    (document.head || document.documentElement).appendChild(s);
};
x.send();

此方法不需要'unsafe-inline' 指令,因为扩展注入的内联脚本会绕过内容安全策略 (ref)。

【讨论】:

  • 感谢您的来信!如果 script.js 出于版本控制的目的加载其他脚本怎么办? script.js 将包含最新的文件名(版本化)。 @Rob
  • @Kevin 更改您的设置以便只需要一个文件,例如使用 r.js 优化器(用于 AMD 项目),或者将每个依赖项与您的主脚本连接。
  • 您的建议非常有效。现在唯一的问题是,因为脚本是内联的,所以堆栈跟踪将 @ 显示为来源,而不是文件名。但这是一个单独的问题。
  • 在这里发布新问题:stackoverflow.com/questions/27553866/…
  • 我注意到这种方式的 GET 请求不会设置 cookie。对于我的用例,服务器实际上依赖 cookie 来返回正确的 js。是否有任何解决方法来包含 cookie? @Rob W
猜你喜欢
  • 2021-07-30
  • 2019-07-24
  • 2013-02-01
  • 2021-09-24
  • 2015-01-26
  • 1970-01-01
  • 2012-09-10
  • 2020-10-09
  • 2013-12-23
相关资源
最近更新 更多