Prevent direct access to a php include file

后端 未结 30 1025
盖世英雄少女心
盖世英雄少女心 2020-11-22 06:32

I have a php file which I will be using as exclusively as an include. Therefore I would like to throw an error instead of executing it when it\'s accessed directly by typing

30条回答
  •  太阳男子
    2020-11-22 06:57

    1: Checking the count of included files

    if( count(get_included_files()) == ((version_compare(PHP_VERSION, '5.0.0', '>='))?1:0) )
    {
        exit('Restricted Access');
    }
    

    Logic: PHP exits if the minimum include count isn't met. Note that prior to PHP5, the base page is not considered an include.


    2: Defining and verifying a global constant

    // In the base page (directly accessed):
    define('_DEFVAR', 1);
    
    // In the include files (where direct access isn't permitted):
    defined('_DEFVAR') or exit('Restricted Access');
    

    Logic: If the constant isn't defined, then the execution didn't start from the base page, and PHP would stop executing.

    Note that for the sake of portability across upgrades and future changes, making this authentication method modular would significantly reduce the coding overhead as the changes won't need to be hard-coded to every single file.

    // Put the code in a separate file instead, say 'checkdefined.php':
    defined('_DEFVAR') or exit('Restricted Access');
    
    // Replace the same code in the include files with:
    require_once('checkdefined.php');
    

    This way additional code can be added to checkdefined.php for logging and analytical purposes, as well as for generating appropriate responses.

    Credit where credit is due: The brilliant idea of portability came from this answer.


    3: Remote address authorisation

    // Call the include from the base page(directly accessed):
    $includeData = file_get_contents("http://127.0.0.1/component.php?auth=token");
    
    // In the include files (where direct access isn't permitted):
    $src = $_SERVER['REMOTE_ADDR']; // Get the source address
    $auth = authoriseIP($src); // Authorisation algorithm
    if( !$auth ) exit('Restricted Access');
    

    The drawback with this method is isolated execution, unless a session-token provided with the internal request. Verify via the loop-back address in case of a single server configuration, or an address white-list for a multi-server or load-balanced server infrastructure.


    4: Token authorisation

    Similar to the previous method, one can use GET or POST to pass an authorization token to the include file:

    if($key!="serv97602"){header("Location: ".$dart);exit();}
    

    A very messy method, but also perhaps the most secure and versatile at the same time, when used in the right way.


    5: Webserver specific configuration

    Most servers allow you to assign permissions for individual files or directories. You could place all your includes in such restricted directories, and have the server configured to deny them.

    For example in APACHE, the configuration is stored in the .htaccess file. Tutorial here.

    Note however that server-specific configurations are not recommended by me because they are bad for portability across different web-servers. In cases like Content Management Systems where the deny-algorithm is complex or the list of denied directories is rather big, it might only make reconfiguration sessions rather gruesome. In the end it's best to handle this in code.


    6: Placing includes in a secure directory OUTSIDE the site root

    Least preferred because of access limitations in server environments, but a rather powerful method if you have access to the file-system.

    //Your secure dir path based on server file-system
    $secure_dir=dirname($_SERVER['DOCUMENT_ROOT']).DIRECTORY_SEPARATOR."secure".DIRECTORY_SEPARATOR;
    include($secure_dir."securepage.php");
    

    Logic:

    • The user cannot request any file outside the htdocs folder as the links would be outside the scope of the website's address system.
    • The php server accesses the file-system natively, and hence can access files on a computer just like how a normal program with required privileges can.
    • By placing the include files in this directory, you can ensure that the php server gets to access them, while hotlinking is denied to the user.
    • Even if the webserver's filesystem access configuration wasn't done properly, this method would prevent those files from becoming public accidentally.

    Please excuse my unorthodox coding conventions. Any feedback is appreciated.

提交回复
热议问题