On Sun, Apr 11, 2010 at 6:23 PM, Keith Roberts <ke...@karsites.net> wrote:
> Hi all. > > I've been reading about the security implications of turning > allow_url_fopen 'on' for certain PHP applications that need to read files > from a remote URL. > > To recap, please read this old article about Remote file inclusion > vulnerabilities: http://lwn.net/Articles/203904/ > > I'm just wondering if the ability to read files from a remote URL could be > moved into a set of functions dedicated to that purpose alone? Then remove > the URL reading ability from the standard file reading functions, to make > those more secure? > > The new set of remote file reading functions could be prefixed with 'url_'. > > This would make it easier to distinguish between the local file reading > functions, and those that read from remote URL's. > > So the normal fopen() function would only work on files locally, regardless > of whether allow_url_open was turned on. > > allow_url_open would only enable the file functions with the 'url_' prefix. > > setting allow_url_open to 'OFF' would disable those remote file reading > functions, prefixed with 'url_'. > > To read a file from localhost just use the normal syntax: > > <?php > $handle = fopen("/home/rasmus/file.txt", "r"); > $handle = fopen("/home/rasmus/file.gif", "wb"); > ?> > > To read a file from a remote URL use: > > <?php > $handle = url_fopen("http://www.example.com/", "r", $md5hash); > ?> > > To write a file to a remote URL use: > > <?php > $handle = url_fopen("ftp://user:passw...@example.com/somefile.txt", "w", > $md5hash); ?> > > To make sure that an attacker cannot use url_fopen() in an attack script, > these url_ prefixed remote file read/write functions could also take another > required parameter, $md5hash. > > fopen > (PHP 4, PHP 5) > > fopen — Opens file or URL > > Description > > fopen ( string $filename, string $mode, $md5hash > [, bool $use_include_path = false [, resource $context ]] ) > > As in: > > <?php > $handle = url_fopen("http://www.example.com/", "r", $md5hash); > ?> > > $md5hash is a value that the 'url_' prefixed remote file reading/writing > functions checks before opening the remote URL. > > If the $md5hash parmeter does not match what the function expects, then the > function fails with an error message, and refuses to open the remote file. > > If the $md5hash was stored on the localhost, then the attacker would not > have access to it, and the url_ prefixed remote file functions would fail > with the error message, "Cannot open remote URL - invalid hash key". > > These remote file opening attempts would also appear in the PHP error log, > making it easier to spot such security attacks. > > Any ideas how the $md5hash KEY could be stored on localhost, so PHP can > read it, and then compare that KEY with the value the programmer passes into > the url_fopen($file, $mode, $md5hash) function? > > First of all, I agree that it would be easier for check your codebase against remote file inclusion possibilities, if the normal file/stream handling functions wouldn't be allowed to open remote resources, but this would be a big loss of functionality, at now, almost every file/stream handler function is capable of handling remote locale and remote resourse, so we would need to duplicate all of them, with prefixing url_. This would be a big BC too. The md5hash thing is silly, you cannot defend (and obviously too late) the remote inclusion, if the attacker is capable of executing custom php code on the server. so this would require a lot of work in the engine, could cause a lot of bug(function missed to re-write/duplicate), would cause a big BC, and I see no real benefit to implement. Tyrael Kind Regards, > > Keith Roberts > > ----------------------------------------------------------------- > Websites: > http://www.karsites.net > http://www.php-debuggers.net > > All email addresses are challenge-response protected with > TMDA [http://tmda.net] > ----------------------------------------------------------------- > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php >