【问题标题】:Apache: how to double-decode double-encoded incoming URLsApache:如何对双编码的传入 URL 进行双重解码
【发布时间】:2014-12-25 11:21:54
【问题描述】:

我的 Rails 应用程序在Passenger/Apache 下运行时遇到问题,Googlebot 在其中尝试访问查询字符串参数已被双重编码的 URL。 (我不知道 Googlebot 是从哪里获取这些 URL 的——它们不在我应用的任何链接中。)

这导致我的日志中出现大量额外错误,因此很难诊断“真正的”问题,因为它们隐藏在由 Googlebot 尝试访问的网址引起的错误之下。

这是我的 Apache 访问日志中的一个示例:

66.249.67.103 - - [27/Oct/2014:07:44:32 -0400] "GET /catalog?f%255Bfacet_field_1%255D%255B%255D=foo&f%255Bfacet_field_2%255D%255B%255D=bar&sort= title_info_primary_ssort+asc%252C+date_start_dtsi+asc HTTP/1.1" 200 5266 "-" "Mozilla/5.0(兼容;Googlebot/2.​​1; +http://www.google.com/bot.html)"

注意双重编码(“%255B”、“%255D”),它是已编码字符(“%5B”、“%5D”)的编码版本。所以不是我的 Rails 应用程序接收这些参数:

{
  "f[facet_field_1][]" => "foo",
  "f[facet_field_2][]" => "bar",
  "sort" => "title_info_primary_ssort asc, date_start_dtsi asc"
}

...它接收这些:

{
  "f%5Bfacet_field_1%5D%5B%5D" => "foo",
  "f%5Bfacet_field_2%5D%5B%5D" => "bar",
  "sort"=>"title_info_primary_ssort asc%2C date_start_dtsi asc"
}

... 它无法解释,导致错误日志中出现大量条目。 URL 被解码一次(很确定 Apache 默认会这样做),但这仍然会在 Rails 无法处理的参数哈希中留下 URL 编码的字符。

我需要一种对用户代理是 Googlebot 的 URL 进行双重解码的方法。似乎应该可以使用 mod_rewrite 来做到这一点,但我运气不佳,因为 mod_rewrite 似乎不太适合修改 URL 的查询字符串部分。这也是有问题的,因为我无法预测参数的确切顺序,也无法预测可能在 URL 中传递的参数的确切组合。

如何告诉 Apache 在将请求传递给我的应用程序之前对 URL 进行双重解码(基于用户代理)? (服务器版本:Apache/2.4.7 (Ubuntu))。阻止 Googlebot 是不可接受的选择。

【问题讨论】:

    标签: apache mod-rewrite url-rewriting apache2 urldecode


    【解决方案1】:

    有办法做到这一点,但它需要修改服务器的.conf 文件。您需要在服务器配置中添加以下指令:

    RewriteMap unescape int:unescape
    

    之后你可以像这样使用 RewriteRule:

    RewriteEngine On
    RewriteCond %{IS_SUBREQ} false
    RewriteRule ^(.*)$ $1?${unescape:%{QUERY_STRING}} [L]
    

    而且,正如我认为的那样,不应该对每个请求都这样做,而应该只对那些需要解码的请求进行,因此需要额外的 RewriteCond。例如,您可以检查%255B%255D 等是否存在。

    因此,最终的规则集将是(它可能会在元素值中存在双引号符号的情况下触发,而不仅仅是在参数名称中)

    RewriteEngine On
    RewriteCond %{IS_SUBREQ} false
    RewriteCond %{QUERY_STRING} %255(B|D)
    RewriteRule ^(.*)$ $1?${unescape:%{QUERY_STRING}} [L]
    

    【讨论】:

    • 这很好用——谢谢! FWIW,我最终决定对这些 Googlebot 请求返回 400 Bad Request 响应,而不是像参数已正确编码一样重定向它们:'RewriteCond %{HTTP_USER_AGENT} Googlebot RewriteCond %{QUERY_STRING} %25[25][BC]重写规则。 - [R=400,L]'
    猜你喜欢
    • 2015-09-13
    • 1970-01-01
    • 2011-11-11
    • 1970-01-01
    • 1970-01-01
    • 2010-11-13
    • 1970-01-01
    • 2012-01-27
    • 1970-01-01
    相关资源
    最近更新 更多