Prevent direct access to php files

scripts
#1

I have a webpage (e.g. project3) on my localhost (will be uploaded to server either on its own domain or in a subdomain/subfolder) with the structure:
localhost
   [project1]
   [project2]
   …
   [project3]
      [data] (containing only html&xml files and the users.txt / storing users data submitted from register.php)
      [editor] (containing simple textarea editor used in other PHP files
      [images] (icons, logo only)
      [system] (PHP files only)
         .htaccess
         data.php (generates the files stored in [data] filling submitted data from input.php)
         input.php (form for submitting data to [data]-files
         login-register.php (form with only two submit inputs / LOGIN or REGISTER)
         login.php (login form)
         logout.php (logout script)
         r_egister.php_ (register form)
         thanks.php (page after logout)
   index.php (contains list of links to all [data]-html files) and a button [SUBMIT YOUR DATA] leading to start.php
The operation is:

  1. index page is the only public accessible by URL - only registered users may submit their data -> login-register.php
  2. login compares login data with users.txt -> input or register -> login ->input
  3. data - generates [data]-files
    I have not find a way how to pretend direct access to all files except of index.php by adding their URLs in browser.
#2

Hi @info2499 and a warm welcome to the forum.

To prevent all PHP files being read except index.php I would try placing the project3 folder above the root.

index.php remains in the root path, is visible in browsers and calls index.php/login to include '…/project3/system/login.php

This is the recommended setup for most PHP Frameworks including WordPress.

#3

On host servers the entire domain incl. _sub folder (my subdomains) id placed in /public_html fodler. If I understand you, the project3 shall be moved out of public_html? May it be then renamed to any other, e.g. project3_secure and the index may go in public_html?
I am not sure if I can create any directory out of public_html. I’ll ask my ISP.

#4

If your files are not outside root this is very easy. Basic example:

index.php

<?php
define('SECURE_PAGE', true);
include 'includes/page.php';

includes/page.php

<?php
if (!defined('SECURE_PAGE'))
{
    die('<h1>Direct File Access Prohibited</h1>');
}
?>
Included Page
#5

Hallo,
Brilliant explanation! Anyway, I do something wrong.
I have made a demo system to see, how it works. But:
Inserting and adjusting (that may be the problem) your codes results in “Direct File Access Prohibited” (regardless wether calling the subpages by submit buttons or inserting their URLs).DEMO ARCHIVE
To make it simpler, I maded a demo with all necessary files (some remain not used, but still there). Anyting with “_” in name must not be accessible via direct URL inserting, only by internal PHP calls (internal links, submits).

#6

I downloaded and tried your files and was amazed there was not a single doctype used?

Try validating your files using the following:

https://validator.w3.org/

#7

Oops, I haven’t think about this in this pure testing environment. Hepofully, everything is OK now. Revised >>

#8

What is with all the leading underscores on the directories and file names?

Your approach to whatever problem you are trying to solve appears to be incorrect. How about telling us about what you are actually trying to do, the overall big picture.

1 Like
#9

The only I want to achieve is prevent all files (now named with undescore) from being accessible by their URLs directly. IOW, they shall only be accessible by internal functions. The only accepted URL from visitors shall be the index.php. All other files shall remein externally inaccesible. Any try for using an URL e.g. https://mydomain.tld/test/_<anyfolder>/_<anyfile> shall either return “404” or redirect to the beginning of the page (index.php). I have tried sessions, htaccsess, some php tricks found in forums and tutorials, but none of them worked expected way.
The leading underscores are not necessaty. I used them only to make clear, whoch files shall be externally inaccessible.
The operation is actually described in headers of the pages and in my first post.

#10

I take you’re using Apache? With Nginx this would be trivial.

Anyway, assuming Apache the best option would indeed be as @benanamen already suggested to put the other PHP files outside of the document root, so they are not publicly accessible at all. That is the most secure way and also the most common way.

/home
  /website
     /includes
         /foo.php
     /public
         /index.php 

Then from index.php you can include __DIR__.'/../includes/foo.php; since PHP is allowed to access these files even though Apache is not.

If for some reason you insist to keep all the PHP files inside the document root, you can prevent any access to them with an .htaccess file in the directory/directories you want to keep hidden with the contents deny from all. That will result in an HTTP 403 for any request to those directories or any of their subdirectories.

2 Likes
closed #11

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.