1

I am trying to get something working with mod_rewrite, but am not entirely sure it's even possible.

Say I have some request like:

https://www.example.com?h=somerandomvalue&u=www.another.example/content

I'd like to take the value of the u parameter and rewrite the request using this value, so from the above example request, I'd like to rewrite it to be

https://www.another.example/content

So basically, request:

https://www.example.com?h=somerandomvalue&u=www.another.example/content

Redirects to:

www.another.example/content

Is this possible? I've seen other examples where people are capturing and using parameters as part of a rewritten path but I have not seen anything in the way of redirecting to an entirely new domain using the provided parameter.

Any help or guidance here is very much appreciated!

0

1 Answer 1

2

I've seen other examples where people are capturing and using parameters as part of a rewritten path

Yes, this is possible. The basic principle is the same:

RewriteEngine On

RewriteCond %{QUERY_STRING} (?:^|&)u=([\w./-]{6,})(?:&|$)
RewriteRule ^$ https://%1 [QSD,R=302,L]

%1 is a backreference to the capturing group in the preceding CondPattern. ie. the value of the u URL parameter.

([\w./-]{6,}) is just a very rudimentary check to match a semi-valid URL. This can be improved.

The (?:^|&) prefix on the regex ensures we only match the u URL parameter and not any URL parameter that simply ends in u.

This only redirects requests for the root, as in your example. A malicious user could turn your site into a relay to forward traffic.

However, without further validation of the URL being redirected to this is potentially open to abuse and should not be used.

UPDATE#1:

For example, you could limit the hostnames that can be redirected to with a series of RewriteCond directives:

RewriteCond %{QUERY_STRING} (?:^|&)u=([\w./-]{6,})(?:&|$)
RewriteCond %1 ^(www\.another\.example/.*) [OR]
RewriteCond %1 ^(www\.two\.example/.*) [OR]
RewriteCond %1 ^(www\.three\.example/.*) [OR]
RewriteCond %1 ^(www\.four\.example/specific/path/to/file.html)
RewriteRule ^$ https://%1 [QSD,R=302,L]

The %1 backreference (which contains the captured group from the last matched CondPattern) matches the complete URL that is sent in the u URL parameter. This relies on the fact that RewriteCond directives finish "early" when the condition is satisfied.

If you have many specific URLs then you could create a RewriteMap in the server config and perform a lookup to check the valid URLs.

Alternatively, rewrite the request to a server-side script (eg. PHP) and manage the checks and redirection in the script instead.


UPDATE#2:

Does this example also work if the u parameter is an encoded URL?

Not currently. The QUERY_STRING server variable is not %-decoded. To allow a URL encoded (%-encoded) parameter value then you will need to include % in the regex character class that matches the URL and include the NE (noescape) flag on the RewriteRule directive to prevent any %-encoded characters being doubly encoded in the redirect response.

For example:

RewriteCond %{QUERY_STRING} (?:^|&)u=([\w%./-]{6,})(?:&|$)
:
RewriteRule ^$ https://%1 [NE,QSD,R=302,L]
Sign up to request clarification or add additional context in comments.

3 Comments

Appreciate the help. You are right about this being dangerous in practice - simply put this is supposed to redirect 1000s of different URLs, all of which I could not possibly account for in some RewriteCond. I am going to mark your answer as the correct one since it generally works as described, however know that I've decided to look at other options so you and I can sleep a little more soundly.
Does this example also work if the u parameter is an encoded url?
@JasonWordtmann Not currently. I've updated my answer with an example that will allow a %-encoded URL parameter.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.