CSP 中的 script hash 到底该怎么生成和使用?
我在给网站加 Content Security Policy,想用 hash 来允许内联脚本执行,但试了好几次浏览器还是报错说不被允许。我用的是 sha256-... 这种格式,但不确定是不是生成方式不对。
比如我有这段内联脚本:
<script>
console.log('hello');
</script>
我用 openssl 算了 hash:echo -n "console.log('hello');" | openssl dgst -sha256 -binary | openssl base64,然后加到 CSP 里,但控制台还是报错。到底哪里出问题了?
你那个openssl命令的问题在于:
1. 只hash了JS代码本身,没算上script标签里的空白字符
2. echo -n会把换行符吃掉,但浏览器实际计算时是包含换行的
正确的做法是:
重点是要用整个script标签内容(包括换行)作为输入源。比如你这个例子,实际应该算的是:
而不是只算JS里面那句console.log。顺便说一句,这种问题调试的时候可以直接看浏览器控制台报错信息,它会告诉你它期望收到什么hash值,你可以对比下和你生成的有啥不同。
如果还不行,可能是你的CSP格式写错了,正确的格式应该是:
大半夜配CSP确实容易暴躁,我懂...
标签里的完整内容,包括换行符和缩进。对于你的例子,正确的做法应该是计算这个字符串的hash:
注意最后的换行符!这才是浏览器实际解析的内容。你可以用这个命令重新计算:
MDN文档里其实有说明这点,但很多人都忽略了。推荐的做法是先用浏览器控制台的报错信息,它会告诉你它期望的hash值是什么,你可以先复制这个值来验证。
还有个小坑要注意:如果脚本里有unicode字符,不同平台的处理可能不一致。遇到这种情况建议直接用node的crypto模块来算更可靠。