Chrome扩展开发 内容安全策略Content Security Policy (CSP) 官方原文部分翻译.

Content Security Policy (CSP)

内容安全策略

Inorder to mitigate a large class of potential cross-site scripting issues,Chrome's extension system has incorporated the general concept of Content SecurityPolicy (CSP) .This introduces some fairly strict policies that will make extensions moresecure by default, and provides you with the ability to create and enforcerules governing the types of content that can be loaded and executed by yourextensions and applications.

Ingeneral, CSP works as a black/whitelisting mechanism for resources loaded orexecuted by your extensions.Defininga reasonable policy for your extension enables you to carefully consider theresources that your extension requires, and to ask the browser to ensure thatthose are the only resources your extension has access to. These policiesprovide security over and above the host permissions your extension requests;they're an additional layer of protection, not a replacement.

Onthe web, such a policy is defined via an HTTP header or meta element.Inside Chrome's extension system, neither is an appropriate mechanism. Instead, an extension's policy is definedvia the extension'smanifest.json fileas follows:

为了降低潜在XSS攻击,Chrome拓展体系纳入了内容安全策略的一般概念。这(内容安全策略)引入一些相当严苛的策略,在默认设置下,这些策略将使得拓展更加安全。并且,内容安全策略也允许给开发者定义和遵守规则,来管理其应用、拓展需要加载或执行的不同类型的内容。总的来讲,CSP通过白名单、黑名单的工作机制为拓展加载资源或执行脚本。为拓展定义合理规则能够促使开发者考虑资源的必要性,并且要求浏览器确保拓展引用资源的唯一性。这些策略不能替代拓展的主机权限保护,其提供的安全性在拓展主机权限之上的,依附于主机权限。对于web应用,这样的策略通过HTTP headermeta元素定义。而在Chrome 拓展系统中,两者都不是合适的策略。相反,拓展策略由其manifest.json文件来定义,如下:

 

{

  ...,

  "content_security_policy": "[POLICY STRING GOES HERE]"

  ...

}

Forfull details regarding CSP's syntax, please take a look at the Content Security Policy specification , and the "An Introduction to Content Security Policy" article on HTML5Rocks.

有关CSP语法的完整详细信息,请参阅内容安全策略规范(the Content Security Policy specification )和HTML5Rocks的“内容安全策略简介”( "An Introduction to Content Security Policy" )一文。

 

Default Policy Restrictions

默认策略限制

Packagesthat do not define a manifest_version have no defaultcontent security policy. Those that selectmanifest_version 2, have a default content security policy of:

没有明确manifest_version的拓展没有默认内容安全策略。对于设置manifest_version2的,其默认安全策略如下:

script-src 'self'; object-src 'self'

This policy adds security by limitingextensions and applications in three ways:

这种策略从三个方面限制拓展和应用来提高安全性。

 

Eval and related functions are disabled

禁止eval和相关功能

Code like the following does notwork:

alert(eval("foo.bar.baz"));

window.setTimeout("alert('hi')", 10);

window.setInterval("alert('hi')", 10);

new Function("return foo.bar.baz");

Evaluating strings of JavaScript likethis is a common XSS attack vector. Instead, you should write code like:

alert(foo && foo.bar && foo.bar.baz);

window.setTimeout(function() { alert('hi'); }, 10);

window.setInterval(function() { alert('hi'); }, 10);

function() { return foo && foo.bar && foo.bar.baz };

Inline JavaScript will not be executed

内联JavaScript不会被执行

InlineJavaScript will not be executed. This restriction bans both inline <script> blocks and inlineevent handlers (e.g. <buttonοnclick="...">).

Thefirst restriction wipes out a huge class of cross-site scripting attacks bymaking it impossible for you to accidentally execute script provided by amalicious third-party. It does, however, require you to write your code with aclean separation between content and behavior (which you should of course doanyway, right?). An example might make this clearer. You might try to writea Browser Action's popup as a single popup.htmlcontaining:

 

<!doctype html>

<html>

  <head>

    <title>MyAwesome Popup!</title>

    <script>

      functionawesome() {

        // do something awesome!

      }

 

      functiontotallyAwesome() {

        // do something TOTALLY awesome!

      }

 

      functionclickHandler(element) {

        setTimeout("awesome();totallyAwesome()", 1000);

      }

 

      function main() {

        // Initialization work goes here.

      }

    </script>

  </head>

  <body onload="main();">

    <button onclick="clickHandler(this)">

      Click forawesomeness!

    </button>

  </body>

</html>

Three things will need to change inorder to make this work the way you expect it to:

·        The clickHandler definitionneeds to move into an external JavaScript file (popup.js wouldbe a good target).

·        Theinline event handler definitions must be rewritten in terms of addEventListener and extracted into popup.js.

Ifyou're currently kicking off your program's execution via code like <body οnlοad="main();">, consider replacing it by hookinginto the document's DOMContentLoaded event, or the window's load event,depending on your needs. Below we'll use the former, as it generally triggersmore quickly.

·        The setTimeout callwill need to be rewritten to avoid converting the string "awesome(); totallyAwesome()" into JavaScript for execution.

Those changes might look somethinglike the following:

functionawesome() {

  // Do something awesome!

}

 

functiontotallyAwesome() {

  // do something TOTALLY awesome!

}

 

functionawesomeTask() {

  awesome();

  totallyAwesome();

}

 

functionclickHandler(e) {

  setTimeout(awesomeTask, 1000);

}

 

function main() {

  // Initialization work goes here.

}

 

// Add event listeners once the DOM has fully loaded bylistening for the

// `DOMContentLoaded` event on the document, and adding yourlisteners to

// specific elements when it triggers.

document.addEventListener('DOMContentLoaded', function () {

  document.querySelector('button').addEventListener('click', clickHandler);

  main();

});

<!doctype html>

<html>

  <head>

    <title>MyAwesome Popup!</title>

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

  </head>

  <body>

    <button>Clickfor awesomeness!</button>

  </body>

</html>

Only local script and and object resources are loaded

Script and object resources can onlybe loaded from the extension's package, not from the web at large. This ensuresthat your extension only executes the code you've specifically approved,preventing an active network attacker from maliciously redirecting your requestfor a resource.

Instead of writing code that dependson jQuery (or any other library) loading from an external CDN, considerincluding the specific version of jQuery in your extension package. That is,instead of:

<!doctype html>

<html>

  <head>

    <title>MyAwesome Popup!</title>

    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>

  </head>

  <body>

    <button>Clickfor awesomeness!</button>

  </body>

</html>

Download the file, include it in yourpackage, and write:

<!doctype html>

<html>

  <head>

    <title>MyAwesome Popup!</title>

    <script src="jquery.min.js"></script>

  </head>

  <body>

    <button>Clickfor awesomeness!</button>

  </body>

</html>

Relaxing the default policy

放宽默认策略

Inline Script

Upuntil Chrome 45, there was no mechanism for relaxing the restriction againstexecuting inline JavaScript. In particular, setting a script policy thatincludes 'unsafe-inline' will have no effect.

Asof Chrome 46, inline scripts can be whitelisted by specifying the base64-encodedhash of the source code in the policy. This hash must be prefixed by the usedhash algorithm (sha256, sha384 or sha512). See Hash usage for <script> elements for an example.

Remote Script

远程脚本

Ifyou have a need for some external JavaScript or object resources, you can relaxthe policy to a limited extent by whitelisting secure origins from whichscripts should be accepted. We want to ensure that executable resources loadedwith an extension's elevated permissions are exactly the resources you expect,and haven't been replaced by an active network attacker. As man-in-the-middle attacks are both trivial andundetectable over HTTP, those origins will not be accepted.

如果您需要一些外部JavaScript或对象资源,则可以通过将可接受脚本的安全源列入白名单来在一定程度上放宽策略。我们希望确保加载了扩展提升的权限的可执行资源正是您期望的资源,并且没有被活动的网络攻击者替代。由于中间人攻击通过HTTP是琐碎的和不可检测的,所以这些源不会被接受。

Currently,we allow whitelisting origins with the following schemes: blobfilesystemhttpschrome-extension, and chrome-extension-resource. The host part of the origin mustexplicitly be specified for thehttps and chrome-extension schemes. Generic wildcards such as https:https://* and https://*.comarenot allowed; subdomain wildcards such as https://*.example.com are allowed. Domains in the Public Suffix list are also viewed as generic top-level domains. To load aresource from these domains, the subdomain must explicitly be listed.

目前,我们允许使用以下方案列入白名单来源:blobfilesystemhttpschrome-extension,  chrome-extension-resource。这些源的主体部分必须明确指定为httpchrome-extension方案。必须为httpschrome-extension明确指定源的主体部分。不允许使用通用通配符(例如https:, https:// *https://*.com; 允许子域通配符(例如https://*.example.com)。公共后缀列表中的域也被视为通用顶级域。要从这些域加载资源,必须显式列出子域。

Forexample, https://*.cloudfront.net is invalid, buthttps://XXXX.cloudfront.net and https://*.XXXX.cloudfront.net can be whitelisted.

Toease development, we're also allowing the whitelisting of resources loaded overHTTP from servers on your local machine. You may whitelist script and objectsources on any port of either http://127.0.0.1 orhttp://localhost.

例如,https://*.cloudfront.net无效,但https://xxXX.cloudfront.nethttps://*.XXXX.cloudfront.net可以列入白名单。为了便于开发,允许以HTTP加载在开发者本地服务器上的资源列入白名单。可以将http://127.0.0.1 orhttp://localhost任意端口下的脚本和对象列入白名单。

Therestriction against resources loaded over HTTP applies only to those resourceswhich are directly executed. You're still free, for example, to makeXMLHTTPRequest connections to any origin you like; the default policy doesn'trestrict connect-src or any of the other CSP directives in any way.

 

Arelaxed policy definition which allows script resources to be loaded from example.com overHTTPS might look like:

"content_security_policy": "script-src 'self' https://example.com; object-src'self'"

Notethat both script-src and object-src aredefined by the policy. Chrome will not accept a policy that doesn't limit eachof these values to (at least) 'self'.

Makinguse of Google Analytics is the canonical example for this sort of policydefinition. It's common enough that we've provided an Analytics boilerplate ofsorts in the Event Tracking with Google Analytics sample extension, and a brief tutorial that goes into more detail.

Evaluated JavaScript

Thepolicy against eval() and its relatives like setTimeout(String)setInterval(String), and new Function(String) can be relaxed by adding 'unsafe-eval' toyour policy:

"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src'self'"

However, we strongly recommendagainst doing this. These functions are notorious XSS attack vectors.

Tightening the default policy

Youmay, of course, tighten this policy to whatever extent your extension allows inorder to increase security at the expense of convenience. To specify that yourextension can only load resources of any type (images, etc)from its own package, for example, a policy of default-src 'self' would be appropriate. The Mappysample extension is a good example ofan extension that's been locked down above and beyond the defaults.

Content Scripts

Thepolicy that we have been discussing applies to the background pages and event pages of the extension. How they apply to the content scripts of the extension is more complicated.

Contentscripts are generally not subject to the CSP of the extension. Since contentscripts are not HTML, the main impact of this is that they may use eval evenif the extension's CSP does not specify unsafe-eval,although this is not recommended. Additionally, the CSP of the page doesnot apply to content scripts. More complicated are <script> tagsthat content scripts create and put into the DOM of the page they are runningon. We will refer to these as DOM injected scripts going forward.

DOM injected scripts that would beexecuted immediately upon injection into the page will execute as you mightexpect. Imagine a content script with the following code as a simple example:

    document.write("<script>alert(1);</script>");

 

Thiscontent script will cause an alert immediately upon the document.write(). Note that this will execute regardless of the policy a pagemay specify.

However,the behavior becomes more complicated both inside that DOM injected script andfor any script that does not immediately execute upon injection. Imagine thatour extension is running on a page that provides its own CSP thatspecifies script-src'self'. Now imagine the content scriptexecutes the following code:

    document.write("<buttonοnclick='alert(1);'>click me</button>'");

 

Ifa user clicks on that button, the onclick scriptwill not execute. This is because the script did not immediatelyexecute and code not interpreted until the click event occurs is not consideredpart of the content script, so the CSP of the page (not of theextension) restricts its behavior. And since that CSP does not specifyunsafe-inline,the inline event handler is blocked.

Thecorrect way to implement the desired behavior in this case would be to addthe onclick handler as a function from the content script asfollows:

    document.write("<buttonid='mybutton'>click me</button>'");

    varbutton = document.getElementById('mybutton');

    button.onclick = function() {

      alert(1);

    };

 

Another similar issue arises if thecontent script executes the following:

    varscript = document.createElement('script');

    script.innerHTML = 'alert(1);'

    document.getElementById('body').appendChild(script);

 

Inthis case, the script will execute and the alert will pop up.However, take this case:

    varscript = document.createElement('script');

    script.innerHTML = 'eval("alert(1);")';

    document.getElementById('body').appendChild(script);

 

Whilethe initial script will execute, the call to eval willbe blocked. That is, while the initial script execution is allowed, thebehavior within the script will be regulated by the page's CSP.

Thus,depending on how you write DOM injected scripts in your extension, changes tothe page's CSP may affect the behavior of your extension. Since content scriptsare not affected by the page's CSP, this a great reason to putas much behavior as possible of your extension into the content script ratherthan DOM injected scripts.

Content available under the CC-By3.0 license

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

horo99

求个赞啦

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值