I have a site that plays music. The user can listen to a song only by navigating to a specific site on the server that retrieves the music file and presents it to the user through the audio html tag. In order to prevent the users from accessing directly the song's address I implemented a year ago the following htaccess script:
Header set Access-Control-Allow-Origin "http://myexamplesite.000webhostapp.com/"
ErrorDocument 403 /error404.php
ErrorDocument 404 /error404.php
Options -Indexes
RewriteEngine on
RewriteCond %{HTTP_REFERER} !^http://(myexamplesite\.)?000webhostapp [NC]
RewriteCond %{HTTP_REFERER} !^http://(myexamplesite\.)?000webhostapp.*$ [NC]
RewriteRule \.(mp3|png|jpg)$ - [F]
RewriteEngine on
RewriteCond %{HTTP_REFERER} !^http(s)?://(www.)?(myexamplesite.000webhostapp.com)(/)?.*$ [NC]
RewriteRule .*.(.zip|.rar|.exe|.mp3|.pdf|.swf|.psd)$ http://myexamplesite.000webhostapp.com/error404.php [R,NC]
This script has been working flawlessly until a week ago, when chrome and mozilla updated and since then I see the error below on the chrome developer tools.
The browser cannot load any media such as images, documents and music files as described in the script above.
When I remove the script the problem is resolved but by doing so lets the users access and hotlink my resources with great ease.
The most confusing part is that mobile browsers have not any problem while desktop ones show errors. For example the updated chrome and firefox mobile browsers can access the site normally with all those resources without the issues dealt on desktop browsers.
I have tested if the problem appears in various computers and it still appears.
I believe that the problem shows up in newly updated browsers because the problem does not show up on elder versions of mozilla firefox desktop browser (version 47).
What causes this problem? How can I deal with it? I need a solution that does not override the main purpose of the htaccess script; to not allow direct access and hotlinking to sensitive media (images, pdf documents and mp3 files).
I want to redirect all urls without www to the www-version:
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\.domain\.tld$ [NC]
RewriteRule ^(.*)$ http://www.domain.tld/$1 [R=301,L]
that works for every browser except google chrome with subfolders. That means http://domain.tld is redirected to http://www.domain.tld like it should but when I want to access http://domain.tld/subfolder I get a 'ERR_NAME_NOT_RESOLVED' error in chrome.
Firefox, IE, Safari are working.
I have no definite answer for you, but these few hint may help you :
idea 1
Chrome uses google own's DNS, so it might be that it is trying to reach directly the ip host known as www.domain.tld for wich it does'nt find a record.
Idea 2
You might want to install fiddler and run a trace to see exactly what is exchanged between chrome and the internet. This way you'll know if your apache conf is firing the redirect correctly.
I tried typing both adresses in chrome directly : none is recognized by the omnibar (which suggests to me an issue with google dns mirrors)
I'm trying to make a file only accessible when you're on a specific page.
Like download.php, the user can click a link to the file and the download starts without problems.
But if you go to the link in the browser directly it should not work.
Could I use .htaccess for this? or how would I do this?
This is possible with .htaccess by checking for the ${HTTP_REFERER}, which is the previous url you were on.
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^http://www.example.com/download.php
RewriteRule myFile.zip - [R=403,L]
This checks if the previous page was download.php, otherwise it rewrites the request for myFile.zip to a 403 error page.
Note that it is possible to forge a referer by intercepting / creating your own request. This does not provide 100% security.
I have a bot that is trying to access my site by entering what appear to be keywords or passcodes. The entries come from dozens of different IPs and locations, so I can't block via IP, location, or referrer.
The bot attempts to visit a page like this:
http://www.website.com/valid-page/?kwd=du2c3m
Always in this format and the 'valid-page' is always the same page. I get as many as 400 of these attempts a day, and have been getting them for over a week.
My question is, how can I use .htaccess to block these attempts? I'm sure it's relatively straightforward - like blocking all '?kwd' urls or blocking all subdirectories of the 'valid-page'
Any thoughts? I really appreciate it.
What's unique that these bots are doing that normal humans browsing your site aren't doing? If it's a matter of a user-agent (should be in your access logs), then block that user-agent:
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} the_bot_useragent
RewriteRule ^ - [L,F]
If it's a matter of the weird query string, then block that query string:
RewriteEngine On
RewriteCond %{QUERY_STRING} kwd=
RewriteRule ^ - [L,F]
If it's a matter of all the bots originating from an IP or a subnet:
Deny 123.45.67
# or
Deny 123.123.123.123
I'm having trouble figuring this one out. I'm trying to direct mobile traffic to the mobile version of a website via HTACCESS User-Agent sniffing, like so:
RewriteCond %{HTTP_USER_AGENT} (android|blackberry|ipad|iphone|ipod|iemobile|mini|mobi|palmos|webos|googlebot\-mobile) [NC]
RewriteCond %{HTTP_HOST} ^mobile\.mywebsite\.com$
RewriteRule ^([aA0-zZ9\-\/]*)/([^/]*)$ /index.php?page=$1&q=$2&q2=$3&setview=mobile [L,QSA]
The string mini|mobi is where the Opera Mini browser should be detected. However, this does NOT happen. I've also changed that string to opera m and other variations. Still no luck.
This rewrite condition appears to work with other mobile browsers, but not Opera, and I don't understand why. Even the second condition, which checks for an explicit pointer to the mobile. subdomain also fails to deliver the mobile content.
I'm not an HTACCESS guru, so my first guess is that my syntax is wrong. But why does this work on other mobile browsers and not Opera Mini?
Thanks for looking!
UPDATE: 2012-06-08
I actually resorted to a different method by using PHP to check headers. For some reason my HTACCESS file did not detect certain header information. Even though karlcow's answer would validate, I was having trouble getting the iPhone and third-party Android browsers to validate. It wasn't until a page was passed to the PHP interpreter that I was able to read the information. I guess I just don't understand how that works.
Anyway, I borrowed code from an Internet search that I placed into a library function:
function get_device_view() {
$view='desktop';
if(preg_match('/(up.browser|up.link|mmp|symbian|smartphone|midp|wap|phone|android)/i', strtolower($_SERVER['HTTP_USER_AGENT'])))
$view='mobile';
if((strpos(strtolower($_SERVER['HTTP_ACCEPT']),'application/vnd.wap.xhtml+xml')>0) || ((isset($_SERVER['HTTP_X_WAP_PROFILE']) || isset($_SERVER['HTTP_PROFILE']))))
$view='mobile';
$mobile_ua=strtolower(substr($_SERVER['HTTP_USER_AGENT'],0,4));
$mobile_agents=array(
'w3c ','acs-','alav','alca','amoi','audi','avan','benq','bird','blac',
'blaz','brew','cell','cldc','cmd-','dang','doco','eric','hipt','inno',
'ipaq','java','jigs','kddi','keji','leno','lg-c','lg-d','lg-g','lge-',
'maui','maxo','midp','mits','mmef','mobi','mot-','moto','mwbp','nec-',
'newt','noki','oper','palm','pana','pant','phil','play','port','prox',
'qwap','sage','sams','sany','sch-','sec-','send','seri','sgh-','shar',
'sie-','siem','smal','smar','sony','sph-','symb','t-mo','teli','tim-',
'tosh','tsm-','upg1','upsi','vk-v','voda','wap-','wapa','wapi','wapp',
'wapr','webc','winw','winw','xda ','xda-');
if(in_array($mobile_ua,$mobile_agents))
$view='mobile';
if (strpos(strtolower($_SERVER['ALL_HTTP']),'OperaMini')>0)
$view='mobile';
if(strpos(strtolower($_SERVER['HTTP_USER_AGENT']),'windows')>0)
$view='desktop';
return $view;
}
This function is called as part of a strapper process for the website so that before anything is output, the $view is returned so that appropriate pages and stylesheets are loaded.
Additionally, I modified my HTACCESS file to contain the following:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{HTTP_COOKIE} !((^|;\s*)DD_VIEW=([^;]+))
RewriteCond %{HTTP_HOST} mobile\.buffalosbigdeal\.com
RewriteRule ^([aA0-zZ9\-\/]*)/*([^/]*)$ /index.php?page=$1&q=$2&q2=$3&setview=mobile [L,QSA]
As you can see I'm only redirecting explicit calls for the mobile. subdomain, and those not containing a cookie which retains the $view set during the strapper process.
My original intent was to perform browser detection exclusively using HTACCESS; because of simplicity and under premise of mod_rewrite's power. But in my frustration, and to meet the deadline, I compromised by settling for a more chunky method that may require more maintenance in the future.
Lesson learned: Build responsive websites based on browser capabilities (ie: resolution, touch, and DOM level), and do not rely heavily on user-agent strings. Have we yet a solution like this?
Thanks for looking.
Note that the pattern of Opera Mini string is
Opera/9.80 (J2ME/MIDP; Opera Mini/$CLIENT_VERSION/$SERVER_VERSION; U; $LANGUAGE) Presto/$PRESTO_VERSION
Mini is with an uppercase M. Hmm but you put NC which is for nocase, so that's not it.
Just to be sure could you try
RewriteCond %{HTTP_USER_AGENT} (android|blackberry|ipad|iphone|ipod|iemobile|mobi|palmos|webos|googlebot\-mobile) [NC,OR]
RewriteCond %{HTTP_USER_AGENT} Opera\ Mini
Should it be
if (strpos(strtolower($_SERVER['HTTP_USER_AGENT']),'operamini')>0)
or should it be
if (strpos(strtolower($_SERVER['ALL_HTTP']),'operamini')>0)
I get a debug error using ALL_HTTP, but the error goes away when I use HTTP_USER_AGENT
Here is the debug error, as follows:
Debug Notice: Undefined index: ALL_HTTP in header.php on line 29