【问题标题】:.htaccess Variables Issue Unrecognized header format %.htaccess 变量问题无法识别的标头格式%
【发布时间】:2020-12-16 17:37:06
【问题描述】:

我正在为我的一个网站构建一种内容安全策略生成器。我被它的 .htaccess 部分的一个特定部分难住了

生成的.htaccess是:

# Media Sources
SetEnv CSP_Media "media-src 'self' ;"

# Default Sources
SetEnv CSP_Default "default-src 'self' kevinpirnie.com ;"

# Add the CSP Headers
SetEnv CSP "%{ENV:CSP_Default} %{ENV:CSP_Media}"
Header always set Content-Security-Policy %{ENV:CSP}
Header always set X-Content-Security-Policy %{ENV:CSP}

当我将引号从 SetEnv CSP 行中删除时,我会得到一个不同的错误:SetEnv takes 1-2 arguments 这是有道理的......但是在它们周围加上引号时,我得到了 Unrecognized header format % 错误

任何想法我可以做些什么来利用变量,或者如何解决header format 问题?

【问题讨论】:

    标签: apache .htaccess content-security-policy mod-headers


    【解决方案1】:

    这里有几个问题...

    SetEnv CSP "%{ENV:CSP_Default} %{ENV:CSP_Media}"
    

    这实际上将CSP 环境变量设置为文字值%{ENV:CSP_Default} %{ENV:CSP_Media} - CSP_DefaultCSP_Media 环境变量没有展开。 AFAIK 无法在 SetEnv 指令的 value 参数中引用环境变量。

    您可以使用 mod_rewrite(或 SetEnvIfExpr - 见下文)来创建这个 CSP 环境变量,它是两个现有环境变量的串联,由 空格 分隔。

    但是,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 参数包含 空格

    • SetEnvIf - SetEnvIf 指令中的整个 name=value 对必须用双引号引起来(不是 )。

    • RewriteRule - 整个 flags 参数需要用双引号引起来(不是 value)。

    更新:您可以避免在上面使用 mod_rewrite,而是使用 SetEnvIfExpr 指令来使用 Apache expression (Apache 2.4) 连接环境变量。

    例如:

    # Add the CSP Headers
    SetEnvIfExpr "reqenv('CSP_Media').' '.reqenv('CSP_Default') =~ /(.*)/" CSP=$1
    

    表达式左侧的点 (.) 是字符串连接运算符(很像 PHP)。它们不会作为正则表达式 (RHS) 捕获的字符串的一部分出现并用作$1 反向引用中的串联

    Header 指令中访问环境变量

    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_setenvif,方法是不创建中间 CSP env var,只需将它们组合到 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 呢?

    【讨论】:

    • 谢谢怀特先生。几天后我会调查这一切......目前在一个急需的 PTO 上 :) 回答你的最后一个问题......出于组织目的和更好的易读性。最终,我不会是唯一需要查看生成的规则的人 :)
    • 这确实起到了作用。再次感谢
    • 我已经更新了我的答案以包括使用 mod_rewrite 连接两个环境变量的替代方法(以创建组合的 CSP env var)。因为这也可以通过使用SetEnvIfExpr(也是 mod_setenvif 的一部分)来实现,尽管语法可能不那么简洁/可读。
    猜你喜欢
    • 2021-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-29
    • 2021-02-27
    相关资源
    最近更新 更多