This is EXACTLY the same case as: (htaccess) How to prevent a file from DIRECT URL ACCESS?
But, no one of codes provided by answers work for me. I tried 1 by 1, then tried to combine, but still not works. Here is my code:
# prevent direct image url access
# ----------
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http(s)://(www\.)?example\.com [NC]
RewriteCond %{HTTP_REFERER} !^http(s)://(www\.)?example\.com.*$ [NC]
# this not works
RewriteRule \.(png|gif|jpe?g)$ - [F]
# and this
RewriteRule \.(png|gif|jpe?g)$ - [F,NC]
# and this
RewriteRule \.(png|gif|jpe?g)$ https://example.com/wp-login.php [NC,R,L]
# even by combining them
# ----------
# /prevent direct image url access
The case simulation:
index.php has <img src="test.png" alt=""> and should be normally accessible. The requirement is: http://example.com/test.png shouldn't be accessible.
I use WordPress in wp-engine, and i think WordPres's default rewrite doesn't cause the problem since the code from answers are placed above WordPress rewrite.
UPDATE
I use PHP Version 5.5.9-1ubuntu4.14 on Apache 2 on wp engine
Your rules basically work for me, except for one thing:
The (s) is not doing what you think it does.
RewriteCond %{HTTP_REFERER} !^http(s)://(www\.)?example\.com [NC]
With parentheses you define a group, which doesn't make any sense at this point. If you remove the (s), it works for http.
If you want to use https too you have to write it like this:
RewriteCond %{HTTP_REFERER} !^https?://(www\.)?example\.com [NC]
The ? will make the preceding character (or group, if in parentheses) optional.
Related
We have tried adding the below hotlink protection inorder to save the bandwidth.
RewriteEngine on
RewriteCond %{HTTP_REFERER} !^https://(www\.)?domain [NC]
RewriteCond %{HTTP_REFERER} !^https://(www\.)?domain.*$ [NC]
RewriteRule \.(gif|GIF|jpg|JPG|PNG|png|jpeg|JPEG|mp4|MP4|mkv|MKV|webm|WEBM|ico|ICO)$ - [F]
This is working perfectly. Now, we want to exclude hotlink protection for the URL admin/thumbs (domain.tld/admin/thumbs/image.jpg) should be excluded from the hotlink protection.
We tried adding the below code however its not working. We searched on stackoverflow and multiple forums however none were helped us.
RewriteEngine on
RewriteCond %{HTTP_REFERER} !^https://(www\.)?domain [NC]
RewriteCond %{HTTP_REFERER} !^https://(www\.)?domain.*$ [NC]
RewriteCond %{REQUEST_URI} !/admin/thumbs$
RewriteRule \.(gif|GIF|jpg|JPG|PNG|png|jpeg|JPEG|mp4|MP4|mkv|MKV|webm|WEBM|ico|ICO)$ - [F]
Any help would be appreciated.
RewriteCond %{REQUEST_URI} !/admin/thumbs$
This creates an exception for any URL that ends with /admin/thumbs, whereas it would seem you want to create an exception for any file in the /admin/thumbs subirectory, ie. any URL that starts /admin/thumbs.
The suggestion !^admin/thumbs/? in comments is incorrect, since the REQUEST_URI server variable always starts with a slash so the condition will always be successful and the request is potentially blocked.
You should use the CondPattern !^/admin/thumbs($|/) instead to exclude requests for /admin/thumbs, /admin/thumbs/ and /admin/thumbs/<anything>, but not /admin/thumbsomething. For example:
RewriteCond %{REQUEST_URI} !^/admin/thumbs($|/)
Your existing rule can be further simplified/refined since the existing conditions that check the HTTP_REFERER are "the same", but also match too much. And the mixed case RewriteRule pattern can be flattened by using the NC (nocase) flag instead.
For example, the complete rule would become:
# Hotlink protection for images, except those in "/admin/thumbs/..."
RewriteCond %{HTTP_REFERER} !^https://(www\.)?example\.com($|/) [NC]
RewriteCond %{REQUEST_URI} !^/admin/thumbs($|/)
RewriteRule \.(gif|jpg|png|jpeg|mp4|mkv|webm|ico)$ - [NC,F]
Note that this also blocks an empty Referer header. This includes direct requests (anyone typing the URL directly into the browser's address bar) and any user that has suppressed the Referer in their browser (which some users do for increased privacy).
Alternative solution with additional .htaccess file
Alternatively, you could create an additional .htaccess in the /admin/thumbs/ subdirectory and simply disable the rewrite engine. For example:
RewriteEngine Off
This overrides and prevents the hotlink-protection directives in the parent config from being processed when anything within this subdirectory is requested.
I have the following snippet:
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^https?://%{SERVER_NAME}/
RewriteRule \.(js|css|png|jpg) - [R=404,L]
Simple and should work right? It seems to 404 the listed filetypes if I have referrers enabled on browser. Disabling referrers it then allows the files to be served. I have checked the value of %{SERVER_NAME} and it is www.mydomain.com I've tested this in multiple browsers and under HTTP and HTTPS, all have the same result. I used the below rewrite to check %{SERVER_NAME}'s value:
RewriteRule servername value_is_%{SERVER_NAME} [R=301,L]
The URL I get redirected to is then https://www.mydomain.com/value_is_www.mydomain.com
That being said the snippet should allow a referrer with that value or an empty one. But why is it being triggered? It's been driving me nuts for the past 2 hours, but it's 5am so I could be just crazy =o\ Thank you in advance, and I'm off to bed!
Problem is, you cannot use variables in conditional patterns (well, at least not until Apache 2.4) as the patterns are being precompiled during server startup.
For your particular problem, though, there's a simple workaround that you may use to mimic the condition:
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{SERVER_NAME}%{HTTP_REFERER} !^(.*)https?://\1/
RewriteRule \.(js|css|png|jpg) - [R=404,L]
Yep, that's all. You cannot use variables but sure can use back-references.
Oh ... and btw. Apache 2.4 does ship with expressions that may be used instead of the conditional patterns:
RewriteCond expr "! %{HTTP_REFERER} -strmatch '*://%{HTTP_HOST}/*'"
I have a hard time understanding htaccess mod_rewrite and while I found several related questions + answers, I unfortunately can't get my very specific situation to work correctly (mod_rewrite is even after hours of searching a book of seven seals to me to be honest)
I have foo.html and bar.html within my root directory. Now, I'd like to have foo.html as the default directory index (solved, easy), but from there I do not get it.
What I want to achieve is:
hiding the .html extensions
user should be able to type /bar to get /bar.html without seeing the .html (for every .html)
301 redirecting .html version
user should be able to type /bar.html and see /bar in the url (avoid duplicate, for every .html)
The most tricky part:
As foo.html is default directory index, typing / already shows (transparently) /foo.html, but I need typing /foo.html to resolve to / as well as typing /foo to resolve to /
Try putting these rules in the htaccess file in your document root:
RewriteEngine
# 1. hiding the .html extensions
RewriteCond %{REQUEST_URI} ^/(.*?)/?$
RewriteCond %{DOCUMENT_ROOT}/%1.html -f
RewriteRule ^ /%1.html [L]
# 2. 301 redirecting .html version
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([^\ ]+)\.html
RewriteCond %1 !foo$
RewriteRule ^ /%1 [L,R=301]
# 3. typing /foo.html to resolve to / as well as typing /foo to resolve to /
RewriteCond %{REQUEST_URI} ^/(.*?/?)foo(\.html)?$
RewriteRule ^ /%1 [L,R=301]
Also, make sure you have Multiviews turned off:
Options -Multiviews
The first rule has 2 conditions, the first groups the URI everything between the first / and a possible last /. The references it using %1 in the next condition which sees if the /path/to/www/document/root/%1.html is a file that exists. If both are true, it internally rewrites the URI to include a .html at the end.
The second rule has 2 conditions, the first matches against the actual request as opposed to the URI (which can change as the rules are being applied and rewrites happen). It sees if there's a request that ends with .html, and if so, the second condition makes sure that it isn't foo.html request (since the last rule handles that). If both are true, then it redirects the browser to the part of the URI without the html, again using %1 to reference the grouping in the match from the first condition ([^\ ]+).
The last rule checks if the request is for a foo or foo.html. If so, redirect removing that part of the URI.
I am using the one below and it works except that, in some strange case when working with a WARRANTY script for a client it just won't do the thing.
However; the other scripts that calls external scripts via iFrame in a sub-folder seems to work with the exception of the WARRANTY script. ...
Options +FollowSymLinks -MultiViews
RewriteEngine on
RewriteBase /
RewriteCond %{ENV:REDIRECT_END} =1
RewriteRule ^ - [L,NS]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^(.*?)\.(php|html?)$ $1 [R=301,NC,NS]
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule (.*)$ $1.html [L,E=END:1,NS]
RewriteCond %{REQUEST_FILENAME}\.htm -f
RewriteRule (.*)$ $1.htm [L,E=END:1,NS]
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule (.*)$ $1.php [L,E=END:1,NS]
I hope this Helps.
I'm having problems understanding how htaccess redirects work:
Can I do a background redirect, so that the user sees [subdomain].mydomain.com/?p1=v1..., but the server delivers mydomain.com/?sid=[subdomain]&p1=v1... without actual redirection, only server side.
This is what I have so far, it doesn't work:
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^([^./]+)\.localhost\.com/(.+) [NC]
RewriteRule (.+) localhost.com/index.php?supplier=$1&$2 [L]
I doesn't change anything.
Edit
I got this halfway working:
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^([^./]+)\.localhost\.com$ [NC]
RewriteRule /(.+)$ http://localhost\.com/eshop/?supplier=%1 [QSA,P]
Now I get a nice forbidden warning, if I remove the P flag it'll redirect, so the URL shows http://localhost.com/eshop/?supplier=[subdomain]&p1=v1... like it should, but the user must still see http://[subdomain].localhost.com/eshop/?p1=v1..., now how the remove that forbidden part...
(Notice my website is actually in a folder under www, but the eshop part will go away).
EDIT 2
IT WORKS, so as clmarquart said I needed mod_proxy. On WAMP you have to enable it by clicking on the tray icon->Apache->Apache modules and I enabled proxy_module and proxy_http_module, whatever they are.
Use the "P" flag to force use of the internal proxy. The RewriteURL target must be a full URL when using the proxy module. Use "%1" to "%9" as the captured data from the RewriteCond expression, and "$1" to "$9" for the captured data from the RewriteRule expression.
The following should work better (not tested though)
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^([^./]+)\.localhost\.com$ [NC]
RewriteRule (.+) http://localhost.com/index.php?supplier=%1&$1 [L,P]
Hi people#stackoverflow,
Maybe I have a fundamental misconception about the working of RewriteRule. Or maybe not. Nevertheless, I'm trying to figure this out now for two days, without any progress.
This is the currrent situation:
I have a Joomla website with SEF and mod_rewrite turned on.
This results in the URL:
mysite.com/index.php?option=com_remository&Itemid=7
being rewritten to:
mysite.com/sub-directory/sub-directory/0000-Business-files/
These are the lines that are currently used in my .htaccess (all standard Joomla)
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^([^\-]*)\-(.*)$ $1 $2 [N]
RewriteCond %{QUERY_STRING} mosConfig_[a-zA-Z_]{1,21}(=|\%3D) [OR]
RewriteCond %{QUERY_STRING} base64_encode.*\(.*\) [OR]
RewriteCond %{QUERY_STRING} (\<|%3C).*script.*(\>|%3E) [NC,OR]
RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR]
RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2})
RewriteRule ^(.*)$ index.php [F,L]
# RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{REQUEST_URI} (/|\.php|\.html|\.htm|\.feed|\.pdf|\.raw|/[^.]*)$ [NC]
RewriteRule (.*) index.php
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]
This is what I want to achieve:
When a visitor uses this URL
mysite.com/sub directory/sub directory/0000 Business files/
it should lead him to the right page.
Although I know it's not the best idea to use spaces in a URL, I'm confronted with the fact that these 'spacious' URL's are used in a PDF, that's already been issued.
I thought I could use mod_rewrite to rewrite these URL's. But all I get is 'page not found'
I've added this rule on top of the .htaccess file:
RewriteRule ^([^\-]*)\-(.*)$ $1 $2 [N]
But this is not working. What am I doing wrong? Or, also possible, am I missing the point on when and how to use mod_rewrite?
rgds, Eric
First off, the default behavior of apache is usually to allow direct URLs that map to the underlying file system (relative to the document root), and you should use RewriteRule when you want to work around that. Looking at your question, it seems like you want to browse the filesystem and so you should not use a RewriteRule.
If mysite.com/sub+diretory/sub+directory/0000+Business+files/ doesn't work (without your rule), I'm wondering: do you have that directory structure on your server? I.e. does it look like this?
[document root]/index.php
[document root]/sub directory/sub directory/0000 Business files/
If not, I'm not sure I understand what you're trying to achieve, and what you mean by the visitor being "lead to the right page". Could you provide an example URL that the user provides, and the corresponding URL (or file system path) that you want the user to be served.
Regarding your rewrite rule, I'm not even sure that it is allowed, and I'm surprised you don't get a 500 Internal Server Error. RewriteRule takes two arguments (matching pattern and substitution) and optionally some flags, but because of the space between $1 and $2 you're supplying three arguments (+ flags).
EDIT: I got the pattern wrong, but it still doesn't make much sense. It matches against any URL that has at least one dash in it, and then picks out the parts before and after the first dash. So, for a URL like "this-is-a-url-path/to-a-file/on-the-server", $1 would be "this" and $2 would be "is-a-url-path/to-a-file/on-the-server". Again, if I had some example URLs and their corresponding rewrites, I could help you find the right pattern.
On a side note, spaces aren't allowed in URLs, but the browser and server probably does some work behind the scenes, allowing your PDFs to be picked up correctly.