PHP path protection

I am writing some PHP that takes some paths to different content directories and uses them to include different parts of the pages later. I am trying to ensure that the paths are as they appear, and none of them violates the rules of the application. What is,

  • PRIVATEDIR(defined relatively DOCUMENT_ROOT) should be higher DOCUMENT_ROOT.
  • CONTENTDIR(defined relatively PRIVATEDIR) should lie below PRIVATEDIRand should not return to DOCUMENT_ROOT.
  • The rest *DIRS(relative to CONTENTDIR) should be belowCONTENTDIR

I set some default values ​​in one controller of the singleton class, and then the user passes an array of paths that they want to override to this class constructor. Then I want sanity to test them, to comply with the above rules. This is how I started doing this ...

EDIT: Pay attention to my use error_reportingin the code below, and then don't do it yourself! I misunderstood how this command works. If you're wondering why, see comments by stealthyninja and Col. Shrapnel in the comments (and thank them for pointing this out to me).

private $opts = array( // defaults
   'PRIVATEDIR'   => '..',        // relative to document root
   'CONTENTDIR'   => 'content',   // relative to private dir
   ...
   ...
);

private function __construct($options) { //$options is the user defined options
    error_reporting(0);
    if(is_array($options)) {
        $this->opts = array_merge($this->opts, $options);
    }

    if($this->opts['STATUS']==='debug') {
        error_reporting(E_ALL | E_NOTICE | E_STRICT);
    }

    $this->opts['PUBLICDIR']  = realpath($_SERVER['DOCUMENT_ROOT'])
                                        .DIRECTORY_SEPARATOR;
    $this->opts['PRIVATEDIR'] = realpath($this->opts['PUBLICDIR']
                                        .$this->opts['PRIVATEDIR'])
                                        .DIRECTORY_SEPARATOR;
    $this->opts['CONTENTDIR'] = realpath($this->opts['PRIVATEDIR']
                                        .$this->opts['CONTENTDIR'])
                                        .DIRECTORY_SEPARATOR;
    $this->opts['CACHEDIR']   = realpath($this->opts['CONTENTDIR']
                                        .$this->opts['CACHEDIR'])
                                        .DIRECTORY_SEPARATOR;
    $this->opts['ERRORDIR']   = realpath($this->opts['CONTENTDIR']
                                        .$this->opts['ERRORDIR'])
                                        .DIRECTORY_SEPARATOR;
    $this->opts['TEMPLATEDIR' = realpath($this->opts['CONTENTDIR']
                                        .$this->opts['TEMPLATEDIR'])
                                        .DIRECTORY_SEPARATOR;

   ...
   ...
   ...


    // then here I have to check that PRIVATEDIR is above PUBLICDIR
    // and that all the rest remain within private dir and don't drop 
    // down into (or below) PUBLICDIR again. And die with an error if
    // they don't conform.
}

, , , , - (, , ), .

, ( ) , , , . ( ) , , , , (, // ...) , , .

, , , , ? . ? , , - ? ( , ).

.

+5
3

strpos ? , - , . :

// PRIVATEDIR already includes PUBLICDIR at this point
if(strpos($this->opts['PRIVATEDIR'],$this->opts['PUBLICDIR']) !== 0) {
die('ERROR: '.$this->opts['PRIVATEDIR'].' must be located in .'$this->opts['PUBLICDIR']);
}

, , , PUBLICDIR 0 PRIVATEDIR, - . , (PUBLICDIR!= PRIVATEDIR), "./test/../", ".".

+1

, , , . , .htaccess( , -).

, array_merging ? $opts , E_STRICT; - , , , ( - $opts = array('TEMPLATEDIR'=>'/templates') , $config->$opts['TEMPLATEDIR'] - , , /templates); , .

+1

, , , realpath(), , ? , "../'?

, , , CACHEDIR , - .

In addition, you are rewriting existing variables instead of creating new variables from the template values ​​- even if you do this in the constructor, this is a rather dirty approach to values ​​that really need to be final as soon as they are declared.

0
source

All Articles