javascript - 具有“严格动态”的外部脚本哈希需要脚本标签上的“完整性”属性?
问题描述
我正在研究网站的Content Security Policy,特别是strict-dynamic
关键字。
我的测试站点有两个文件:
索引.html:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1,user-scalable=yes" />
<meta charset="UTF-8" />
<title>csp-test</title>
</head>
<body>
<h1>csp-test</h1>
<script src="./index.js"></script>
</body>
</html>
index.js:
console.log('foo');
我正在研究使用基于哈希的方法来允许脚本。
这是我在节点脚本中生成哈希的方式:
const input = fs.readFileSync("/path/to/index.js");
crypto.createHash("sha256").update(input, 'utf8').digest('base64')
这是结果index.js
:1kOLrDKT3TBiHLcnxiGsc7HF/lyVJKLhoZDSn0UwCfo=
使用此哈希,我将 CSP 配置更新为:
default-src 'self'; script-src 'self' 'strict-dynamic' 'sha256-1kOLrDKT3TBiHLcnxiGsc7HF/lyVJKLhoZDSn0UwCfo=' 'unsafe-inline'; object-src 'none'; base-uri 'self'
当我将此值作为具有此名称的响应标头(使用 ModHeader Chrome 扩展名)时,Content-Security-Policy-Report-Only
我仍然在控制台中收到错误消息:
[Report Only] Refused to load the script 'http://localhost:5000/index.js' because it violates the following Content Security Policy directive: "script-src 'self' 'strict-dynamic' 'sha256-1kOLrDKT3TBiHLcnxiGsc7HF/lyVJKLhoZDSn0UwCfo=' 'unsafe-inline'". 'strict-dynamic' is present, so host-based allowlisting is disabled. Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.
我可以通过integrity
在我的脚本标签上设置属性来消除这个错误:
<script integrity="sha256-1kOLrDKT3TBiHLcnxiGsc7HF/lyVJKLhoZDSn0UwCfo=" src="./index.js"></script>
我的问题是:为什么我需要添加integrity
属性?
我没有在文档中看到它,需要添加这个属性会使我们的构建过程更加复杂。是否需要指定此属性的替代方法?
解决方案
为什么我需要添加完整性属性?我没有在文档中看到它,需要添加这个属性会使我们的构建过程更加复杂。
MDN 仅包含解释 CSP 工作原理的常见内容。所有细节都在CSP 规范
中'hash-value'
令牌的使用假定外部脚本已经具有该integrity=
属性(来自第三方 CDN 的脚本)。'nonce-value'
对于自己的脚本,使用令牌更容易。
此外,Firefox不支持允许外部脚本的“哈希值”,仅允许内部脚本。Safari -也是。
是否需要指定此属性的替代方法?
没办法,很遗憾。只有内置脚本<script>...</script>
不需要attr,并且如果它们的哈希包含在指令integrity=
中,则会自动允许。script-src
我正在研究网站的内容安全策略,特别是严格动态关键字。
小心,Safari 仍然不支持 'strict-dynamic'
.
这是我在节点脚本中生成哈希的方式:
常量输入 = `fs.readFileSync("/path/to/index.js");
crypto.createHash("sha256").update(input, 'utf8').digest('base64')
外部脚本的内容在散列之前不需要转换为 UTF8,只需对内联脚本进行转码。
此外,CSP 规范要求所有 ' - ' 字符替换为 ' + ',并且所有 ' _ ' 字符替换为 ' / ' 在哈希值中。然后添加“sha256-”前缀。
推荐阅读
- php - 多个 Wordpress 在一页中循环,产生相同的数据
- unity3d - 是否有将 SVG 导入 Unity android 游戏的免费方法?
- linux - 如何根据文本文件将文件移动到子目录
- jquery - jQuery模糊代码影响整个块
- android - 导航找不到 xml 菜单
- shiny - shinyTree:超过 3 个层级
- node.js - 如何添加数据以自动将数据添加到每个 Express res.render 调用?
- typescript - Array 和 Object 类型的 Typescript 联合
- extjs - 一些按钮后面的奇怪边框[EXTJS 6.5.2]
- azure - Azure 自动化 - 续订 RunAsAccount 证书