Bugzilla – Bug 129682
php.ini contains broken include_path ("." missing)
Last modified: 2007-06-11 21:46:36 UTC
I just wondered why my (local) PHP-based websites didn't run and showed the following messages instead: PHP Warning: main(admin/_mysql_connect.php): failed to open stream: No such file or directory in [...] PHP Fatal error: main(): Failed opening required 'admin/_mysql_connect.php' (include_path='/usr/share/php') in [...] The reason for this is very simple - the default php.ini from php4-4.4.0-6.i586.rpm contains include_path = "/usr/share/php" This means the script's directory (".") is _not in the default include_path. I'm afraid this will break lots of scripts that include() or require() files. The solution is quite simple - change the php.ini entry to: include_path = ".:/usr/share/php" Just add this ------^^ Maybe this is worth a YOU update ;-)
The `.' in path is a SECURITY risk. Please fix your scripts.
Due security the risk the request is INVALID
> The `.' in path is a SECURITY risk. Please fix your scripts. You must be joking. No, wait - disabled PHP scripts can't have security issues :-/ To be serious: Nearly every "larger" PHP script is split up into several files that are put together using include() or require(). Without "." in include_path, I would have to put my whole website (except index.php and the images) to /usr/share/php. The same is true for Typo3 (and much more scripts) - it would also mostly reside in /usr/share/php. This is unreasonable on a host with only one site and *impossible* on a server that hosts lots of vHosts. And it will _not_ increase security. On the other hand, I can't see the possible security problems. PHP scripts are called via Apache, and "." always means dirname($script). Usually the only user who has write access to the main script also is the only one with write access to include()d scripts in the same directory. If you don't trust scripts that are include()d inside this directory, you should be rigorous - then you must not trust the main script itsself (as $user can replace include() with the content of the included script) and disable PHP. Very secure, but too rigorous, I think ;-) Maybe I've overlooked something - if so, please tell me where you see the security risk.
Christian Boltz seems to be right guys. the default value of include_path on SUSE 9.2 x86_64: include_path = ".:/usr/share/php" (it includes . ) the value of include_path on Fedora Core 4: include_path =".:/usr/share/pear" (again it includes ".") My 9.3 box amd64 says. include_path = ".:/usr/share/php5/PEAR" (dot included..) default value on slackware Linux 10.2 include_path = ".:/usr/lib/php" default value on Redhat Enterprise Linux 3 include_path ".:/usr/share/pear" PHP.net own recommeded php.ini features a "dot" as the first include_path http://cvs.php.net/co.php/php-src/php.ini-recommended?r=1.183 I actually don't have access to other distributions to prove Werner is wrong. and this is not a security hole.
this problem also broke the auto_prepend_file, auto_append_file features using htaccess files. also http://cl2.php.net/manual/en/ini.core.php#ini.include-path features an example with .dot included, and tells you " Using a . in the include path allows for relative includes as it means the current directory."
I also had problems with a PHP-based web Content Management System that I traced to the include_path entries in SuSE's php4 (/etc/php.ini) and php5 (/etc/php5/apache2/php.ini) packages. I am not a php programmer and cannot comment on any security implications nor on whether this is a bug, feature, or otherwise. But, in both PHP versions, adding ".:" to the include_path directive did get Drupal to work. If it helps, the /etc/php.ini file for Fedora Core 3's php4 package has no uncommented include_path entry at all, and Drupal worked on it out of the box using Drupal's installation instructions. Some discussion on the Drupal site also shows a fix for just Drupal (I don't think it would fix other PHP applications). And the SuSE 10.0 phpMyAdmin rpms did work out of the box with unmodified php.ini files. One observation: in both the 4 and 5 SuSE 10.0 php packages, the default include_path is something like "/usr/share/php5", but (at least in /usr/share/php5) the directory is empty. Thanks for your time on this.
I check phpMyAdmin on SL10 with php4 and php5 and it works fine with include_path = "/usr/share/php" (include_path = "/usr/share/php5"), Bill how do you test it please? Another comment to empty /usr/share/php (or /usr/share/php5) directory. Try install php4-pear, php4-swf, php4-pear-log, php5-pear. Werner, could you comment please the last comments of this issue?
Just to clarify some things, I did some tests: Without . in include_path, - include('file.php') works (huh? Without being in include_path?) - include('subdir/file.php') works if the script with the include command is in "." (huh? again...) - include called from a subdirectory does *not* work. Example: index.php: <?php include ('subdir/file.php') ?> subdir/file.php: <?php include ('subdir/foo.php') ?> <-- will fail Before you ask: include ('foo.php') also doesn't work and is the wrong way according to the PHP documentation. - include('./subdir/file.php') works, even in the scenario described above (BTW, phpMyAdmin uses this syntax) The problems with this: - I guess there are several scripts out there that do not use ./subdir/file.php, but just subdir/file.php. They will break if the include command is contained in a script in a subdirectory. - It even seems to be buggy - if include_path does not contain ".", include('file.php') also should NOT work. Or am I wrong with that? - the current bahaviour will worry people because it works in some (most?) cases With "." in include_path, all described testcases work.
Every author of scripts accessible to the public should be aware the problems with the `.' in exec/include paths and also the risks of temporary files without using mktemp(3). What is wrong with the extension of such paths with the real used parts needed for a specific script instead of loading all in the current working directory and catching a scriplet not designed for the main script? IMHO this increase the risk to be attacked. But Petr is the maintainer of php. Petr?
werner: It increase the possiblity of "nothing works" and _does_not_ improve the security -- please install in your computer the most common PHP apps, and look them crash ..(even if not included in SUSE) .. also, read the PHP docs, even the original php.ini-recommend. "What is wrong with the extension of such paths with the real used parts needed for a specific script instead of loading all in the current working directory and catching a scriplet not designed for the main script??" makes sense, however , I had to say the way without "." in the include path IS NOT the expected behaviuor , nor the Upstream Vendor recommended setting. ps: in PHP, apps should create temporary files using the tempfile() function, or better, you can use de OOP way using the PEAR System.php Class, it provides a function to emulate mktemp(3) (without system() or exec() calls of course )
OK, then it is Petr's decision. For the php4 vesus php4 switch a version check whould be perfect. However I don't know how this could be done in php.
"For the php4 vesus php4 switch a version check whould be perfect. However I don't know how this could be done in php." werner: can you explain us the last comment.. maybe I can help, but I don't understand your comment.. did you mean "php4 versus php5 switch" ?
something like (in C like syntax) if (php_version == 4) include_path = ".:/usr/lib/php" else include_path = ".:/usr/lib/php5" or something like that.
<?php if (version_compare(phpversion(), "5.0.0", ">=")) { $include_path = ".:/usr/lib/php5"; // we are on php >= 5..do something.. } else { $include_path = ".:/usr/lib/php"; // we are on older versions..do something ... } ?>
of course you need to use the $include_path variable to set the include path for the actual script, using ini_set() function ;-) ps: include_path can be changed _everywhere_ ...
Still waiting for an anwser. Petr?
to comment #4: Christian B., where did you find, that Red Hat Enterprise Linux used default value include_path ".:/usr/share/pear" ? I looked at Red Hat Enterprise Linux AS release 4 and FC4-x86_64 and both has default php.ini with commented recommendation to use include_path with value: ".:/php/includes" . Same I found in gentoo, no one set dot in include_path by default. I leave it as it is, and who wants dot, he has to explicitly add it. (Our php projects in SL box works without it).
Too many Christians in this bug? Comment #4 was from Christian R. ;-) However, http://de.php.net/manual/en/ini.core.php#ini.include-path shows only examples with "." in the include_path, so this seems to be the upstream recommendation. What about my comment #8? PHP includes files from the current directory even if "." is *not* in include_path (most times, see comment #8 for details). I guess this is not intended - maybe a bug in PHP? Not reopening for now, but please add a comment about comment #8 ;-)
Petr: this is a real bug, since the default behaviour will not be the expected behaviour. this will break a lot well written code.
this annoyance caused by a simple dot, has been fixed for 10.1 ;-)
Indeed, and it is still fixed on 10.2 :-)