mod_rewrite 匹配编码 URL
mod_rewrite match encoded URL
在我的 Apache 配置中,当查询字符串参数包含特定值时,我想 return 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'
感谢
QUERY_STRING
服务器变量保持 % 编码(因为它在请求中),与 RewriteRule
模式匹配的 URL 路径不同,这是 %-解码的。
但是,在 Apache 2.4 上,您可以使用带有 RewriteCond
指令的 Apache 表达式来 URL 解码 QUERY_STRING
,然后再进行比较。例如:
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=myval
和 mykey=myvalany
,这可能是问题,也可能不是问题。要消除这种歧义并仅匹配查询字符串中的“键=值”对,那么您需要使用 (?:^|&)mykey=myval(?:&|$)
之类的正则表达式。
在我的 Apache 配置中,当查询字符串参数包含特定值时,我想 return 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'
感谢
QUERY_STRING
服务器变量保持 % 编码(因为它在请求中),与 RewriteRule
模式匹配的 URL 路径不同,这是 %-解码的。
但是,在 Apache 2.4 上,您可以使用带有 RewriteCond
指令的 Apache 表达式来 URL 解码 QUERY_STRING
,然后再进行比较。例如:
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=myval
和 mykey=myvalany
,这可能是问题,也可能不是问题。要消除这种歧义并仅匹配查询字符串中的“键=值”对,那么您需要使用 (?:^|&)mykey=myval(?:&|$)
之类的正则表达式。