筛选项

实现内容安全协议(CSP)

背景

Branch 非常重视客户的隐私和安全。以下文档提供了一些建议,以使我们的客户能够与 Branch webSDK 一起在其网站中实现内容安全策略(CSP)。

CSP 如何操作

内容安全策略(CSP)是一种计算机安全标准,为跨站点脚本(XSS),clickjacking 以及依赖于在可信网页上下文中执行恶意内容的其他代码注入攻击提供了额外的保护。通过在 HTTP 响应 header 中使用合适的 CSP 指令,您可以有选择地指定 Web 应用中应允许使用哪些数据源。

在服务器端的 HTTP 响应 header 中添加CSP

任何服务器端编程环境都应允许您发送回自定义 HTTP 响应 header。以下是向 Apache Web 服务器添加 CSP header 的示例

已添加到 httpd.conf 或 .htaccess文件,这将设置一个默认策略,仅允许源内容。

Header set Content-Security-Policy "default-src 'self';"

Please refer to https://content-security-policy.com/ for different servers configuration.

Add CSP through <meta> tag under HTML Page

CSP directive could be added on page level by using <meta> tag. Here is an example to add a CSP policy in your HTML page

<meta http-equiv="Content-Security-Policy" content="default-src 'self'">

两种方法都在网络中被广泛采用。如果您的网站是单页应用,或者您只想将 CSP 应用于特定页面,则通过 <meta> header 添加 CSP 可能是一个更好的选择,因为它易于实现和更改。

与 CSP 政策结合集成 Branch Web SDK

对于在其网站上实现了 CSP 政策或计划在集成 Branch webSDK 时添加 CSP 政策的客户,我们建议以下一些选项和建议。

将与 Branch 相关的代码包装到本地 javascript 文件中

If customers want to wrap and store the branch related JavaScript codes into a javascript file under the server where the website is hosted, they could use the script-src 'self' policy as ‘self’ matches the current origin and JavaScript files loaded from the same origin will be allowed..

Content-Security-Policy: script-src 'self' https://cdn.branch.io https://app.link;

Here is an example about adding a proper CSP policy with <meta> tag when integrating Branch webSDK using local javascript files. In the following script, the branch.js file is stored locally and &lt;meta http-equiv="Content-Security-Policy" content="script-src 'self' https://cdn.branch.io https://app.link> defines the CSP policy.

<!doctype html>
<html><head>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="Content-Security-Policy" content="script-src 'self' https://cdn.branch.io https://app.link">
  <title>Branch Demo</title>
  <script src="branch.js"></script>
</head><body>Branch Journey Demo</body>
</html>

使用 in-line Branch javascript 代码

Some customers prefer to use inline javascript code when integrating with branchWebSDK. For example, our demo page https://cdn.branch.io/example.html is using the inline script when calling functions defined in branchWebSDK.

有两种广泛使用的选项,使用哈希随机数允许使用 CSP 策略时安全地执行 inline javascript 代码

选项1:使用 CSP 哈希策略实现 inline 脚本安全

使用哈希是允许在内容安全策略中执行 inline 脚本的一种方法。这只是一个白名单,当浏览器看到原始脚本块时,它将对其进行哈希处理,将其与 CSP 进行比较,然后在匹配时运行它。基本上,客户端对 inline javascript 代码进行哈希处理并获取 SHA256 哈希值,并将其添加到 CSP 策略下

Content-Security-Policy: script-src 'sha256-Ci5HNPYwBSR4VHU9hJh95ZFVy6fOb+k1oj6ZuaHln/g=' https://cdn.branch.io https://app.link;

这是使用 inline Javascript 时使用 CSP 哈希的示例

https://codepen.io/BranchWebSDK/pen/RwRqLmv

在代码中,我们通过 <meta> 标签定义 CSP 哈希

…..
<meta http-equiv="Content-Security-Policy" content="script-src  'sha256-Ci5HNPYwBSR4VHU9hJh95ZFVy6fOb+k1oj6ZuaHln/g=' https://cdn.branch.io https://app.link">
  <title>BranchWebSDK Demo</title>
  <script>
    // load Branch
(function(b,r,a,n,c,h,_,s,d,k){if(!b[n]||!b[n]._q){for(;s<_.length;)c(h,_[s++]);d=r.createElement(a);d.async=1;d.src="https://cdn.branch.io/branch-latest.min.js";
……
</script>

SHA256 哈希是基于 inline JavaScript 代码生成的。生成它的最简单方法是只打开浏览器的开发人员工具控制台,它将在控制台错误消息中输出脚本的预期哈希值。以下是浏览器控制台如何为您生成 CSP 哈希的屏幕截图。

2418

选项2:使用 CSP 随机数策略实现 inline 脚本安全

使用哈希的最大挑战是,在更改脚本时必须重新生成哈希。这意味着,如果您的 inline JavaScript 代码是动态的,则此哈希方法对您将无用。CSP nonce 提供了另一种处理方式。

随机数是模拟随机版本的 “number used once”。随机数可让您将整个脚本块列入白名单,而不用像哈希表那样将精确的脚本块列入白名单。

Content-Security-Policy: script-src 'nonce-4AEemGb0xJptoIGFP3Nd' https://cdn.branch.io https://app.link;

Here is an example of https://codepen.io/BranchWebSDK/pen/LYZBqao using nonce in CSP policy. In the codes, It consists of both a <meta> header with CSP policy defined and an attribute on the script tag

<head>
  <meta http-equiv="Content-Security-Policy" content="script-src  'nonce-4AEemGb0xJptoIGFP3Nd' https://cdn.branch.io https://app.link">
  <title>BranchWebSDK Demo</title>
  <script nonce="4AEemGb0xJptoIGFP3Nd">
    // load Branch
(function(b,r,a,n,c,h,_,s,d,k){if(!b[n]||!b[n]._q){for(;s<_.length;)c(h,_[s++]);d=r.createElement(a);d.async=1;d.src="https://cdn.branch.io/branch-latest.min.js";k=r.getElementsByTagName(a)[0];k.parentNode.insertBefore(d,k);b[n]=h}})(window,document,"script","branch",function(b,r)
……
 </script>

📘

注意

The nonce should be generated per request, and it should be random.

In the above provided example, we explicitly added script-src because some javascript files are loaded from these two domains when executing the branch webSDK