我们正在努力创建严格的内容安全策略 (https://csp.withgoogle.com/docs/strict-csp.html),这需要 Apache 在每次请求资源时创建一个随机数,以便我们可以将此随机数插入到 http 标头中。
我们如何使用 Apache 2.4 创建随机数?
我读过的所有 CSP 相关文档都提到了“随机数只是服务器上生成的随机字符串,包含在 CSP 标头中......”,但没有找到任何有关如何使用 Apache 执行此操作。我们当然可以使用应用程序代码来执行此操作,但通过 Apache 执行此操作似乎是一个更干净的解决方案/将确保每个页面都获取 CSP 标头。
您需要在服务器上生成
nonce
,然后让 Apache 将其 nonce
传递到您可以使用它的脚本。
我们为 Apache 创建了一个开源模块,可以简化此过程:mod_cspnonce。
这是服务器端配置的一个简单示例:
LoadModule headers_module modules/mod_headers.so
LoadModule cspnonce_module modules/mod_cspnonce.so
# add the CSP_NONCE to the "default-src"
Header add Content-Security-Policy "default-src 'self' 'nonce-%{CSP_NONCE}e';"
这是在脚本中使用随机数的简单示例:
<script nonce="<?= $_SERVER['CSP_NONCE'] ?>">
var inline = 1;
</script>
该示例是 php,但您可以使用任何语言。
我更愿意简单地将其添加为评论,但我的声誉<50 does not allow it so I'm posting this as an answer instead.
回复:
1.) apache 通过 mod_unique_id 生成随机字符串
这是一个“唯一”值,而不是“随机”值,因此您可能需要小心将其用作 CSP 随机数。
2.)我们将其插入到我们的 CSP 标头中(不知道实际如何执行此操作)
<IfModule mod_headers.c>
<FilesMatch "\.(htm|html|php)$">
Content-Security-Policy: script-src 'strict-dynamic' 'nonce-%{UNIQUE_ID}e' 'unsafe-inline' ' https:;
</FilesMatch>
</IfModule>
我希望这有帮助。
找到 mod_unique_id 后,这非常容易(http://httpd.apache.org/docs/current/mod/mod_unique_id.html)。
1.) 启用 mod_unique_id。这通常是 httpd.conf 中的一行: LoadModule unique_id_module模块/mod_unique_id.so
2.) mod_unique_id 生成一个唯一的字符串(请参阅 user3526609 的答案,这对您来说可能足够随机,也可能不够随机),并且在每个页面请求上将服务器变量 UNIQUE_ID 设置为等于该随机字符串,然后您可以将其注入到 CSP 中您需要列入白名单的任何内联代码。如果你碰巧使用 Php,$_SERVER['UNIQUE_ID'];
在 Apache 中,您必须启用名为 mod_unique_id 的模块。他生成一个唯一的环境变量(UNIQUE_ID)。然而,它的编码包含csp [A-Za-z0-9@-] 的非法字符,而不是通常的base64 [A-Za-z0-9+/]。
您应该使用base64编码来生成正确的值。例如:
Header set X-Nonce "expr=%{base64:%{reqenv:UNIQUE_ID}}"
然后生成完整的 CSP 策略:
Header set Content-Security-Policy "expr=default-src 'self'; script-src 'self' 'nonce-%{base64:%{reqenv:UNIQUE_ID}}'"
在 PHP 中使用:
echo $_SERVER['HTTP_X_NONCE'];
提取随机数。
随机数必须插入到具有内联 CSS 和/或 Javascript 处理程序的任何元素中,因此必须插入到应用程序层。
解析输出 HTML 并插入随机数会破坏 CSP 随机数的全部目的——Web 服务器无法知道内联 CSS/JS 是否应该存在,或者是否是由攻击者插入的。
我很抱歉,但你为什么不使用 randomAlphanumeric(int count) 'nonce-%{base64:randomAlphanumeric(45)}' 也许是一个愚蠢的想法,但可能会有所帮助
在我的公司,他们不允许安装新的 Apache 模块,因此 mod_cspnonce 不适合我。 我将 mod_unique_id 与 base64 一起使用(因为 mod_unique_id 可以生成 CSP 标头中不允许的特殊字符)和 shtml (Apache SSI)。
这是我在 Apache 2.4 中的完整设置:
在apache配置文件中:
加载模块include_module模块/mod_include.so
FollowSymLinks 选项包括添加类型文本/html .shtml AddOutputFilter 包括 .shtml
#主机设置CSP示例 #解析并发送 .shtml 文件而不是 html。您的配置可能不同 重写规则 ^ /index.shtml
标头始终设置 Content-security-Policy "expr=script-src 'self' 'nonce-%{base64:%{reqenv:UNIQUE_ID}}';"
创建index.shtml文件并上传apache主机:
” >链接参考: https://httpd.apache.org/docs/2.4/mod/mod_unique_id.html https://httpd.apache.org/docs/current/mod/mod_include.html