Make php files under a certain directory unaccessible using htaccess - apache

I have a .htaccess file in place to redirect all requests that does not hit an existing file or directory to be parsed by my index.php file like this:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
# Our app bootstrap file is index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L]
</IfModule>
This is working fine, But I'd like also to add another rule to prevent any direct access to php files under a certain directory, routing those calls to the same index.php file.
Like so:
request for example.com/something.php -> ok
request for example.com/themes/(anythinggoeshere)/somefile.php -> not
ok, route trough index.php
request for example.com/themes/(anythinggoeshere)/banner.png -> ok
I'm looking for a way to make those "rules" work to everything under the "themes" folder without breaking my current ones.
Thanks!

You can have a new rule to handle those .php requests:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
# handle .php requests via index.php
RewriteCond %{REQUEST_URI} !^/themes/ [NC]
RewriteRule ^[^/]+/.+?\.php$ index.php?/$1 [L,NC]
# Our app bootstrap file is index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L]
</IfModule>

Related

Rewrite existing file request to subdirectory

I have a php framework on a shared hosting and this is my directory structure:
root (can't change because of shared hosting; here's the .htaccess)
vendor
web (index.php, assets in subfolders like css, images or js)
My .htaccess looks like this:
<IfModule mod_rewrite.c>
Options -MultiViews
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ web/index.php [L]
</IfModule>
Now the framework routing works, but I want Apache to search all existing files (${REQUEST_FILENAME} !-f) only in the web folder, not from the root level.
Example:
http://www.domain.tld/hello/world (virtual path) is rewritten to index.php
http://www.domain.tld/css/bootstrap.css is not found, because the file is in the web/css folder.
http://www.domain.tld/web/css/bootstrap.css would match, because of the RewriteCond %{REQUEST_FILENAME} !-f
Is it possible to combine RewriteCond %{REQUEST_FILENAME} !-f with a folder rewrite for existing files only? All other request must be rewritten to the index.php
All in all I want it similar as setting the VirtualHost->DocumentRoot to the web folder.
Thanks!
You can use these rules in site root .htaccess:
<IfModule mod_rewrite.c>
Options -MultiViews
RewriteEngine On
RewriteBase /
RewriteRule ^/?$ web/index.php [L]
# if file is found in web/ folder then route it
RewriteCond %{DOCUMENT_ROOT}/web/$1 -f
RewriteRule ^(.+)$ web/$1 [L]
# otherwise route it to web/index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ web/index.php [L]
</IfModule>

.htaccess file wont redirect to /public folder (laravel issue)

I have folder /var/www/html/project/himp and there is my laravel installation.
In /var/www/html/project is my landing page index.html and some css files.
Inside /himp folder I have .htaccess:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} !^public
RewriteRule ^(.*)$ public/$1 [L]
</IfModule>
also in /himp/public folder I have also .htaccess:
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
RewriteEngine On
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
Now when I go to the domain.com/himp/public I get Laravel installation and startup screen but when I go to the domain.com/himp I get just folder views, so there is no redirection to public folder ...
Why? What can be a problem here? Please help.
Contrary to the pattern in RewriteRule (see "What is matched?"), the variable REQUEST_URI contains the full path, including /himp. So the condition should be either
RewriteCond %{REQUEST_URI} !/public
without a beginning of string anchor ^, or you must include the full path
RewriteCond %{REQUEST_URI} !^/himp/public

Laravel on Plesk-Server - Only accessible by calling /public

When setting up a fresh Laravel installation, we have to run it using domain.com/public instead of domain.com.
I googled after this problem and I saw that this could be because of mod_rewrite not being enabled. However, we are running Plesk on our server and their documentation at http://download1.parallels.com/Plesk/PP12/12.0/Doc/en-US/online/plesk-administrator-guide/index.htm?fileName=74206.htm says:
The mod_rewrite module is enabled by default in Apache that comes with Plesk for Linux. To make use of the functionality, you will need to create an .htaccess file containing the desired rewrite rules - refer to the Apache documentation for more information.
Laravel is working fine, if I move the contents of public in the main folder, and the rest in a /laravel folder (simply have to adopt the main index.php file).
However I would like to keep the original file structure.
Any tips?
Just use .htaccess to redirect from / to /public. Maybe similar to this
RewriteCond %{REQUEST_URI} !^public
RewriteRule ^(.*)$ public/$1 [L]
You need two .htaccess files. One inside the Laravel Project and the other one inside your domain.com
Laravel Project (/var/www/vhosts/domain.com/public/.htaccess)
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ public/index.php?$1 [L,QSA]
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Send Requests To Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
main domain (/var/www/vhosts/domain.com/.htaccess)
RewriteEngine on
RewriteCond %{REQUEST_URI} !^public
RewriteRule ^(.*)$ public/$1 [L]

Remove htaccess action to public directories

How I can disable the rewrite rule to access directories into Laravel public directory, without affecting my Laravel project?
ex: I have (asd) directory into my public Laravel but I can't access
if I remove
RewriteRule ^ index.php [L]
line and I can access, but this affects my Laravel project.
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
RewriteEngine On
RewriteBase /
# Redirect Trailing Slashes...
RewriteRule ^(.*)/$ /$1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
This line is doing exactly what you're asking for (which is to apply the rule on anything except real directories):
RewriteCond %{REQUEST_FILENAME} !-d
However, you seem to have an issue with your rewriting.
Did you take a look at your access logs within your web server ?

Trying to apply mod rewrite rule for e.g. css/style.123456.css -> css/style.min.css

I'm trying to create a rewrite rule for any js/css files with a given time stamp to point to the real files but not really sure how to do it. Below is my attempt but when I try this it seems to mess up my
AddDefaultCharset UTF-8
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(js|css)\/(.+)\.(\d+)\.(js|css)$ $1/$2.min.$4
RewriteRule ^(.*)$ index.php?_url=/$1 [QSA,L]
</IfModule>
By the way, my folder structure is as follows:
/public/
/public/index.php
/public/.htaccess (rules are written in this file)
/public/css/style.min.css
/public/js/all.min.js
Also, the apache vhost conf file will direct requests to the /public/ directory. This I can verify works. But when I try to view /css/style.12235543543.css (which I want to point to /css/style.min.css) it just goes through the front controller (index.php) instead of the stylesheet.
Use that:
AddDefaultCharset UTF-8
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
RewriteRule ^(js|css)/(.+)\.(\d+)\.(js|css)$ $1/$2.min.$4 [L]
RewriteRule ^(.*)$ index.php?_url=/$1 [QSA,L]
</IfModule>