我做错了什么还是这个错误?
使用时
var checkSum = crypto.createHash("sha256").update(scriptInnerHTML, "utf-8").digest("base64")
为此脚本标记生成sha256:
<script>
console.warn("works");
var some code ...
</script>
在Content-Security-Policy中使用它,如下所示:
<meta http-equiv="Content-Security-Policy" content="script-src 'sha256-8O+YTKIDgMhMvSanTZx1Om5XY2ERB+kIxN8AcO2r6Ok='">
事情可以正常运作,但是除了没有警告日志之外,这个相同,不起作用。注意代码之前的几行新行和一个标签。
<script>
var some code ...
</script>
如果之后有文本,Node似乎会以不同方式解释制表符(或更确切地说是换行符+制表符)。怪异!
在Safari和Chrome中都进行了测试,因此不应该是浏览器问题。
更新: 我当然会为每个输入重新生成哈希值。
示例:
(脚本标签位于底部)
工作哈希('sha256-5 ++ 3ItSu + 9maCZiuuXH60RG7EugmibMmhxhwpsynAn0 ='):http://aggressive.se/test/works.html
不工作哈希('sha256-hIRDHGUSaEmjNiVhNabY + 8l4GNQdj / PXD4XHA21gdRM ='):http://aggressive.se/test/fail.html
解决: 问题是由于JSDom中的serialize()函数,我用它来生成节点中的HTML。在计算哈希值之后调用dom.serialize(),它删除了一个不必要的选项卡,它改变了源代码(以一种难以注意的方式)。
但是你知道,问题不在于节点和加密模块。 (希望有人为此使用)
答案 0 :(得分:1)
我不确定你是如何获得scriptInnerHTML
变量的,但是如果我在innerHTML
示例中访问感兴趣的脚本的fail.html
属性,我会得到这个hexdump:
00000000 0a 0a 0a 09 76 61 72 20 6c 61 79 6f 75 74 20 3d |....var layout =|
00000010 20 6e 65 77 20 41 67 67 72 65 73 73 69 76 65 4c | new AggressiveL|
00000020 61 79 6f 75 74 28 29 3b 0a 09 41 67 67 72 65 73 |ayout();..Aggres|
00000030 73 69 76 65 4c 61 79 6f 75 74 2e 70 72 6f 74 6f |siveLayout.proto|
00000040 74 79 70 65 2e 73 65 74 75 70 46 75 6e 63 74 69 |type.setupFuncti|
00000050 6f 6e 20 3d 20 66 75 6e 63 74 69 6f 6e 28 29 0a |on = function().|
00000060 09 7b 0a 09 09 76 61 72 20 65 6c 65 6d 65 6e 74 |.{...var element|
00000070 20 3d 20 64 6f 63 75 6d 65 6e 74 2e 63 72 65 61 | = document.crea|
00000080 74 65 45 6c 65 6d 65 6e 74 28 22 64 69 76 22 29 |teElement("div")|
00000090 3b 0a 09 09 65 6c 65 6d 65 6e 74 2e 69 6e 6e 65 |;...element.inne|
000000a0 72 48 54 4d 4c 20 3d 20 22 49 74 20 77 6f 72 6b |rHTML = "It work|
000000b0 73 22 3b 0a 09 09 74 68 69 73 2e 65 6c 65 6d 65 |s";...this.eleme|
000000c0 6e 74 73 2e 72 6f 6f 74 45 6c 65 6d 65 6e 74 2e |nts.rootElement.|
000000d0 61 70 70 65 6e 64 43 68 69 6c 64 28 65 6c 65 6d |appendChild(elem|
000000e0 65 6e 74 29 0a 09 7d 0a |ent)..}.|
其对应的哈希是bR9Os+NBLWNZ3/wFVRhBilP05u9OeSj0ABRo+T8QF+g=
。如果我在html文件中使用此哈希,它似乎工作...
JSDOM
的示例:
const fs = require('fs');
const crypto = require('crypto');
const { JSDOM } = require('jsdom');
const dom = new JSDOM(fs.readFileSync('./fail.html'));
const data = dom.window.document.querySelector('head > script:last-child').innerHTML;
console.log(crypto.createHash('sha256').update(data, 'utf-8').digest('base64'));
//bR9Os+NBLWNZ3/wFVRhBilP05u9OeSj0ABRo+T8QF+g=