使用 Apache 2.4 生成一个随机数(用于内容安全策略标头)



我们正在努力创建一个严格的内容安全策略(https://csp.withgoogle.com/docs/strict-csp.html(,这需要Apache在每次请求资源时创建一个nonce,以便我们可以将这个nonce插入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 不允许这样做,所以我将其作为答案发布。

针对:

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 中的一行:负载模块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 nonces的全部目的 - Web服务器无法知道内联CSS/JS是否应该存在,或者它是否由攻击者插入。

我很

抱歉,但你为什么不使用randomAlphanumeric(int count('nonce-%{base64:randomAlphanumeric(45(}'也许是一个愚蠢的想法,但可能会有所帮助

最新更新