如何在 APACHE 中注入随机 CSP nonce?

如何在 APACHE 中注入随机 CSP nonce?

我想在 APACHE 中添加以下 CSP 指令,因为我希望它应用于每个页面。

<IfModule mod_headers.c>
    <FilesMatch "\.(htm|html|php)$">
        Content-Security-Policy: script-src 'strict-dynamic' 'nonce-{random}' 'unsafe-inline' ' https:;
    </FilesMatch>
</IfModule>

我也想直接在 APACHE 中生成 {random} 值(如果可能的话)。

是否可以直接在 APACHE CSP 指令中生成并插入它?或者这是一个坏主意,我应该在应用程序层(PHP)生成并插入吗?

注意:我确实找到了这个使用 Apache 2.4 生成随机数(用于内容安全策略标头)看起来很有希望,但我不确定 $_SERVER[UNIQUE_ID] 是否实际上是一个足够随机的值。

答案1

您在 CSP 标头中设置的 nonce 必须与脚本标记中使用的 nonce 相同。这就是为什么它通常在应用程序级别设置,其中保存值可以在 HTTP 标头和 HTML 中使用。如果您在 Apache 级别设置它,那么您如何在应用程序中使用它?

答案2

@user3526609 因这个出色的解决方案而获得赞誉,但我想总结一下,以便让其他像我一样到处寻找这个问题并发现它埋在评论中的人能够清楚地看到。

简而言之,这就是如何在文件中.htaccess而不是在 Web 应用程序中创建 CSP nonce,但仍然能够在 Web 应用程序中使用它。

您可以通过重复使用 Apache 为每个请求创建的唯一 ID 来“生成”一个随机数。按如下方式创建内容安全策略标头(为简洁起见,省略了许多其他重要部分):

Header always set Content-Security-Policy "\
  default-src 'self'; \
  script-src 'self' 'nonce-%{UNIQUE_ID}e';"

请注意,反斜杠将命令分成易于阅读的行,这些行稍后会被 Apache 删除。

这将创建类似以下内容的内容:

'nonce-STRINGofRANDOMcharacters'

PHP 可以按如下方式访问它:

$_SERVER['UNIQUE_ID']

网页中的示例:

<script 
  src="https://www.google.com/recaptcha/api.js?render=your-site-key"
  nonce="<?php echo $_SERVER['UNIQUE_ID']; ?>">
</script>

答案3

在 Apache 中,您必须启用名为 mod_unique_id 的模块。它会生成一个唯一的环境变量 (UNIQUE_ID)。但是,它的编码包含 csp 的非法字符 [A-Za-z0-9@-],而不是通常的 base64 [A-Za-z0-9+/]。

您必须使用 base64 编码来生成正确的值。这仅在 Apache > 2.4 及更高版本时才有效。例如:

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}}'"

相关内容