We're currently using folders inside webroot to store images and videos which we're loading in views (using the usual html image helper) that require log in.
How can I prevent outside visitors from just doing a site.com/img/photos/1.jpg url and having access to the images?
From what I understand I can't really use media views to render an image inside a proper view, and I can't figure out if there's a solution through htaccess manipulation.
Which is the best practise for this?
Perhaps choosing to go with a non-webroot folder would be best (although that would make it harder in the file-storing part)?
As poncha suggested, I tried editing the main .htaccess file into this
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP_REFERER} !localhost
RewriteCond %{REQUEST_URI} ^app/webroot/img/
RewriteRule .* / [L,F]
RewriteRule ^$ app/webroot/ [L]
RewriteRule (.*) app/webroot/$1 [L]
</IfModule>
But the rewrite base line seems to be forbidding access to the whole site, and without it there seems to be no change in img access.
Edit 2:
Editing the htaccess inside webroot:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]
# this RewriteCond is needed to avoid rewrite loops
RewriteCond %{REQUEST_URI} !^/app/webroot/
RewriteRule (.*) app/webroot/$1 [L,R]
RewriteCond %{HTTP_REFERER} !127.0.0.1
RewriteCond %{REQUEST_URI} ^/app/webroot/img/
RewriteRule .* - [L,F]
</IfModule>
This checks if Referer http header is set to something containing your domain, and denies access to img/ folder if not.
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_REFERER} !site.com
RewriteCond %{REQUEST_URI} ^img/
RewriteRule .* / [L,F]
Note: it is easy enough to "break" this protection if someone wants to steal your content, however, it does prevent hotlinking without the need to produce some sort of script that would pass thorugh all the images/videos to check if access should be granted.
EDIT:
In case your website is not in /, You have two options:
Change RewriteBase to reflect the base uri of the site (eg RewriteBase /app/webroot/)
Change RewriteCond to reflect the path from / (eg RewriteCond ^app/webroot/img/)
The second option is preferred in your case because you have other rules there
EDIT2:
In your case, the whole set should look like this:
RewriteEngine on
RewriteBase /
# this RewriteCond is needed to avoid rewrite loops
RewriteCond %{REQUEST_URI} !^/app/webroot/
RewriteRule (.*) app/webroot/$1 [L,R]
RewriteCond %{HTTP_REFERER} !localhost
RewriteCond %{REQUEST_URI} ^/app/webroot/img/
RewriteRule .* - [L,F]
Related
What am I trying to achieve?
I want to convert all URL's that are within the /migrate directory (and subdirectories) to lowercase.
What have I done?
I have migrated my website from DNN to Wordpress. Therefore I have URL's in my posts that reference images with a combination of upper and lowercase letters.
All of my directories and files on disk in the /migrate folder (and subfolders) are lowercase.
When I view an article, if the reference to the image has an uppercase character, I am getting a 404 which is expected.
For example:
https://xxx.domain.net/wp-content/migrate/ABC/image.jpg
https://xxx.domain.net/wp-content/migrate/Xyz/image.jpg
https://xxx.domain.net/wp-content/migrate/abc/Image.jpg
https://xxx.domain.net/wp-content/migrate/ABC/Xyz/image.jpg
So after reading various articles online and on here I tried a few things:
1) Enabled mod_speling and added this to apache2.conf
LoadModule speling_module /usr/lib/apache2/modules/mod_speling.so
<IfModule mod_speling.c>
CheckSpelling On
CheckCaseOnly On
</IfModule>
This didn't work, continued to get 404's.
2) Tired to use Rewritemap in my /etc/sites-enabled/mysite.conf file.
RewriteMap lc int:tolower
RewriteCond %{REQUEST_URI} /migrate [A-Z]
RewriteRule ^(.*)$ /${lc:$1} [R=301,L]
However this would rewrite all URL's to lowercase and it broke some of the Wordpress plugins and editors as the files on disk had uppercase characters.
My .htaccess file in the Wordpress root directory is as follows:
RewriteEngine on
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule ^(.*) - [E=HTTP_AUTHORIZATION:%1]
RewriteCond %{HTTPS} !=on
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]
#BEGIN Wordpress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
After hours and hours of trying different things and reading through the logs, I have worked this out!
Basically I needed to ignore all the other Wordpress directories from rewriting.
RewriteMap lc int:tolower
RewriteCond %{REQUEST_URI} [A-Z]
RewriteCond %{REQUEST_URI} !^/wp-content/uploads/
RewriteCond %{REQUEST_URI} !^/wp-content/themes/
RewriteCond %{REQUEST_URI} !^/wp-content/plugins/
RewriteCond %{REQUEST_URI} !^/wp-includes/
RewriteCond %{REQUEST_URI} !^/wp-admin/
RewriteRule ^/?(.*)$ /${lc:$1} [R=301,L]
I am using CMSMADESIMPLE for a website. It can generate search engine friendly URLs using a .htaccess file and mod_rewrite.
BUT it is possible to insert anything between the base url and the requested page. For example all these URLs will work:
www.example.com/aboutus
www.example.com/home/aboutus
www.example.com/any/rubbish/i/enter/aboutus
I have seen other sites using Wordpress where it is possible to enter the same in the address window, but it will redirect back to the lowest level i.e. www.example.com/aboutus. I would like to achieve the same thing but cannot master .htaccess to do it.
The relevant bits of the .htaccess file are:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ index.php?page=$1 [QSA]
</IfModule>
I am assuming that this is something that can be achieved just using mod_rewrite and doesn't require changes to the PHP code within the CMS.
If that's not possible I would like to setup a permanent redirect from some URLs within the CMS which have been indexed by Google.
i.e From www.example.com/home/aboutus to www.example.com/aboutus
I tried adding a RewriteRule to .htaccess without success:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
RewriteRule home/aboutus aboutus [R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ index.php?page=$1 [QSA]
</IfModule>
Any help appreciated.
Look at the sample htaccess.txt file in the doc folder. There is a section about parent child.
# Rewrites urls in the form of /parent/child/
# but only rewrites if the requested URL is not a file or directory
#
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ index.php?page=$1 [QSA]
I have two Codeigniter sites, one sitting within the subdirectory of the other. I need some help modifying my htaccess file to remove index.php from both.
The first site, http://subdomain.domain.com is stored in /home/sites/subdomain/www/html/
The second, http://test.subdomain.domain.com lives in /home/sites/subdomain/www/html/app_staging/
This is my .htacess file from /home/sites/subdomain/www/html/:
RewriteEngine On
# Rewrite the main domain
RewriteCond %{HTTP_HOST} !test.subdomain.domain.com
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?/$1 [L]
# Rewrite the sub domain
RewriteCond %{HTTP_HOST} test.subdomain.domain.com
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/(.*)$ /app_staging/index.php?/$1 [L]
This is removing index.php from the from the first site, everything is ok there. On the second site, I can load the default controller form http://test.subdomain.domain.com, but subsequent pages return a 404 from the server. What are my next steps?
You should put each of two .htaccess files inside their own root CI folder.
Personally, I prefer restricting requested files and/or folders in order to prevent them from being treated by RewriteRule.
So, for the first file which is located at /home/sites/subdomain/www/html/:
<IfModule mod_rewrite.c>
Options +FollowSymLinks
RewriteEngine on
RewriteCond $1 !^(index\.php|robots\.txt|favicon\.ico|public)
RewriteRule ^(.*)$ /index.php/$1 [L]
</IfModule>
And for the other one is located at /home/sites/subdomain/www/html/app_staging/:
<IfModule mod_rewrite.c>
Options +FollowSymLinks
RewriteEngine on
RewriteCond $1 !^(index\.php|robots\.txt|favicon\.ico|public)
RewriteRule ^(.*)$ /app_staging/index.php/$1 [L]
</IfModule>
Note: You must add css and other folders (like public) to RewriteCond if you don’t want them to be treated by RewriteRule.
As a side-note: You might want to prevent directory listing by using the following inside each .htaccess file:
<IfModule mod_autoindex.c>
Options -Indexes
</IfModule>
I'm trying to write a rewrite rule in addition to wordpress's :
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
I would not like everything to redirect to the main page. I have multiple sub-directories which need to be redirected too : http://www.example.com/sub1 and http://www.example.com/sub2. I'm doing this so my content can be loaded via Ajax.
I thought this would simply be
RewriteRule ^/(sub1|sub2)/(.*)$ http://www.example.com/$1/ [L]
Which I placed in the block here:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/(sub1|sub2)/(.*)$ http://www.example.com/$1/ [L]
RewriteRule . /index.php [L]
</IfModule>
Perhaps with wordpress you must use wp_rewrite_rule? I figured I could mess with the .htaccess file, get my rule to work, then move it over to functions.
any help would be appreciated.
Thanks.
UPDATE:
I've also tried to set the .htacces file back to the wordpress default... and add this code to the functions.php file for my child theme:
function AJAX_rewrite_rule() {
add_rewrite_rule(
'^/(sub1|sub2)/(.*)$',
'http://www.example.com/$1',
'top' );
};
add_action( 'init', 'AJAX_rewrite_rule' );
Seems to slow the load of everything down, but all files not found are still redirected to the main page, not the subdirectory.
UPDATE #2
I think I was going the wrong direction, as add_rewrite_rule is only to add a rule to the structure already put in place by wordpress. This all works by interpreting URL's, and changing them to variables for a DB query run by index.
I'm pretty sure I need to use $wp_rewrite->non_wp_rules. If anyone has more of an idea, let me know.
Try this, you seem to have ine bad line there:
<IfModule mod_rewrite.c>
RewriteEngine On
# RewriteBase /
# RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f #Means DONT redirect if file exists.
RewriteCond %{REQUEST_FILENAME} !-d #Means DONT redirect if directory exists.
RewriteCond %{REQUEST_URI} !^/sub1/
RewriteCond %{REQUEST_URI} !^/sub2/
# RewriteRule ^/(sub1|sub2)/(.*)$ http://www.example.com/$1/ [L]
RewriteRule . /index.php [L]
</IfModule>
What happens is, every time you add a "RewriteRule" all the "RewriteCond" are applied to that rule, and then you start with a blank slate:
RewriteCond A
RewriteCond B
RewriteCond C
RewriteRule Whatever [L] #This applies A, B, and C
RewriteRule Another [L] #This applies no rules
Perhaps that will help.
Also, you may try adding your "RewriteRule ^/(sub1|sub2)/(.*)$ http://www.example.com/$1/ [L]" right after "RewriteEngine On" if that doesn't work…
quick question about mod rewriting on a sub-directory when i already have a rewrite rule on the webroot to remove 'index.php'
my .htaccess looks like this:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
i have an API directory (/webroot/api/index.php) where i want to have a RESTful API (Restler) to serve requests into the application- so my question is..
to make RESTful requests i need to use the following URL format:
/webroot/api/index.php/user/get/ (to get all the users)
what i would like to achieve is something in the form:
/webroot/api/user/get/ (return a list of users)
which still retaining the base rewrite rules for the main website
/webroot/members/ (display a list of users in the main applications)
many thanks,
Justen
Your base rewrites look odd.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
This says that if we match index.php we are done (and no rewrite takes place). Is that what you want? If the request is exactly for /index.php with no trailing material, then it is left alone.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
To remove index.php you want something like:
RewriteRule ^index.php/(.*) $1 [L]
E.g. index.php/foo goes to foo (relative rewrite: then RewriteBase gets tacked on it turning into the /foo URL to feed back into the request pipeline.)