Securing paths in PHP

Posted by tjm on Stack Overflow See other posts from Stack Overflow or by tjm
Published on 2010-12-23T21:49:53Z Indexed on 2010/12/23 21:54 UTC
Read the original article Hit count: 175

Filed under:
|
|

I'm writing some PHP which takes some paths to different content directories, and uses these to include various parts of pages later. I'm trying to ensure that the paths are as they seem, and none of them break the rules of the application. I have PRIVATEDIR which must lie above DOCUMENT_ROOT (aka) PUBLICDIR. CONTENTDIR which must lie within PRIVATEDIR and not go back below PUBLICDIR and some other *DIR's which must remain within CONTENTDIR. Currently I set up some defaults, and then override the ones the user specifies and then sanity check them with the following.

private function __construct($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['PRIVATEDIR']
                                        .$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.
}

The thing is this seems like a lot of work to do, especially as it must be run, every time a page is accessed, before I can do anything else, e.g check for a cached version of the page I'm serving. Part of me is thinking, since all of these paths are predefined by the maintainer of the site, they SHOULD be aware of what paths they are allowing access to and ensuring they are secure. But, I think I'm thinking that because currently I am said maintainer, and I KNOW my paths conform to the rules. That said, I do want to secure this thing from any accidental errors by future maintainers (and I bet, now I've said above "I KNOW...", probably from myself somewhere down the line). This just feels like a suboptimal solution. I wonder how fast this would really be and what you would suggest to improve it or as an alternative?

Thanks.

© Stack Overflow or respective owner

Related posts about php

Related posts about web-development