# Making reading files from remote URL's more secure

- Thread: https://externals.io/message/47870
- Original archive: https://news-web.php.net/php.internals/47870
- Started by Keith Roberts on 2010-04-11T16:23:04+00:00
- Messages: 3
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #47870 — Keith Roberts — 2010-04-11T16:23:04+00:00

URL: https://externals.io/message/47870#47870

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:password@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?

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]

---

## #47871 — Ferenc Kovacs — 2010-04-11T16:28:25+00:00

URL: https://externals.io/message/47870#47871 · In reply to: #47870

> 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.
>
> This would be a great step.... backward.

Tyrael

---

## #47872 — Ferenc Kovacs — 2010-04-11T16:40:09+00:00

URL: https://externals.io/message/47870#47872 · In reply to: #47870

> 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:password@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]
