Stop hotlinking using htaccess and non-specific domain code - .htaccess

I need to write an anti-hotlink command for my .htaccess file but it can not be specific to any domain name in particular. Here's what I found on another sites so far but I'm not sure exactly why it doesn't work, can anyone spot the problem?
# Stop hotlinking.
#------------------------------
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} ^https?://([^/]+)/ [NC]
# Note the # is just used as a boundary. It could be any character that isn't used in domain-names.
RewriteCond %1#%{HTTP_HOST} !^(.+)#\1$
RewriteRule \.(bmp|gif|jpe?g|png|swf)$ - [F,L,NC]

Try this.
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} ^https?://(www\.)?([^/]+)/.*$ [NC]
RewriteCond %2#%{HTTP_HOST} !^(.+)#(www\.)?\1$ [NC]
RewriteRule \.(bmp|gif|jpe?g|png|swf)$ - [F,L,NC]
Would even work when only one of the referrer or target url has a leading www.
EDIT : (how does this % thing work?)
%n references the n(th) bracket's matched content from the last matched rewrite condition.
So, in this case
%1 = either www. OR "" blank (because it's optional; used ()? to do that)
%2 = yourdomain.com (without www always)
So, now the rewrite condition actually tries to match
yourdomain.com#stealer.com OR yourdomain.com#www.stealer.com
with ^(.+)#(www\.)?\1$ which means (.+)# anything and everything before # followed by www. (but again optional); followed by \1 the first bracket's matched content (within this regex; not the rewrite condition) i.e. the exact same thing before #.
So, stealer.com would fail the regex while yourdomain.com would pass. But, since we've negated the rule with a !; stealer.com passes the condition and hence the hot-link stopper rule is applied.

Related

Remove trailing dot in URL domain

We have URLs of the form:
www.dev-studio.co.uk.
www.dev-studio.co.uk./a-sample-image
With the help of .htaccess rules, I am trying to remove the trailing dot (co.uk.) in the end of the domain name but I'm failing.
This is the rule I'm trying:
RewriteCond %{HTTP_HOST} ^([a-z0-9\.-]+)(\.co\.uk\.)(.*)$
RewriteRule ^ http://www.dev-studio.co.uk/%3 [L,R=302,NE]
But the %3 which should capture the 3rd group is returning empty.
The goal is to simple redirect www.dev-studio.co.uk./a-sample-image to www.dev-studio.co.uk/a-sample-image
I have tried all the other questions over here but the solutions are not working for me.
Any help would be appreciated.
RewriteCond %{HTTP_HOST} ^([a-z0-9\.-]+)(\.co\.uk\.)(.*)$
RewriteRule ^ http://www.example.co.uk/%3 [L,R=302,NE]
The HTTP_HOST server variable contains the hostname only (ie. the value of the Host HTTP request header), it does not contain the URL-path, so the %3 backreference is always empty.
You need to either capture the URL-path from the RewriteRule pattern. For example:
RewriteRule (.*) http://www.example.co.uk/$1 [R=302,L]
Or, use the REQUEST_URI server variable (which contains the full URL-path, including slash prefix) instead:
RewriteRule ^ http://www.example.co.uk%{REQUEST_URI} [R=302,L]
This should ultimately be a 301 (permanent) redirect, once you have confirmed it works OK.
Note that since you are redirecting to a specific domain, do you need a CondPattern that matches any .co.uk hostname? You could be specific:
RewriteCond %{HTTP_HOST} =www.example.co.uk.
RewriteRule ^ http://www.example.co.uk%{REQUEST_URI} [R=302,L]
The = prefix on the CondPattern changes it to a lexicographical string comparison (not a regex), so no need to escape the dots.
If you wanted an entirely generic solution to remove the trailing . (FQDN) from any requested host then you could do something like:
RewriteCond %{HTTP_HOST} (.+)\.$
RewriteRule ^ http://%1%{REQUEST_URI} [R=302,L]
Although you might want to combine this with your canonical redirects (eg. non-www to www / HTTP to HTTPS?) to avoid multiple redirects - although they are probably unlikely to occur all at once anyway, so probably not an issue.

URL Rewrite subdomain with variables to regular domain with variables

I am trying to get some help with this URL rewrite. I have already read multiple tutorials and documentation pages on how to do all this, but none of it makes sense to me. I also don't understand regular expression, so that doesn't help either. I have a semi working piece of code and just need help getting it working correctly.
I need: http://subdomain.domain.com?dl=2
to redirect to http://domain.com/subdomain.php?dl=2
The code I have is
RewriteEngine on
RewriteCond %{HTTP_HOST} ^subdomain.example\.com$ [NC]
RewriteCond %{REQUEST_URI} !page.php
RewriteRule ^(.+/)?([^/]*)$ page.php?dl=$2 [QSA,L,NC]
Which sends the variable but can't figure out the subdomain part. If anyone could please help me out, it would be greatly appreciated.
You need to check the QUERY_STRING as RewriteRule doesn't include it. In addition, your rule is not using the redirect flag R.
RewriteEngine on
# First, check for the subdomain
RewriteCond %{HTTP_HOST} ^subdomain.domain.com$ [NC]
# Then, check the query string - it should match digits (\d+)
RewriteCond %{QUERY_STRING} ^dl=\d+ [NC]
# Check if we are not at subdomain.php
# (This is redundant, but leaving it here in case you really need it)
RewriteCond %{REQUEST_URI} !^/subdomain.php
# If all the above conditions are true, match a root-request
# and redirect to domain.com/subdomain.php with the query string
# Note: You don't need to actually specify the query string
# in the destination URI - Apache will automatically
# hand it over upon redirect (using the R flag).
# The only time this is not the case is when you
# either add the QSD flag, or append the destination
# URI with a question mark.
RewriteRule ^$ http://domain.com/subdomain.php [R=302,L]
The above will redirect http://subdomain.domain.com/?dl=2 to http://domain.com/subdomain.php?dl=2. If you would like to make the redirect permanent and cached by browsers and search engines, change 302 to 301.

friend url on wildcard subdomains htacces, not working

i have wildcard subdomains sets already and works fine, now i wish have friends url for the content in thats subdomains, the structure of my site is if the user type subdomain.maindomain.com and the .htaccess redirect to
blogs/index.php?user=subdomain
where blogs/index.php receive the param and show the correct content
now i try to make the url function like this
subdomain.maindoamin.com/24/title-of-content
and then .htaccess must result
blogs/index.php?id_content=24&title=title-of-content
i have the next .htaccess
Options +FollowSymLinks
#this force to server the content always without www.
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.(.*)$
RewriteRule ^(.*)$ http://%1/$1 [R=301]
#this is to pass the subdomain like param and show the right content of the user
RewriteCond %{HTTP_HOST} !^www\.misite\.com [NC]
RewriteCond %{HTTP_HOST} ^([a-z0-9]+)\.misite\.com
RewriteRule ^(.*)$ blogs/index.php?url=%1 [QSA,L]
#the next line i can't make work to make nice url
RewriteRule ^/(.*)/(.*)$ blogs/index.php?idP=$1&name=$2 [L]
not working because when i make in index.php
echo $_SERVER['REQUEST_URI'];
don't show idP=24 show /24/title-of-content and i need $_GET(idP)
i really apreciate some light on this stuff i am not expert on htaccess, thanks in advance to everybody.
There are two problems:
The first argument of RewriteRule matches against everything after the slash of the directory .htaccess is in, and before the query string. If .htaccess is in your www-root, and you get the url http://www.example.com/shiny/unicorns.php?are=shiny, you match against shiny/unicorns.php. It will never start with a slash, so ^/ will never match.
Rules are executed in order. If you go to http://sub.example.com/10/unicorns, the second rule will match first and rewrite the request to /blogs/index.php?url=10/unicorns. If you removed the leading slash the third rule would match, but normally you wouldn't want that. You want to have the third rule only match
You want to move the third rule up so it is the second rule. You want to make it more specific to only match with subdomains. You also know the first part contains only numbers, so use that knowledge to prevent blogs/index.php from matching your now second rule. You also need to prevent blogs/index.php from matching the now third rule to prevent it from matching itself. Last but not least I removed [L] from the now second rule, since the third rule will match anyway.
#the next line i can't make work to make nice url
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^([0-9]+)/([^/]+)$ blogs/index.php?idP=$1&name=$2
#this is to pass the subdomain like param and show the right content of the user
RewriteCond %{HTTP_HOST} !^www\.misite\.com [NC]
RewriteCond %{HTTP_HOST} ^([a-z0-9]+)\.misite\.com
RewriteCond %{REQUEST_URI} !/blogs/index\.php
RewriteRule ^ blogs/index.php?url=%1 [QSA,L]

htaccess ReWriteCond ReWriteRule - redirect occurs even when URL includes nonsense characters

We've just finished a major re-structuring our website and I'm trying to write a set of redirect rules of varying specificity. The redirects are half working:
They correctly re-route old URLs
They incorrectly also allow and re-route URLs that include text not specified in the
ReWriteCond statements (when instead I would expect to see a "Not Found" error message displayed in the browser.)
Statements in the .htaccess file (located in the root of the web site) include:
RewriteBase /
RewriteCond %{REQUEST_URI} /company/company-history.html
RewriteRule (.*)$ http://www.technofrolics.com/about/index.html
RewriteCond %{REQUEST_URI} /press
RewriteRule (.*)$ http://www.technofrolics.com/gallery/index.html
The above correctly executes the desired redirect
but also works when I enter the following after the domain name:
/youcanenteranytext/hereatall/anditstillworks/press
In other words, any text following the domain and preceding the conditional string seems to be allowed/ignored. Any advise on how to restrict the condition or rewrite rule to prevent this would be much appreciated!
Thanks, Margarita
You need to including bounds in your regular expressions when you try to match against %{REQUEST_URI}, the ^ indicates the beginning of the match.
RewriteCond %{REQUEST_URI} ^/company/company-history\.html
Will make it so requests for /garbage/stuff/comapny/company-history.html won't match. And likewise:
RewriteCond %{REQUEST_URI} ^/press
Will make it so requests for /youcanenteranytext/hereatall/anditstillworks/press won't match. You can additionally employ the $ in your regular expression to indicate the end of the match, so something like this:
RewriteCond %{REQUEST_URI} ^/press$
Will ONLY match requests for /press and not /something/press or /press/somethingelse or /press/.

mod_rewrite regex (too many redirects)

I am using mod_rewrite, to convert subdomains into directory urls. (solution from here). When I explicity write a rule for one subdomain, it works perfectly:
RewriteCond %{HTTP_HOST} ^[www\.]*sub-domain-name.domain-name.com [NC]
RewriteCond %{REQUEST_URI} !^/sub-domain-directory/.*
RewriteRule ^(.*) /sub-domain-directory/$1 [L]
However, if I try to match all subdomains, it results in 500 internal error (log says too many redirects). The code is:
RewriteCond %{HTTP_HOST} ^[www\.]*([a-z0-9-]+).domain-name.com [NC]
RewriteCond %{REQUEST_URI} !^/%1/.*
RewriteRule ^(.*) /%1/$1 [L]
Can anyone suggest what went wrong and how to fix it?
Your second RewriteCond will never return false, because you can't use backreferences within your test clauses (they're compiled during parsing, making this impossible since no variable expansion will take place). You're actually testing for paths beginning with the literal text /%1/, which isn't what you wanted. Given that you're operating in a per-directory context, the rule set will end up being applied again, resulting in a transformation like the following:
path -> sub/path
sub/path -> sub/sub/path
sub/sub/path -> sub/sub/sub/path
...
This goes on for about ten iterations before the server gets upset and throws a 500 error. There are a few different ways to fix this, but I'm going to chose one that most closely resembles the approach you were trying to take. I'd also modify that first RewriteCond, since the regular expression is a bit flawed:
RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.com$ [NC]
RewriteCond %1 !=www
RewriteCond %1#%{REQUEST_URI} !^([^#]+)#/\1/
RewriteRule .* /%1/$0 [L]
First, it checks the HTTP_HOST value and captures the subdomain, whatever it might be. Then, assuming you don't want this transformation to take place in the case of www, it makes sure that the capture does not match that. After that, it uses the regular expression's own internal backreferences to see if the REQUEST_URI begins with the subdomain value. If it doesn't, it prepends the subdomain as a directory, like you have now.
The potential problem with this approach is that it won't work correctly if you access a path beginning with the same name as the subdomain the request is sent to, like sub.example.com/sub/. An alternative is to check the REDIRECT_STATUS environment variable to see if an internal redirect has already been performed (that is, this prepending step has already occurred):
RewriteCond %{HTTP_HOST} ^([^.]+)\.example\.com$ [NC]
RewriteCond %1 !=www
RewriteCond %{ENV:REDIRECT_STATUS} =""
RewriteRule .* /%1/$0 [L]

Resources