Protect php files from direct access without locking to the system

Asked

Viewed 2,585 times

3

In terms of routing, my site is divided into two parts: First, it has an app folder inside root, where it 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 re-add to route inside the app that will call the controller that will call the view and the 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 php type files, which inside the app folder, but so that they are still available if they are re-conquered via includes and ajaxs.

I know this question has been asked N times here but the problem is that all solutions (either 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 answer

2

I’m going to be simple and straightforward. The solution I would give for this would be to structurally divide in the application what is public of what is not.

Like?

Creating a folder that contains all the files that will be accessible to the public and pointing Apache to read from that folder. The other files, which are not 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 mine index.php, contact.php and about.html, however it cannot access any connection script with database or project classes, which is inside the folder app.

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

Notice the above structure? You can simply point your Apache’s Virtualhost directly to the folder projeto/public, thus:

 <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 website, you will limit the user to access only index.php, contact.php and about.html, as well as the folders js and css, with their respective contents.

Observing: If you are using OS as Ubuntu, you will probably access Virtualhost in the folder /etc/apache2/sites-avaliable.

That’s how I do it in all my apps.

And you can, by public/index.php, make a include of a file that is in the folder app/classes normally. PHP will be able to access, but not the browser.

For example, using a structure similar to the one mentioned above, we will access through public/index.php settings stored in a folder app.

Thus:

app/
   constantes.php
   functions.php
views/
     index.tpl
public/
     index.php

In the archive 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

To summarize: Defini public as the root of the application.

The mistake many people make is to define the root as the project folder. However, depending on the situation, this can be bad, and forces the programmer to keep creating various messes in the .htaccess, needlessly.

The pattern used above is followed by the Laravel Framework.

  • 1

    Please never imitate what the CodeIgniter makes, which is to put an if in each class script to check if a constant, defined from the index.php, exists, to determine if you accessed the script directly. This is too ugly.

  • So everything private puts in the folder app?

  • @Jorgematheus or any other at the root. The important thing is to remember that with this setting apache will only be able to access what is inside public, but PHP will be able to do the include of things from outside.

  • Show. In case I have a folder called img, not to access, I put a file index.php redirecting to the home page or with a message 403. With this structure cited by you, the folder img would enter the folder "private"?

  • Good idea! But there’s something wrong! I have to put the . htaccess in root (meusite.com) with the following commands: <Virtualhost *:80> Documentroot /meusite.com/public/ Servername meusite.com </Virtualhost> And put everything outside of app inside the public folder?

  • @Jorgematheus protect images is another story, but I would do it like this: the same thing I did earlier, leaving the folder img out of public. If the user authenticates, I use a file img.php and with the readfile I read the "private" image, responding to the user’s image content. Let’s chat about it, which I explain to you better

  • @Jhenry are you using which operating system? That’s not .htaccess, this is the Virtualhost of the site.

  • My OS is windows. And I’m using it with Wampserver...

  • @Wallacemaxters let’s yes, I like the idea.

  • I found a file called "httpd-vhosts.conf" in "C: wamp64 bin apache apache2.4.33 conf extra", whose content is: "<Virtualhost *:80> Servername localhost Serveralias localhost Documentroot "${INSTALL_DIR}/www" <Directory "${INSTALL_DIR}/www/"> Options +Indexes +Includes +Followsymlinks +Multiviews Allowoverride All Require local </Directory> </Virtualhost>" Do I have to delete this and write what you posted? But if I do, my other projects of inaccessible fiction websites!

Show 5 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.