The attached patch changes open_basedir from PHP_INI_SYSTEM to PHP_INI_ALL.
Wait now... let me finish.
It introduces a custom INI modification handler for open_basedir which
allows the option to be set during Startup and Shutdown (PHP_INI_SYSTEM
contexts) normally, then for other contexts (Activate/Deactivate {PERDIR}
and Runtime) it checks the inbound settings against the current value and
applies some logic:
If open_basedir hasn't been set yet: It allows any new setting to be
applied (unrestrictive to restrictive)
If open_basedir is set, then it checks to see if each component of the new
setting would be allowable under the rules of the old setting, if they're
all good, it allows it. If any component makes the basedir check less
restrictive, it fails (diallows) the change. (less-restrictive to
more-restrictive).
The advantage of doing this is that package authors and/or users of shared
hosting who may not have access to making their settings more restrictive
can avoid most simple FS inspection attacks caused by buggy script code by
adding a single ini_set(basedir(FILE)); to the top of their script or
setting it with an .htaccess directive.
Note that it doesn't do a thing to avoid code inejction attacks as such an
attacker could issue ini_restore("open_basedir"); and have the same access
to the FS as they would without this patch. I'll grant you it's not a
panacea, and it may be more harmful than good by making people think that
tightening up open_basedir is enough, but it's something.
Talk amongst y'selves....
-Sara
I don't have a problem with this.
-Andrei
The attached patch changes open_basedir from PHP_INI_SYSTEM to
PHP_INI_ALL.Wait now... let me finish.
It introduces a custom INI modification handler for open_basedir which
allows the option to be set during Startup and Shutdown
(PHP_INI_SYSTEM
contexts) normally, then for other contexts (Activate/Deactivate
{PERDIR}
and Runtime) it checks the inbound settings against the current
value and
applies some logic:If open_basedir hasn't been set yet: It allows any new setting to be
applied (unrestrictive to restrictive)If open_basedir is set, then it checks to see if each component of
the new
setting would be allowable under the rules of the old setting, if
they're
all good, it allows it. If any component makes the basedir check less
restrictive, it fails (diallows) the change. (less-restrictive to
more-restrictive).The advantage of doing this is that package authors and/or users of
shared
hosting who may not have access to making their settings more
restrictive
can avoid most simple FS inspection attacks caused by buggy script
code by
adding a single ini_set(basedir(FILE)); to the top of their
script or
setting it with an .htaccess directive.Note that it doesn't do a thing to avoid code inejction attacks as
such an
attacker could issue ini_restore("open_basedir"); and have the same
access
to the FS as they would without this patch. I'll grant you it's not a
panacea, and it may be more harmful than good by making people
think that
tightening up open_basedir is enough, but it's something.Talk amongst y'selves....
-Sara
<open_basedir.txt
The attached patch changes open_basedir from PHP_INI_SYSTEM to
PHP_INI_ALL.
My only "beef" would be if the docs claimed it was just plain old
PHP_INI_ALL without explaining the custom restrictions...
It will cause all manner of confusion that it behaves uniquely unless
it's documented.
+1 with documentation
-1 without documentation
--
Some people have a "gift" link here.
Know what I want?
I want you to buy a CD from some starving artist.
http://cdbaby.com/browse/from/lynch
Yeah, I get a buck. So?
Sara Golemon wrote:
The attached patch changes open_basedir from PHP_INI_SYSTEM to PHP_INI_ALL.
[...]
The advantage of doing this is that package authors and/or users of shared
hosting who may not have access to making their settings more restrictive
can avoid most simple FS inspection attacks caused by buggy script code by
adding a single ini_set(basedir(FILE)); to the top of their script or
setting it with an .htaccess directive.
Great feature. I can see this being very useful to packaged PHP applications
like ours (MediaWiki). The only complication in implementation I can think
of is trying to work out the location of PEAR, for those modules that use
it. I suppose we would have to append the default include_path to the
runtime open_basedir, to make sure that PEAR is accessible.
-- Tim Starling
Hello,
Sara Golemon wrote:
The attached patch changes open_basedir from PHP_INI_SYSTEM to PHP_INI_ALL.
[...]The advantage of doing this is that package authors and/or users of shared
hosting who may not have access to making their settings more restrictive
can avoid most simple FS inspection attacks caused by buggy script code by
adding a single ini_set(basedir(FILE)); to the top of their script or
setting it with an .htaccess directive.Great feature. I can see this being very useful to packaged PHP applications
like ours (MediaWiki). The only complication in implementation I can think
of is trying to work out the location of PEAR, for those modules that use
it. I suppose we would have to append the default include_path to the
runtime open_basedir, to make sure that PEAR is accessible.
There is no issue with PEAR or any applications using include_path and
relative paths in include/require. The system include_path, if any,
paths should already be in the open_basedir. If they are not, you
have to install the desired modules within your open_basedir, just
like now.
Sara, I did not check the patch (not readable here :P), but I like the idea.
--Pierre
Pierre wrote:
There is no issue with PEAR or any applications using include_path and
relative paths in include/require. The system include_path, if any,
paths should already be in the open_basedir. If they are not, you
have to install the desired modules within your open_basedir, just
like now.
The application I'm interested in is where there is no system open_basedir,
and the application wishes to lock down the environment. So we could do:
ini_set('open_basedir', ini_get('include_path') . PATH_SEPARATOR
.
dirname(FILE));
But that still allows the application to access every path that the system
administrator has, at a whim, included in include_path. It's not maximally
restrictive, really we only need dirname(FILE) and wherever PEAR is.
We could do:
$pear = trim(pear config-get php_dir
);
ini_set('open_basedir', $pear . PATH_SEPARATOR
. dirname(FILE);
But of course, that's not very portable. What I'm hinting at is that it
might be kind of nice if PHP knew where PEAR was, and provided it say via
$_SERVER. It might save a bit of mucking around.
System administrators are usually pretty clueless about PHP compared to
application developers. It's up to the application to make sense of whatever
insecure, inconsistent mess the sysadmin has left the system in, and to run
in that environment as securely as possible. That's why I welcome a feature
such as this.
Now if there was just some way for the application to control
magic_quotes_gpc and register_globals, I'd be a happy man.
-- Tim Starling
Tim Starling wrote:
Pierre wrote:
There is no issue with PEAR or any applications using include_path and
relative paths in include/require. The system include_path, if any,
paths should already be in the open_basedir. If they are not, you
have to install the desired modules within your open_basedir, just
like now.The application I'm interested in is where there is no system
open_basedir, and the application wishes to lock down the environment.
So we could do:ini_set('open_basedir', ini_get('include_path') .
PATH_SEPARATOR
.
dirname(FILE));But that still allows the application to access every path that the
system administrator has, at a whim, included in include_path. It's not
maximally restrictive, really we only need dirname(FILE) and
wherever PEAR is.We could do:
$pear = trim(pear config-get php_dir
);
ini_set('open_basedir', $pear .PATH_SEPARATOR
. dirname(FILE);But of course, that's not very portable. What I'm hinting at is that it
might be kind of nice if PHP knew where PEAR was, and provided it say
via $_SERVER. It might save a bit of mucking around.
Hi Tim,
This is a bit more PEAR-related, please follow up to pear-dev with any
further questions. The code you're looking for is:
require_once 'PEAR/Config.php';
$c = PEAR_Config::singleton(); // assuming PHP 5, add & if PHP 4
ini_set('open_basedir', $c->get('php_dir') . PATH_SEPARATOR
.
dirname(FILE));
Greg
Hello,
Tim Starling wrote:
Pierre wrote:
There is no issue with PEAR or any applications using include_path and
relative paths in include/require. The system include_path, if any,
paths should already be in the open_basedir. If they are not, you
have to install the desired modules within your open_basedir, just
like now.The application I'm interested in is where there is no system
open_basedir, and the application wishes to lock down the environment.
So we could do:ini_set('open_basedir', ini_get('include_path') .
PATH_SEPARATOR
.
dirname(FILE));But that still allows the application to access every path that the
system administrator has, at a whim, included in include_path. It's not
maximally restrictive, really we only need dirname(FILE) and
wherever PEAR is.We could do:
$pear = trim(pear config-get php_dir
);
ini_set('open_basedir', $pear .PATH_SEPARATOR
. dirname(FILE);But of course, that's not very portable. What I'm hinting at is that it
might be kind of nice if PHP knew where PEAR was, and provided it say
via $_SERVER. It might save a bit of mucking around.Hi Tim,
This is a bit more PEAR-related, please follow up to pear-dev with any
further questions. The code you're looking for is:require_once 'PEAR/Config.php';
$c = PEAR_Config::singleton(); // assuming PHP 5, add & if PHP 4
ini_set('open_basedir', $c->get('php_dir') .PATH_SEPARATOR
.
dirname(FILE));
These values do not change during the application lifetime. Dynamic
tests and decisions are ugly when what you test never change. I would
suggest to do it only during the installation stage.
--Pierre