0

我刚刚完成了 Codecademy 的 Javascript 课程。我试图制作一个显示此页面的 chrome 扩展。所以我研究了如何制作一个示例 chrome 扩展并创建了扩展(基本上复制粘贴了整个站点代码)。我收到此错误

Refused to load the script 'http://dota2.cyborgmatt.com/prizetracker/data/ti4.json?
callback=jQuery11020032285090535879135_1399794129146' because it violates the
following Content Security Policy directive: "script-src 'self' 
chrome-extension-resource:"

我尝试查看内容安全策略并添加了这一行

"content_security_policy": "script-src 'self' http://dota2.cyborgmatt.com/; 
object-src 'self'"

我不完全了解自己在做什么,但我尝试阅读各种内容但未能理解。有人帮忙。提前致谢。

4

2 回答 2

4

只获取执行此操作的页面代码的副本不是一个好主意。

考虑:您收到内容安全策略错误,因为您正尝试从远程服务器执行一段代码。虽然您可以放宽政策,但让我先解释一下为什么这是一个安全问题


目前,您的代码加载http://dota2.cyborgmatt.com/prizetracker/data/ti4.json执行其内容,而不验证它们是什么。现在它看起来像这样:

populatePrizePool({"dollars":3129676});

但是:这是一个您无法控制的网站

想象一下:您编写了您的扩展程序,它变得流行,网站管理员注意到异常流量,更改他们的代码以改为加载http://dota2.cyborgmatt.com/prizetracker/data/ti4_.json,并在谷歌搜索后将原始链接的内容替换为:

alert("By the way, Ramana Venkata is stealing our data. Sincerely, cyborgmatt.com");

突然,您的扩展程序不起作用,您有一群愤怒的用户,并且有点尴尬

你看到问题了吗?情况可能更糟,因为替换代码可能与 JS 允许的一样邪恶。由于 HTTP 流量很容易拦截,因此 cyborgmatt.com 管理员甚至不需要在您的扩展程序中注入任意代码,这就是为什么甚至不可能以这种方式放宽策略的原因。


现在,来解决问题。而不是 AJAX 加载代码,您应该只加载这个文件,解析它以获取 JSON 数据(即{"dollars":3129676}),安全地解析和验证该数据,然后才使用它。这样一来,如果发生上述情况,至少不会有什么坏事发生。

第一步:获取数据。

$.ajax用 XHR替换调用:

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
  if (xhr.readyState == 4) {
    parseAndValidate(xhr.responseText);
  }
};
xhr.open("GET", "http://dota2.cyborgmatt.com/prizetracker/data/ti4.json", true);
xhr.send();

第 2 步:解析和验证。

您有一个字符串,您希望其具有以下格式:populatePrizePool(SOME_JSON);,并且您希望 JSON 数据包含一个非负数dollars

function parseAndValidate(str){
  var some_json;

  // First, extract `SOME_JSON` with a regular expression:
  if(str.match(/populatePrizePool\((.*)\);/)) {
    some_json = str.match(/populatePrizePool\((.*)\);/)[1];
  } else {
    throw Error("Unexpected format for ti4.json");
  }

  // Second, _safely_ parse `some_json`:
  var data = JSON.parse(some_json); // Will throw an exception if something's not right

  // Third, ensure that the JSON has the required data:
  if( !data.dollars || typeof data.dollars !== "number" || data.dollars < 0) {
    throw Error("Unexpected data format for ti4.json");
  }

  // Finally, call the function:
  populatePrizePool(data);
}

对于您的小项目来说,这可能有点矫枉过正,但这是一种学习体验。不要盲目相信你无法控制的数据,更不要相信你无法控制的代码。

于 2014-05-11T12:26:11.083 回答
1

根据文档,这仅适用于 HTTPS 资源,而不是 HTTP 资源:

如果您需要一些外部 JavaScript 或对象资源,您可以通过将应该接受的脚本的安全来源列入白名单来在有限程度上放宽政策。我们希望确保加载了扩展的提升权限的可执行资源正是您期望的资源,并且没有被活跃的网络攻击者替换。由于中间人攻击在 HTTP 上是微不足道且无法检测到的,因此这些来源将不被接受。目前,我们允许使用以下方案将来源列入白名单:HTTPS chrome-extension、 和chrome-extension-resource.

因此,以 开头http:的源绝对不能包含在扩展的script-srcCSP 指令中。

幸运的是,有问题的资源有一个 HTTPS 变体。在您的扩展程序代码中,更改以下行:

var baseURL = ( location.protocol == 'https:' ) ? 'https://dota2.cyborgmatt.com/' : 'http://dota2.cyborgmatt.com/';

对于无条件使用 HTTPS 的人:

var baseURL = 'https://dota2.cyborgmatt.com/';
于 2014-05-11T08:12:25.043 回答