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