【问题标题】:mod_rewrite match encoded URLmod_rewrite 匹配编码的 URL
【发布时间】:2023-03-10 10:56:02
【问题描述】:

在我的 Apache 配置中,当查询字符串参数包含特定值时,我想返回 403。一切正常,除非客户端查询字符串以十六进制编码。如何在不输入文字十六进制字符串的情况下使其匹配?

RewriteEngine On
RewriteCond %{QUERY_STRING} mykey=myval [NC]
RewriteRule .* - [F,L]

然后测试一下:

# Works fine, returns 403
curl -I 'http://localhost/?mykey=myval'

# Does not work, returns 200:
curl -I 'http://localhost/?mykey=%6d%79%76%61%6c'
curl -I 'http://localhost/?%6d%79%6b%65%79=%6d%79%76%61%6c'

谢谢

【问题讨论】:

    标签: regex apache mod-rewrite httpd.conf


    【解决方案1】:

    QUERY_STRING 服务器变量保持 % 编码(就像它在请求中一样),与 RewriteRule 模式 匹配的 URL 路径不同,后者是 % 解码的。

    但是,在 Apache 2.4 上,您可以使用带有 RewriteCond 指令的 Apache 表达式在进行比较之前对 QUERY_STRING 进行 URL 解码。例如:

    RewriteCond expr "unescape(%{QUERY_STRING}) =~ /mykey=myval/"
    RewriteRule ^ - [F]
    

    这将成功匹配?mykey=myval?mykey=%6d%79%76%61%6c?%6d%79%6b%65%79=%6d%79%76%61%6c 形式的请求。

    使用F 时不需要L 标志,因为它是隐含的。如果您只需要在任何 URL 路径上成功(实际上不匹配任何内容),则正则表达式 ^.* 效率略高。

    请注意,正则表达式mykey=myval 匹配查询字符串中的任何位置的字符串,因此它可以成功匹配anymykey=myvalmykey=myvalany,这可能有问题,也可能没有问题。要消除这种歧义并仅匹配查询字符串中的“key=value”对,那么您需要使用像 (?:^|&)mykey=myval(?:&|$) 这样的正则表达式。

    【讨论】:

    • 很好的使用expr指令
    • 你是 Apache 忍者,谢谢 :) 我很好奇,开发人员是否有理由为这种情况保留查询字符串 %-encoded 而不是 RewriteRule 具有 %-decoded ?我意识到保持未转义的价值是“真实”价值,但一些针对网络管理员的“虚拟证明”保护措施可以帮助数百万人。常见场景:站点管理员想要阻止对 URL 的访问,但不知道恶意用户可以对查询字符串进行简单的 % 编码以绕过 RewriteCond
    猜你喜欢
    • 1970-01-01
    • 2020-01-15
    • 1970-01-01
    • 2012-04-14
    • 2013-10-02
    • 1970-01-01
    • 1970-01-01
    • 2012-09-07
    • 2020-06-29
    相关资源
    最近更新 更多