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

问题描述 投票:0回答:7

我们正在努力创建严格的内容安全策略 (https://csp.withgoogle.com/docs/strict-csp.html),这需要 Apache 在每次请求资源时创建一个随机数,以便我们可以将此随机数插入到 http 标头中。

我们如何使用 Apache 2.4 创建随机数?

我读过的所有 CSP 相关文档都提到了“随机数只是服务器上生成的随机字符串,包含在 CSP 标头中......”,但没有找到任何有关如何使用 Apache 执行此操作。我们当然可以使用应用程序代码来执行此操作,但通过 Apache 执行此操作似乎是一个更干净的解决方案/将确保每个页面都获取 CSP 标头。

apache security content-security-policy
7个回答
7
投票

您需要在服务器上生成

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,但您可以使用任何语言。


3
投票

我更愿意简单地将其添加为评论,但我的声誉<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>

我希望这有帮助。


3
投票

找到 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'];


3
投票

在 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'];

提取随机数。


0
投票

随机数必须插入到具有内联 CSS 和/或 Javascript 处理程序的任何元素中,因此必须插入到应用程序层。

解析输出 HTML 并插入随机数会破坏 CSP 随机数的全部目的——Web 服务器无法知道内联 CSS/JS 是否应该存在,或者是否是由攻击者插入的。


0
投票

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


0
投票

在我的公司,他们不允许安装新的 Apache 模块,因此 mod_cspnonce 不适合我。 我将 mod_unique_idbase64 一起使用(因为 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

    CSP 字符串需要位于“expr=”内,Apache 才能执行 base64 函数

    标头始终设置 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

© www.soinside.com 2019 - 2024. All rights reserved.