这里有几个问题...
SetEnv CSP "%{ENV:CSP_Default} %{ENV:CSP_Media}"
这实际上将CSP
环境变量设置为文字值%{ENV:CSP_Default} %{ENV:CSP_Media}
-CSP_Default
和CSP_Media
env 变量没有展开。AFAIK 无法在SetEnv
指令的 value 参数中引用环境变量。
您可以改用 mod_rewrite (或SetEnvIfExpr
- 见下文)来创建这个CSP
env var,它是两个现有 env var 的串联,由空格分隔。
但是,SetEnv
(mod_env) 在 mod_rewrite 请求中处理得太晚(处理得非常早),无法读取这些环境变量。因此,您将需要使用SetEnvIf
(mod_setenvif) 代替(或者也使用 mod_rewrite 来设置初始环境变量)。
例如:
RewriteEngine On
# Media Sources
SetEnvIf ^ ^ "CSP_Media=media-src 'self' ;"
# Default Sources
SetEnvIf ^ ^ "CSP_Default=default-src 'self' kevinpirnie.com ;"
# Add the CSP Headers
RewriteRule ^ - "[E=CSP:%{ENV:CSP_Media} %{ENV:CSP_Default}]"
请注意策略性放置的双引号,因为value参数包含空格。
更新:您可以避免在上面使用 mod_rewrite 并使用SetEnvIfExpr
指令来使用Apache 表达式(Apache 2.4)连接环境变量。
例如:
# Add the CSP Headers
SetEnvIfExpr "reqenv('CSP_Media').' '.reqenv('CSP_Default') =~ /(.*)/" CSP=$1
表达式 LHS 上的点 ( .
) 是字符串连接运算符(很像 PHP)。它们不会作为正则表达式 (RHS) 捕获的字符串的一部分出现并用作反向引用中的连接值$1
。
访问Header
指令中的 env var
Header always set Content-Security-Policy %{ENV:CSP}
Header always set X-Content-Security-Policy %{ENV:CSP}
mod_headers 使用不同的语法来访问 env vars 的值,因此出现“无法识别的标头格式 %”错误。你需要%{var}e
改用。
例如:
Header always set Content-Security-Policy %{CSP}e
Header always set X-Content-Security-Policy %{CSP}e
或者,您可以通过不创建中间环境变量来避免 mod_rewrite 和 mod_setenvifCSP
并将它们组合在Header
指令中。
例如:
# Media Sources
SetEnv CSP_Media "media-src 'self' ;"
# Default Sources
SetEnv CSP_Default "default-src 'self' kevinpirnie.com ;"
# Add the CSP Headers
Header always set Content-Security-Policy "%{CSP_Media}e %{CSP_Default}e"
Header always set X-Content-Security-Policy "%{CSP_Media}e %{CSP_Default}e"
由于空格,value参数需要用双引号引起来。
我正在为我的一个站点构建一种内容安全策略生成器。
虽然,如果此代码是“自动生成的”(?),那么为什么不Header
一步生成完整的代码呢?