What’s the purpose of the HTML “nonce” attribute for script and style elements?
W3C说HTML5.1中有一个新的属性,叫做nonce,用于style和script,可以被网站的内容安全策略使用。
我在google上搜索了一下,但最后还是没有得到它,这个属性实际上做了什么,在使用它时会发生什么变化?
- 看起来这对你的站点来说只是一个额外的安全措施,你把它添加到一个链接或表单中,当页面被服务时,如果这个nonce与你的不匹配,那么你就不服务于页面了。
- @皮特,你是说没人能装你的script和style?像hotlink禁令?
- 它也适用于普通页面和表单验证
nonce属性使您能够"白名单"某些内联script和style元素,同时避免使用csp unsafe-inline指令(这将允许所有内联script和style指令),因此您仍然保留一般不允许内联script和style的关键csp功能。
因此,nonce属性是一种告诉浏览器特定脚本或样式元素的内联内容不是由某些(恶意)第三方注入到文档中,而是由控制文档的服务器的人故意放入文档中的方法。
https://developers.google.com/web/fundamentals/security/csp/如果您必须使用,它提供了一个很好的示例,说明如何使用nonce属性,具体步骤如下:
对于您的Web服务器收到的针对特定文档的每个请求,让您的后端从加密安全的随机数生成器(如EDNnf03nceIOfn39fn3e9h3sdfa)生成一个包含至少128位数据的随机base64编码字符串。那是你的现在。
以步骤1中生成的nonce为例,对于任何要"白名单"的内联script/style,使后端代码在通过线发送之前在文档中插入nonce属性,该nonce作为值:
1
| <script nonce="EDNnf03nceIOfn39fn3e9h3sdfa">… |
使用步骤1中生成的nonce,将nonce-预先发送给它,并使您的后端生成一个csp头,其中包含script-src或style-src的源列表值:
1
| Content-Security-Policy: script-src 'nonce-EDNnf03nceIOfn39fn3e9h3sdfa' |
因此,使用nonce的机制是一种替代方法,而不是让您的后端生成您希望允许的内联script或style的内容散列,然后在CSP头中的相应源列表中指定散列。
请注意,由于浏览器不能(不能)检查在页面请求之间发送的nonce值是否发生了变化,因此尽管完全不建议跳过上面的1,而不允许后端为nonce动态地执行任何操作,在这种情况下,您可以将带有静态值的nonce属性放入文档的HTML源代码中,并发送一个具有相同nonce值的静态csp头。
但是你不想这样使用静态nonce的原因是,它在很大程度上破坏了使用静态nonce的全部目的,因为如果你要使用这样的静态nonce,那么在那一点上,你也可以只使用unsafe-inline。
- 那么nonce用于验证用户?style需要什么验证?
- 这不是为了验证用户,而是为了验证特定脚本或样式元素的内联内容是否没有被注入到文档my some(恶意)第三方中,而是被控制文档的服务器的人故意放入文档中。(我会更新我的答案来回答这个问题。)
- 还有一件事,假设一个站点有相当大的流量,所以会创建和存储数千个nonce。它肯定会降低服务器性能。如果这个站点没有从用户那里接收到重要的数据,比如密码或银行帐户,那么有没有理由进行这种努力并使用这个属性?
- 这些nonce不需要被存储,而是在内存中生成,并插入到csp头文件和通过线发送的html文档中(而不是发送到存储在服务器文件系统/数据库中的源文件)。
- 至于使用nonce属性的任何原因,如果您完全不需要使用它,那么就不要使用它。它实际上只适用于某些情况,因为某些原因,您无法(还)从特定文档中删除某些内联脚本或样式内容(但应该稍后删除)。因此,如果出于某种原因,您需要保留内联脚本和样式内容,那么您至少可以使用nonce机制让浏览器验证它们是否正常。否则,您应该按照实际需要完全使用CSP,而不允许任何内联脚本或样式元素。
- @Sideshowbarker,一个空荡荡的人做什么?我在看与和
的页面。
- @在这些情况下,您在内容安全策略响应头或这些页面的元素中看到什么nonce-*值(如果有)?无论如何,空的nonce属性除了总是使任何csp nonce检查失败之外没有任何作用,因为根据csp规范的要求,csp策略中的任何nonce-*值都必须非空。请参见w3c.github.io/webappsec csp/将nonce与源列表匹配。所以我猜你看到的那些空的nonce属性只是后端在服务页面之前无法填充值的情况。
- 注意:如果脚本是静态的,我建议使用csp哈希,而不是nonce。
- 如果有人"中间"设法在您的页面中插入一个内联脚本,那么他们在其中插入一个nonce并更改CSP头有多困难?
- @尼古拉索伊,你的问题没有一般性的答案,但这可能要困难得多。通过存储/反射的XSS攻击(相当常见的漏洞),可以将内联脚本注入页面。但您通常不能更改服务器从JS发送的头文件。要做到这一点,您必须在目标服务器上进行远程代码执行——好吧,如果是这样的话,情况已经非常糟糕了,没有什么能救您。
- 从最后一个问题中跳出来的另一个问题。黑客是否可以从服务器查看csp头中的nonce,并用与服务器匹配的nonce注入脚本?
- @dmikester1如果黑客可以访问服务器,他们可以使用网页做任何他们想做的事情。