У меня есть следующий URL:
example.com/?redirect=some-url-encoded
Мне нужно перенаправить его на URL-адрес, указанный в строке запроса (redirect
параметр).
Я пытался:
RewriteCond %{QUERY_STRING} redirect=(.+)
RewriteRule ^(.*)$ %1 [R=302,L,QSA]
Но меня перенаправили на URL:
example.com/some-url-encoded?redirect=some-url-decoded
Так:
Как правильно с этим справиться?
- мой URL не декодируется
В QUERY_STRING
переменная сервера не декодируется URL-адресом, и mod_rewrite также будет кодировать URL-адрес подстановки, поэтому вы, вероятно, получите URL-адрес с двойной кодировкой? Вам, вероятно, понадобится NE
(NOESCAPE
) флаг.
Однако, если двоеточия и косые черты (как в http://
) закодированы в URL (т. е. http:%3A%2F%2F
) в параметре строки запроса, то они будут переданы в уже закодированную подстановку, что отрицает их обычное значение в URL-адресе. Хотя большинство функций кодирования URL-адресов будут кодировать эти символы, их строго не нужно кодировать в значении параметра URL-адреса (хотя это может зависеть от конфигурации вашего сервера - если вы меняете то, что сервер считает разделителями URL-адресов - но это редко) . Итак, кодируйте все остальные символы, кроме :
и /
в значении параметра URL. Например, вместо:
example.com/?redirect=https%3A%2F%2Fwww.google.pl%2F
Оставь :
(двоеточие) и /
(косая черта) незакодированные символы:
example.com/?redirect=https://www.google.pl/
Альтернативой вместо использования параметра URL является использование дополнительных PATH_INFO
в конце URL-адреса, поскольку он должен автоматически декодироваться. Однако это зависит от AcceptPathInfo
директиве, и вам также нужно будет включить AllowEncodedSlashes
(в конфигурации сервера), но это связано с собственными проблемами безопасности. См. Документацию Apache: http://httpd.apache.org/docs/current/mod/core.html#allowencodedslashes
- применяется старая строка запроса.
Вы явно указываете mod_rewrite применить исходную строку запроса с QSA
(Добавление строки запроса) флаг. Но он все равно сделает это по умолчанию. Вам нужно явно удалить его с помощью QSD
(Отмена строки запроса) в Apache 2.4+ или добавьте ?
к RewriteRule
подмена.
- URL начинается с
example.com
Вам необходимо указать абсолютный URL-адрес (т.е. со схемой http://
) в параметре URL (или явно жестко закодируйте это в подстановке?). Обратите внимание, что если двоеточие и / или косая черта http://
закодированы в URL-адресе, то Apache не увидит его как абсолютный URL-адрес, и он будет рассматриваться как относительный (по отношению к текущему каталогу), к которому Apache добавит префикс каталога-префикса, а затем попытается сделать его абсолютным (из-за R
флаг - внешний перенаправить), указав префикс протокола и текущего домена, т.е. http://example.com
. Это не только полностью повредит перенаправление, но и откроет вашу внутреннюю структуру каталогов.
Собирая все вместе, попробуйте следующее:
RewriteCond %{QUERY_STRING} redirect=(.+)
RewriteRule ^ %1? [R=302,L,NE]
Предполагается, что протокол / схема является передается в параметре строки запроса. например. http://example.com/?redirect=http://www.google.pl/
Подшаблон в скобках в RewriteRule
шаблон (т.е. (.*)
) здесь показалось бы ненужным.
Обратите внимание, что разрешение любой Абсолютный URL-адрес, который будет использоваться в качестве цели в простом сценарии перенаправления, как это, представляет собой угрозу безопасности. Если хакеры обнаружат это, то, скорее всего, им будут злоупотреблять и использовать как часть цепочки переадресации, побуждающей пользователей загружать вредоносное программное обеспечение и т.п.
Смотрите также:
https://webmasters.stackexchange.com/questions/99749/301-redirect-script-being-abused-for-what-purpose
Вы идете неправильным путем. Используйте RewriteCond / RewriteRule, чтобы переписать путь (с QSA, чтобы сохранить строку запроса) к сценарию (PHP или какой-нибудь CGI, что вам нравится), а затем пусть этот сценарий воплощает ограничения логики и корректности, чтобы получить желаемое перенаправление.
Это также обеспечивает полезные функции включения. Некоторые идеи: