使用 .htaccess 中的 mod_rewrite 重定向到 % 编码的 URL 参数

使用 .htaccess 中的 mod_rewrite 重定向到 % 编码的 URL 参数

我想了解有关的几件事RewriteRule

URL 上的工作规则将查询剥离回重定向,例如 URL:

https://www.example.com/application?user=543&AppLink=https://www.example.net/register/reg.aspx?EnquiryID=12345

工作.htaccess代码:

RewriteCond %{REQUEST_URI}  ^/application$
RewriteCond %{QUERY_STRING} .*AppLink=(.*)
RewriteRule ^(.*)$ %1 [R=302,L]

正确结果是重定向 URL:

https://www.example.net/register/reg.aspx?EnquiryID=12345

一切都很好,直到我想在查询链接中引入 URL 编码,例如:

https://www.example.com/application?user=543&AppLink=https%3A%2F%2Fwww.example.net%2Fregister%2Freg.aspx?EnquiryID=12345

首先,编码的引入破坏了工作RewriteRule,导致 http_host 名称再次出现 - 我不明白为什么会这样:

https://www.example.com/https%3A%2F%2Fwww.example.net%2Fregister%2Freg.aspx?EnquiryID=12345

因此,我试图找出%3A%2F%2F在将查询作为重定向功能的有效 URL 之前将(例如)“解码”/剥离回冒号和斜线的最佳方法。

我假设,在某种程度上,我需要创建一个“循环”RewriteRule 来整理编码(正则表达式),然后将其重定向到同一个主机,剥离有效的 URL 并将其发送到重定向的主机!

是的,很混乱,而且开销很大。

有人对解决这个问题的最佳方法有什么建议或想法吗?

答案1

...解决这个问题的最佳方法是什么?

这实际上是您的 Web 应用程序(例如 PHP、Python 等)的任务,而不是 Apache(.htaccess)。

如果这个脚本是“公开的”,那么......这种性质的“重定向”脚本经常被诈骗者滥用(例如),因此您需要将可能的重定向目标列入白名单(并可选择验证发件人)。这可能很难实现,.htaccess并且可能更适合您的应用程序本身。

https://www.example.com/application?user=543&AppLink=https%3A%2F%2Fwww.domain2.com%2Fregister%2Freg.aspx?EnquiryID=12345

人物:/需要当它们出现在 URL 的查询字符串部分时,需要进行 URL 编码。但是,如果您要正确地对AppLinkURL 参数值进行 URL 编码,那么您还会对?and =(目标 URL 的一部分)进行 % 编码。

首先,编码的引入破坏了有效的 RewriteRule,导致 http_host 名称再次出现 - 我不明白为什么会这样:

服务器QUERY_STRING变量未经过 % 解码。因此,结果代换字符串是:

https%3A%2F%2Fwww.example.net%2Fregister%2Freg.aspx?EnquiryID=12345

Apache/mod_rewrite 将此视为相对 URL,因为它不是以斜杠或有效方案开头(即https://)。对于相对 URL,mod_rewrite 使用RewriteBase当前请求中的方案和主机名(以及目录前缀或指令的值)(默认情况下),以便为外部重定向,因此您看到的是格式错误的重定向。

解决方案

如上所述,我建议在您的应用程序中执行此操作,而不是.htaccess。但无论如何,要回答您的具体问题,您可以执行类似下面的操作而不是当前的指令。但是,这需要 Apache 2.4+ 和对您的服务器配置的访问权限(因为AllowEncodedSlashes在目录/上下文中不允许.htaccess):

以下内容需要放在你的服务器配置(或虚拟主机):

# Allow %2F to be used in the URL-path part of the URL
# Otherwise Apache will trigger a system generated 404 (security feature)
AllowEncodedSlashes On

然后,在.htaccess

# Convert URL param value to path-info (via URL rewrite)
# This essentially %-decodes the URL parameter value
RewriteCond %{QUERY_STRING} AppLink=(.+)
RewriteRule ^application$ /application/%1 [QSD]

# Issue redirect using the %-decoded URL-path
RewriteRule ^application/(https?:/)(.+) $1/$2 [R,L]

笔记:

  • 如果可能的话,使用以下方法检查 URL 路径会更有效:RewriteRule 图案而不是使用额外的状况检查REQUEST_URI服务器变量。
  • QSD需要(查询字符串丢弃)标志来丢弃初始AppLink请求中的(和任何其他)URL 参数。
  • 第一个 URL 重写被传递到触发实际重定向的下一个指令。RewriteRule指令自然地链接在一起,一个指令的输出被用作下一个指令的输入,依此类推。
  • URL 路径RewriteRule 图案匹配的是 % 解码的。(而QUERY_STRING服务器变量仍然是 % 编码的。)但是,URL 路径中的连续斜杠会缩减为单个斜杠。因此https:/https://RewriteRule 图案以及在代换

这还假设您的配置中允许附加路径名信息。如果不允许,您可能需要AcceptPathInfo On.htaccess(或服务器配置)中明确设置。如果没有,那么您还将获得系统生成404.

相关内容