W3C表示,在HTML5.1中有一个新的属性,叫做nonce,用于样式和脚本,可以被网站的内容安全策略使用。

我在谷歌上搜索了一下,但最终没有得到它,这个属性实际上是什么,使用它时有什么变化?


当前回答

nonce属性允许您将某些内联脚本和样式元素“白名单”,同时避免使用CSP不安全的内联指令(该指令将允许所有内联脚本和样式),因此您仍然保留了一般不允许内联脚本/样式的关键CSP特性。

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


Web基础内容安全策略文章“如果你绝对必须使用它”一节中有一个如何使用nonce属性的好例子,相当于以下步骤:

For each request your web server gets for a particular document, have your backend make a random base64-encoded string of at least 128 bits from a cryptographically secure random number generator; e.g., EDNnf03nceIOfn39fn3e9h3sdfa. That’s your nonce. Take the nonce generated in step 1, and for any inline script/style you want to “whitelist”, make your backend code insert a nonce attribute into the document before it’s sent over the wire, with that nonce as the value: <script nonce="EDNnf03nceIOfn39fn3e9h3sdfa">…</script> Take the nonce generated in step 1, prepend nonce-, and make your backend generate a CSP header with that among the values of the source list for script-src or style-src: Content-Security-Policy: script-src 'nonce-EDNnf03nceIOfn39fn3e9h3sdfa'

因此,使用nonce的机制可以替代让后端生成希望允许的内联脚本或样式的内容的散列,然后在CSP标头的适当源列表中指定该散列。


注意:浏览器不会(不能)检查服务器发送的nonce值是否在页面请求之间发生了变化;因此,这是可能的——尽管完全不可取——跳过上面的1,不让你的后端动态地为nonce做任何事情,在这种情况下,你可以把一个nonce属性和一个静态值放在你的doc的HTML源代码中,并发送一个静态CSP头与相同的nonce值。

但是你不希望以那种方式使用静态nonce的原因是,它几乎完全违背了使用nonce的整个目的——因为,如果你要像那样使用静态nonce,那么你可能只是在使用unsafe-inline。


至于哪些元素是“不可中断的”:CSP规范目前限制浏览器只检查脚本和样式元素的nonce。以下是规范细节:

In https://w3c.github.io/webappsec-csp/#match-element-to-source-list, see step 2:If type is "script" or "style", and § 6.6.3.1 Is element nonceable? returns "Nonceable"… At https://w3c.github.io/webappsec-csp/#is-element-nonceable, the Is element nonceable? algorithm itself doesn’t check just for script/style elements; but the only place the spec calls that from is the part cited above, which restricts it to script/style. So if you put a nonce on any other element, the spec requires browsers to ignore it.

其他回答

nonce属性允许您将某些内联脚本和样式元素“白名单”,同时避免使用CSP不安全的内联指令(该指令将允许所有内联脚本和样式),因此您仍然保留了一般不允许内联脚本/样式的关键CSP特性。

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


Web基础内容安全策略文章“如果你绝对必须使用它”一节中有一个如何使用nonce属性的好例子,相当于以下步骤:

For each request your web server gets for a particular document, have your backend make a random base64-encoded string of at least 128 bits from a cryptographically secure random number generator; e.g., EDNnf03nceIOfn39fn3e9h3sdfa. That’s your nonce. Take the nonce generated in step 1, and for any inline script/style you want to “whitelist”, make your backend code insert a nonce attribute into the document before it’s sent over the wire, with that nonce as the value: <script nonce="EDNnf03nceIOfn39fn3e9h3sdfa">…</script> Take the nonce generated in step 1, prepend nonce-, and make your backend generate a CSP header with that among the values of the source list for script-src or style-src: Content-Security-Policy: script-src 'nonce-EDNnf03nceIOfn39fn3e9h3sdfa'

因此,使用nonce的机制可以替代让后端生成希望允许的内联脚本或样式的内容的散列,然后在CSP标头的适当源列表中指定该散列。


注意:浏览器不会(不能)检查服务器发送的nonce值是否在页面请求之间发生了变化;因此,这是可能的——尽管完全不可取——跳过上面的1,不让你的后端动态地为nonce做任何事情,在这种情况下,你可以把一个nonce属性和一个静态值放在你的doc的HTML源代码中,并发送一个静态CSP头与相同的nonce值。

但是你不希望以那种方式使用静态nonce的原因是,它几乎完全违背了使用nonce的整个目的——因为,如果你要像那样使用静态nonce,那么你可能只是在使用unsafe-inline。


至于哪些元素是“不可中断的”:CSP规范目前限制浏览器只检查脚本和样式元素的nonce。以下是规范细节:

In https://w3c.github.io/webappsec-csp/#match-element-to-source-list, see step 2:If type is "script" or "style", and § 6.6.3.1 Is element nonceable? returns "Nonceable"… At https://w3c.github.io/webappsec-csp/#is-element-nonceable, the Is element nonceable? algorithm itself doesn’t check just for script/style elements; but the only place the spec calls that from is the part cited above, which restricts it to script/style. So if you put a nonce on any other element, the spec requires browsers to ignore it.