Forum Moderators: phranque

Message Too Old, No Replies

Exposed file paths - Found a solution but I am Confused

rewrite rule expose subdomain paths, htaccess breaks subdomain urls

         

appliedcms

3:06 pm on Jan 31, 2010 (gmt 0)

10+ Year Member



Is this normal Apache subdomain behavior? (I will replace all http with hxxp because this forum formats code kind of funny)

remove www htaccess on main-domain (used for years on various server without incident)

[size=2]RewriteCond %{HTTP_HOST} !^somesite.com$ [NC]
RewriteRule (.*) hxxp://somesite.com/$1 [R=301,L][/size]

Now on one server I am working on (Hostgator - shared reseller) - That code caused all the sub-domains to rewrite from...

[size=2]hxxp://xyz.somesite.com/ 
to
hxxp://somesite.com/subdomains/xyz/[/size]

So I found this solution on your webmasterworld.com forum which fixes the remove www with wildcards.
--- THANKS APACHE EXPERTS at WebMasterWorld.com ---

[size=2]#RewriteCond %{HTTP_HOST} ^www\.(.*) [NC]
#RewriteRule ^(.*)$ hxxp://%1/$1 [R=301,NC,L] [/size]


Just curious as to why I need to wild card this particular server?
Kind of double checking with you guys to make sure it's not a server-side config issue.

Cheers,
Walt

jdMorgan

4:46 pm on Jan 31, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



That hostname redirection code -in and of itself- did not cause the subdomains to be exposed as filepaths.
However, there was likley an internal subdomain-hostname-to-subdirectory rewrite executed prior to that redirect.

The problem is one of rule execution order. If the subdomain-to-subfolder rewrite is located in a server config file or .htaccess file "higher" in the directory-path than the hostname canonicalization redirect, then the later-executed redirect will expose the previously-rewritten filepath to the client.

So explore this from the viewpoint of "what rules do I have, and where are they located?"

In general, regardless of their location, you must order your rules with all external redirects first, ordered from most-specific (one or only a few URLs affected) to least-specific (e.g. catch-all hostname canonicalization redirect), followed by all internal rewrites, again in order from most- to least-specific.

This prevents both 'stacked/chained/multiple redirects resulting from a single client requests, and prevents exposing internal filepaths as URLs to clients.

It is also possible that some other module which does internal rewriting is executing first.

Jim

jdMorgan

5:09 pm on Jan 31, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Also note that the original code specifically says, "If the requested hostname is NOT *exactly* "www.example.com" then redirect to www.example.com." Therefore, it is not suitable for use with multiple subdomains -- it forces the "www" subdomain for all requests.

A better general solution for your case, which handles FQDN-format hostnames and hostnames with port numbers appended would be:


# If requested hostname is "example.co[b]m.[/b]", "example.co[b]m:[/b]<port>", or "example.co[b]m.:[/b]<port>"
RewriteCond %{HTTP_HOST} ^example\.com(\.|\.?:[0-9]+)$ [NC]
# Redirect to canonical hostname
RewriteRule ^(.*)$ http://example.com/$1 [R=301,L]
#
# If requested hostname is "www.<sub>.example.com" (with or without FQDN indicator or port)
RewriteCond %{HTTP_HOST} ^www\.([^.]+)\.example\.com [NC,OR]
# OR <sub>.www.example.com (with or without FQDN or port)
RewriteCond %{HTTP_HOST} ^([^.]+)\.www\.example\.com [NC,OR]
# OR <sub>.example.co[b]m.[/b], <sub>.example.co[b]m:[/b]<port number>, or <sub>.example.co[b]m.:[/b]<port>
RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.com(\.|\.?:[0-9]+)$
# Redirect to canonical hostname
RewriteRule ^(.*)$ http://%1.example.com/$1 [R=301,L]

If the choice is made to use the "www" subdomain as the canonical "main" domain instead of "example.com", then it can all be done with one rule:

# If requested hostname is "example.com" (with or without FQDN indicator or port)
RewriteCond [b]www.[/b]%{HTTP_HOST} ^(www)\.example\.com [NC,OR]
# OR www.<sub>.example.com (with or without FQDN or port)
RewriteCond %{HTTP_HOST} ^www\.([^.]+)\.example\.com [NC,OR]
# OR <sub>.www.example.com (with or without FQDN or port)
RewriteCond %{HTTP_HOST} ^([^.]+)\.www\.example\.com [NC,OR]
# OR <sub>.example.co[b]m.[/b], <sub>.example.co[b]m:[/b]<port number>, or <sub>.example.co[b]m.:[/b]<port>
RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.com(\.|\.?:[0-9]+)$
# Redirect to canonical hostname
RewriteRule ^(.*)$ http://%1.example.com/$1 [R=301,L]

Jim

[edited by: jdMorgan at 5:23 pm (utc) on Jan. 31, 2010]

appliedcms

5:16 pm on Jan 31, 2010 (gmt 0)

10+ Year Member



Thanks jdMorgan,

I will forward this post to the server admin at Hostgator and see what he thinks.

I am no Apache wizard, so a lot of what you mention is in fact foreign to me.

I just found the server behavior to be odd.

Thanks again for responding,
Walt

g1smd

10:16 pm on Jan 31, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



There is a flaw in your original code:

RewriteCond %{HTTP_HOST} !^example.com$ [b][NC][/b]
RewriteRule (.*) http://example.com/$1 [R=301,L]

Remove the NC flag. As originally coded, it says "if the request is not exactly example.com, but the request can be in any case", but it should be "if the request is not *exactly* example.com".