HTML中的“nonce”属性在脚本和样式元素中有什么作用?

247

W3C 表示,在 HTML5.1 中有一个名为 nonce 的新属性,用于 stylescript,可以被网站的内容安全策略使用。

我搜索了一下,但最终没有明白这个属性实际上是做什么的,使用它会有什么变化?


5
似乎这只是为您的网站提供额外的安全措施,您可以将其添加到链接或表单中。当页面被请求时,如果这个随机数(nonce)与您的不匹配,则不会提供该页面。请注意,本文不包含解释性内容。 - Pete
@Pete 你的意思是没有人能够加载你的 scriptstyle 吗?就像禁止热链接一样? - ata
它也适用于普通页面和表单验证。 - Pete
1个回答

338

nonce 属性允许您“白名单”某些内联的 scriptstyle 元素,同时避免使用 CSP 的 unsafe-inline 指令(这将允许所有内联的 scriptstyle),因此您仍然保留了 CSP 不允许一般内联 script/style 的关键特性。

因此,nonce 属性是告诉浏览器特定脚本或样式元素的内联内容不是由某个(恶意的)第三方注入到文档中的,而是由控制文档所服务的服务器的人有意放置在文档中的一种方式。


Web Fundamentals 内容安全策略 文章的 如果你非常需要使用它 部分有一个很好的示例,展示了如何使用 nonce 属性,具体步骤如下:

对于每个请求您的Web服务器获取特定文件,让后端从加密安全随机数生成器中制作至少128位的随机base64编码字符串;例如:EDNnf03nceIOfn39fn3e9h3sdfa。这是您的nonce。
使用第1步生成的nonce,并为任何要“白名单”内联script/style,使您的后端代码在将文档发送到网络之前插入一个nonce属性,其值为该nonce:
 <script nonce="EDNnf03nceIOfn39fn3e9h3sdfa">…</script>

使用第1步生成的nonce,添加nonce-前缀,然后让您的后端生成CSP标题,并将其作为script-srcstyle-src源列表的值之一:
Content-Security-Policy: script-src 'nonce-EDNnf03nceIOfn39fn3e9h3sdfa'

因此,使用一次性数字的机制是一种替代方法,而不是让您的后端生成内联scriptstyle内容的哈希值,然后在CSP头中指定该哈希值的适当源列表。


注意:浏览器不能检查服务器发送的nonce值是否在页面请求之间实际更改;因此,可以跳过步骤1而不使您的后端动态执行nonce,尽管这是完全不可取的。在这种情况下,您可以将带有静态值的nonce属性放入文档的HTML源中,并使用相同的nonce值发送静态CSP标头。
但是,您不想以那种方式使用静态nonce的原因是,这几乎会完全破坏使用nonce的整个目的-因为如果您像那样使用静态nonce,那么此时您可能就像使用unsafe-inline一样。

就“可使用nonce的元素”而言:CSP规范目前限制浏览器仅对scriptstyle元素检查nonce。以下是规范的详细信息:


35
它并不是用于验证用户身份 - 它是用于验证特定脚本或样式元素的内联内容是否被某个(恶意的)第三方注入到文档中,而是由控制文档所在服务器的人有意放入文档中。 (我将更新我的答案以说明这一点。) - sideshowbarker
5
nonce值无需存储,而是在内存中生成,并插入到CSP头部和HTML文档中,随响应一起通过网络发送(不存储在服务器文件系统/数据库中)。 - sideshowbarker
5
@sideshowbarker,空的nonce有什么作用?我看到一些页面上有<script type="text/javascript" nonce><style type="text/css" nonce> - Pacerier
13
注意:如果你的脚本是静态的,我建议使用CSP哈希而不是随机数。 - Brian
7
如果有人“在中间”成功向您的页面注入内联脚本,那么他们在其中加入一个nonce并改变CSP标头的难度有多大? - Nicolas Hoizey
显示剩余15条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接