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?

Author: Wallace Maxters, 2018-09-21

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.

 2
Author: Wallace Maxters, 2018-09-21 20:16:13