Prevent a PHP file from being called directly from the browser

4

I have tried many methods, but in the end they always fail. The only one that did not give me problems was to do a validation with GET getting the id ,

if(!isset($_GET[id])){
{ 
 header('Location: /App'); }
}

but it does not matter because anyone can access it just by putting link.com/ruta/?id=cualquiercosa

    
asked by I love Photography 17.08.2017 в 07:07
source

3 answers

4

The safest ways to avoid running your PHP scripts directly are:

Hosting them outside the root of the website ( document root )

Your website should have a structure similar to this one:

/var/html/
├── html_publico/
│   ├── imagenes/
│   ├── css/
│   └── index.php
└── aplicacion/
    ├── script_php1.php
    └── script_php2.php

It is the most recommended practice and is the one used by most frameworks (Slim, Symfony, etc.).

You can see an example on the documentation of Slim and another one on the Symfony documentation .

Using variable definition

When the previous solution can not be used (our accommodation does not allow us to access a higher level of our website) we can adopt this alternative solution, although it is less advisable and can lead to error by forgetting the check in a file.

If a PHP script can be accessed directly on its first line, a constant is defined using define() :

define('ACCESO_PERMITIDO', true);

If you do not allow direct access to it, what you do is check that the constant has been defined through a permitted script using defined() :

if (defined('ACCESO_PERMITIDO') === false) {
  header('HTTP/1.0 403 Forbidden');
  exit();
}

Denying access to the HTTP server

Another alternative that we could use is to configure the web server to refuse access to a directory where we store the protected PHP scripts.

It is a practice discouraged because when migrating from one server to another could change some parameter (such as Apache's AllowOverride ) that would allow access to the files that we thought were protected.

Apache makes use of access controls in a block <Directory> or a file .htaccess .

If we use the solution of the file .htaccess our directory structure could be the following:

/var/html/
├── scripts/
│   ├── .htaccess
│   ├── script_php1.php
│   └── script_php2.php
├── imagenes/
├── css/
└── index.php

A content of .htaccess that would prevent direct access to any file inside it would be:

Order Deny,Allow
Deny from All

We must remember that to use a file .htaccess the directive AllowOverride should allow the use of its content through the Limit directive in the site settings web:

<Directory /var/html/scripts>
  AllowOverride Limit
</Directory>

Since we are using the block <Directory> in the configuration of the website this could be, without needing .htaccess or allow Limit with AllowOverride :

<Directory /var/html/scripts>
  Order Deny,Allow
  Deny from All
</Directory>

And on an NGINX server, the website would be configured in the following way (using relative routes of the URL, not local directory routes):

location /scripts {
  deny all;
  return 403;
}
    
answered by 17.08.2017 в 08:41
0

If what you want is that nobody can enter the file, do not leave it public. If your site lives in /var/www/html then you can put the files in /var/archivos .

Now, you can not stop people from making their own requests, saying that your best option for securing your files is obscuring them.

Here I have given an answer on how to serve protected files.

Here is the original answer that contains the mechanism that you can use to serve any type of files.

    
answered by 17.08.2017 в 08:07
0
if (!defined('BASEPATH'))
    exit('No direct script access allowed');

Taken as a codeigniter. You can use this function to validate it, place it right on top of your php file and check if it works for you.

In my case, I use it for each controller in case they want to access it by placing the name of the file directly.

    
answered by 05.04.2018 в 22:39