Folder protection by .htaccess and form by PHP

Question:

I have a security question in the following scenario:

I have a password-protected folder on the server, indicating the following in its .htaccess file:

AuthType Basic
AuthName "restricted area"
AuthUserFile /mihome/miusuario/.htpasswd
require valid-user

When accessing any file in that folder from the browser, a username and password are requested, without which no file can be opened.

Now, in this folder I have a PHP file that sends data to a MySQL DB on the server. From the form you can do CRUD, well … CRUD in Spanish would be ILAB (Insert, Read, Update, Delete) … 🙂 It is therefore something delicate, since the form has the ability to modify the data.

Another piece of information is that updates are done via POST , using Ajax. In other words, there are actually two PHP files involved, the one that presents the form and the one that sends the data to the DB using Ajax.

I thought that having the password protected folder via .htaccess was enough , but now I have a question:

Is it really safe to have that single level of protection or would it be nice to set security at the PHP level as well?

If protection is needed at the PHP level, what files should be protected, only the one that POST through Ajax, or both files?

Wouldn't there be conflicts if protection had to be implemented at both levels?

I imagine a layered protection as follows:

  1. At the .htaccess level, protecting the folder where the files are located, so that no one can enter without the correct password. Of course, said password is encrypted
  2. At the PHP level, validating in some way the POSTS sent to the Database.

Note 1 .:

The question is not about how to protect a folder in .htaccess or in a form in PHP, but about whether the first level of protection would be safe and which files to protect in the case of POST via Ajax.

Note 2 .:

I mean to do it directly in PHP / .htaccess, without having to resort to third-party frameworks. They are PHP files hosted on a shared hosting, which can be accessed through the browser, after authentication.

Note 3 .:

In the situation that I present, the use of https is not possible because the domain does not have that possibility. Although it could be considered if there is no other option left, or if the protection options mentioned above are still excessively vulnerable.

Note 4 .:

Finally I went to https:// , I am on shared hosting and did not know that my hosting offered me a certificate for https for free. I have installed it and it works. The protection is only at the .htaccess level, I have not implemented protection at the PHP level at the moment.

Answer:

The short answer is " DO NOT TRUST HTTP AUTH; IT IS NOT SAFE ".

The long answer is: HTTP AUTH is very easy to break and you shouldn't trust that method. Additionally, HTTP transports the credentials in plain text and anyone could see them with a sniffer on the network. My recommendation is to pass security to PHP and that it determines whether or not it has access to the file.

Consider the following, a script called descarga.php contains among other things the following functions:

<?php
session_start();

function descargar_archivo($archivo) {
   $ruta_completa = "/mis/archivos/varios/" . $archivo;
   header("Content-length:" . filesize($ruta_completa));
   $mimetype = "application/x-zip-compressed";
   header("Content-Type: " . $mimetype);
   header('Content-Type: application/octet-stream');
   header('Content-Disposition: attachment; filename="' . $archivo . '"');
   header('Content-Transfer-Encoding: binary');
   return readfile_chunked($ruta_completa);
}

function readfile_chunked($filename, $retbytes = TRUE) {
    $chunk_size = 1024 * 1024;
    $buffer = "";
    $cnt = 0;
    $handle = fopen($filename, "rb");
    while (!feof($handle)) {
        $buffer = fread($handle, $chunk_size);
        echo $buffer;
        flush();
        if ($retbytes) {
            $cnt += strlen($buffer);
        }
    }
    $status = fclose($handle);
    if ($retbytes && $status) {
        return $cnt;
    }
    return $status;
}

We can then add the following lines:

if (isset($_SESSION['id'])) {
  $archivo = filter_input(INPUT_GET, 'fileid', 513);
  descargar_archivo($archivo);
  exit();
}

The result is a PHP script that downloads a file called descarga.zip when a GET is made to the script http://www.misitio.com/descarga.php?fileid=descarga.zip long as the user has the id variable in your PHP session. This suggests that the user had to login to some page previously to access the file.

With PHP domain security you have options for both the downloadable files and the script that responds to POST, here are a couple of examples that can be implemented:

  • Access control by IP's / geolocation.
  • Session concurrency control.
  • Control of sequence of operations / HTTP requests.
  • Set a specific status (such as HTTP 418) and implement fail2ban to block related IPs directly at the firewall.

You should also consider that the files can be in any directory within your server that is not public, that is, they can live in /home/usuario/archivos in the same way that they can live in /var/archivos/varios . This reduces the attack surface and hides the contents of the folder.

You can use this example to serve JPG's, CSS, JS, etc. there are no limits. In the same way you can use this example to add any number of validations.

Remember that you can always work with self-signed certificates without any problem, it is not necessary to buy a certificate from a provider to encrypt your connections. Once the SSL protocol is implemented, you can require and validate the client certificate at the web server level and / or at the PHP level, which will protect your access credentials and the misuse / unauthorized use of your web server.

Scroll to Top