Hi,

==
Short version:
I have concerns about the disclosure of error messages using glob() as
it reveals file names that a user should not have access to. I have
written to security@ but got no answer and the related glob()-bug
(#28932) has been marked bogus even though I pointed out that the
error was still present after following the open_basedir-advice. As of
such, I don't think it's any harm to show some (pretty ugly) code to
utilize the error:

http://basedir.ter.dk/globeater.php
http://basedir.ter.dk/globeater.php?debug=1
http://basedir.ter.dk/globeater.phps

PHP is running as an Apache module, restricted by safe_mode,
restricted by open_basedir, sessions placed in a non-default folder.
The script is owned by an ordinary user. session.save_path can be
disclosed by adding ?PHPSESSID=_ to URI using sessions and looking at
error messages.

Sessions in files is the native way of storing sessions.
session_set_save_handler() could be used but is cumbersome on a large
scale.

I am worried that there is no mechanism to prevent this kind of
filelist harvesting.

===
Long version:
I have earlier made some noise regarding bug #28242 (sessions shared
across virtual hosts) and bug #28932 (glob() performs a weird
safe_mode-check, and discloses file names).

I have tried to follow instructions by the bug reporters, but still
seem dismissed. I can understand part of the arguments, but I think
it's sad to ignore the issue as a whole.

Basically I find it hard to help and point out issues. The story goes
something like:

Me: Bug #28242, sessions are shared across virtual hosts
Bugfixer: Well, then, use different session.save_path for each and
every single virtual host out there.
Me: But bug #28932 shows that one can easily retrieve every file name
available to Apache, thus retrieving the session file names - and as
the session file names equals the cookie value, hijacking is extremely
easy.
Bugfixer: Well, we can't check the UID for each file. Besides,
safe_mode is not entirely safe and has many drawbacks. It 
is much better to use open_basedir to restrict the user to 
their home directory or any other set of directories.
Me: Okay, but even when I follow your advice and use open_basedir, the
issue is present?
Bugfixer: Then this is not a bug.

(my interpretation :)

It seems like every time these issues are brought up, people tend to
focus on the exceptions to claim that there are other ways to disclose
information. But users don't necessary have access to other language,
shell-accounts or FTP-access out of their own home directories. We
can't help where users do have other access to the file structure, but
just because these setups exist out there it doesn't mean that pure
PHP-based access shouldn't be more secure. Furthermore, I don't think
the solution for ISPs to run a jailed Apache for each and every of
their thousand customers out there is that realistic.


So, my question is just:

Is it really a-okay that a script in pure PHP under
safe_mode-restriction, under open_basedir-restriction, using any
native php configuration methods to prevent accessing directory
information, with no access to shells, other languages or other means
of retrieving information from the system still is able to retrieve
file lists, that might contain session files, opening the possibility
of session hijacking?

I find it confusing that the solution basically requires that "files
aren't secret" and sessions instead is saved in a database using
session_set_save_handler() - and every user has to invent their own
session mechanism.


Once again, I know that safe_mode isn't per se safe. That is not my
claim and not a relevant argument. But when bugfixers suggest
workarounds to bugs and these workarounds just isn't enough, I find it
a pity that the conclusion just is "Well then, I suppose that's the
way it should work". I fully agree to the documentation: "It is
architecturally incorrect to try to solve this problem at the PHP
level, but since the alternatives at the web server and OS levels
aren't very realistic, many people, especially ISP's, use safe mode
for now." - this case even concerns the case where only pure PHP is
used. Currently it seems that glob() makes the
open_basedir/safe_mode-check of opendir() pretty useless (as a user
could just use glob() instead).

Besides, what is actually the total performance loss in relation to
the total amount of work by parsing a php page?
find largedir -printf "%U" seem pretty fast here on an old server (a
couple of thousand file UIDs outputted in about one second)


.. and as usual, just to clarify: I'm not against any of the
bugfixers. They really are doing a magnificent job. My only concern is
PHP.

Some workarounds/solutions (based on general php behaviour and not at
php-code-level) to solve different issues might be:
* Most important: No disclosure of file name on
safe_mode/open_basedir-error when using glob(). This could prevent
file structure havesting.
* UID check for each glob()-entry, not just the first one. It requires
more effort but it might be a small price to pay.
* glob() of non-existent folders should be restricted as well -
glob("/home/nonexistent/") provides no error, but
glob("/home/existent/") does.
* Session file names could be hashed values. In that case the filename
itself can't be used for session hijacking.
* Append the UID to the session file in safe_mode (just as the UID is
appended to the realm in HTTP authentication) - or maybe (hash of)
SERVER_NAME where available.
* An option to prevent running of PHP scripts with the same UID as the
Apache user (as it is easy to create a script with the UID of the
Apache user, bypassing some safe_mode-limitations).

I can't see why setups only using PHP (and e.g. FTP restricted to
homedir as ftp-root) absolutely have to be insecure based on arguments
that has nothing to do with PHP-only-access. I don't believe that
security comes in a box, but any issue to be solved on a
global/centralized level is better than asking sysadms and developers
of performing custom, individual workarounds.

Just my 0.02dkk - thanks for listening!

-- 
- Peter Brodersen

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to