Protect php files from direct access without blocking to the system
In terms of routing, my site is divided into two parts: first, it has an app folder inside the root, where is contained all the files of the site in MVC system, and, second, next to the app, a set of folders and file that serve to intercept the URL type and redact to route within the app that will call the controller that will call the view and that whole story.
EDIT: the server is in Apache!
site.com
|
+--- app
| |
| +--- public
| +--- route
| +--- ctrl
| +--- model
| +--- view
| +--- bla
| +--- bla
| +--- bla
|
+--- tag
| |
| +---tag1.php
| +---tag2.php
| +---tag3.php
|
+--- page
| |
| +---page1.php
| +---page2.php
| +---page3.php
|
+--- index.php
Well, what I want to do now is: Block direct access via html to all files of the php type, which inside the app folder, but so that they are still available if they are regained via includes and ajaxs.
I know this question has been asked N times around here but the problem is that all solutions (be They via .htaccess or via direct editing in the php file) blocks access to the system as well and the site does not load.
Anyway, how to do it the right way?
1 answers
I'll be simple and straightforward. The solution I would give to this would be to structurally divide in the application what is public than what is not.
How?
Creating a folder containing all files that will be publicly accessible and pointing Apache to read from that folder. The other files, regardless of not being accessible to the client (browser), would be accessible to the script, perfectly serving the dependencies.
Consider the following scenario: I want the user to access my index.php
, contact.php
and about.html
, but it cannot access any database connection script or project classes, which is inside the app
folder.
I would do so (simulating Linux environment):
projeto/
public/
index.php
contact.php
about.html
css/
default.css
js/
default.js
jQuery.js
app/
classes/
DBConnection.php
Mail.php
Noticed the structure above? You can simply point your Apache VirtualHost directly to the projeto/public
folder, like this:
<VirtualHost *:80>
#importante apontar para public, não para raiz do projeto
DocumentRoot /var/www/projeto/public
ServerName meusite.com
</VirtualHost>
With this, when you access your site, you will limit the user to only access index.php
, contact.php
and about.html
, as well as the folders js
and css
, with their respective contents.
Note : if you are using OS like Ubuntu, you will probably access VirtualHost in the /etc/apache2/sites-avaliable
folder.
This is how I do it in all my applications.
And you can, at least public/index.php
, make an include of a file that is in the app/classes
folder normally. PHP will be able to access, but the browser will not.
For example, using a structure similar to that cited previously, we will access by public/index.php
settings stored in a folder app
.
Like this:
app/
constantes.php
functions.php
views/
index.tpl
public/
index.php
In the file app/constantes.php
, I have:
define('ROOT_DIR', realpath(__DIR__ . '/../'));
define('VIEWS_DIR', ROOT_DIR . '/views');
In my public/index.php
, I do
<?php
include __DIR__ . '/../app/constantes.php';
exit(ROOT_DIR); // '/var/www/projeto
Summarizing: I set public
to the root of the application.
The mistake many people make is to set the root as the project folder. However, depending on the situation, this can be bad, and forces the programmer to be creating several messes in .htaccess
, without need something.
The pattern used above is followed by the Laravel Framework.