Forget Forget - 3 months ago 7
PHP Question

How to deny acess to folder with php files with sensitive information?

I'm really new to PHP, but I had to rush a job in PHP recently and I did something which has the following structure:

|- html
|- css
|- js
|- root

Root is folder which contains all the PHP handling. In the JS files I post data to a PHP page which then does its stuff. It all works fine but I don't know how to restrict the user from accessing that "root" folder and the PHP files since it contains information that I don't want disclosed.

I also tried
but it gives 500 internal server error.


This is what I did.

Move the PHP files out of the public folder except for one gateway file

   html files
   css files
   js files

I use .htaccess to redirect all requests for my PHP scripts to gateway.php. This file does the rest: to get a.php, the browser needs to request url /php/a. /php/b will be forwarded to b.php...

RewriteEngine On
RewriteBase /    
RewriteRule ^php/(.*)   gateway.php?file=$1.php   [END,QSA,NC]

END means to stop looking for more redirect rules. NC means case-insensitive match. QSA means to attach query parameters if any to the redirect destination.

In php.ini, I set auto_prepend_file to point to a file in the scripts folder. This file is run before all PHP scripts, so I can use it to do some configuration. In part, it has a list of allowed PHP scripts.


//the only scripts that will be allowed to run (besides gateway.php)
Const SAFE_SCRIPTS = '"/path/to/gateway.php","/path/to/a.php" ...';
Const SCRIPTS_PATH = __DIR__; //this file should be in the scripts directory

//block unnknown files. This will prevent a malicious file from running
$file = $_SERVER['SCRIPT_FILENAME'];//should be /path/to/gateway.php
if(strpos(SAFE_SCRIPTS,"\"$file\"")===false) {http_response_code(404);exit;}

gateway.php is in charge of making sure the requested PHP file is on the allowed list and of forwarding the request to the right file

//get the file requested. Comes from the htaccess rule
$file = SCRIPTS_PATH.'/'.$_GET['file'];

//if file is not in the allowed list, abort
if(strpos(SAFE_SCRIPTS,"\"$file\"")===false) {http_response_code(404);exit;}

//load the file that will handle the request
require SCRIPTS_PATH.'/'.$file;

My setup is slightly more complicated but you get the idea. Keeps my scripts outside of the public web folder.