Bug 129682

Summary: php.ini contains broken include_path ("." missing)
Product: [openSUSE] SUSE LINUX 10.0 Reporter: Christian Boltz <suse-beta>
Component: NetworkAssignee: Petr Ostadal <postadal>
Status: VERIFIED INVALID QA Contact: E-mail List <qa-bugs>
Severity: Normal    
Priority: P5 - None CC: crrodriguez, werner
Version: Final   
Target Milestone: ---   
Hardware: Other   
OS: Other   
Whiteboard:
Found By: Other Services Priority:
Business Priority: Blocker: ---
Marketing QA Status: --- IT Deployment: ---

Description Christian Boltz 2005-10-20 11:27:47 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 ;-)
Comment 1 Dr. Werner Fink 2005-10-20 11:52:33 UTC
The `.' in path is a SECURITY risk.  Please fix your scripts.
Comment 2 Dr. Werner Fink 2005-10-20 11:53:22 UTC
Due security the risk the request is INVALID
Comment 3 Christian Boltz 2005-10-21 22:59:03 UTC
> 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.
Comment 4 Cristian Rodríguez 2005-10-24 22:13:40 UTC
 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.
 

 

Comment 5 Cristian Rodríguez 2005-10-24 22:52:22 UTC
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."


 
Comment 6 Bill Wayson 2005-11-02 16:28:04 UTC
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.
Comment 7 Petr Ostadal 2005-11-21 11:56:46 UTC
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?
Comment 8 Christian Boltz 2005-11-21 20:21:12 UTC
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.
Comment 9 Dr. Werner Fink 2005-11-22 10:55:02 UTC
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?
Comment 10 Cristian Rodríguez 2005-11-24 06:02:33 UTC
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 )










 
Comment 11 Dr. Werner Fink 2005-11-24 10:22:59 UTC
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.
Comment 12 Cristian Rodríguez 2005-11-24 15:46:52 UTC
"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" ?
Comment 13 Dr. Werner Fink 2005-11-29 10:09:39 UTC
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.
Comment 14 Cristian Rodríguez 2005-11-29 16:07:11 UTC
<?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 ...     

     }
     
 ?>
Comment 15 Cristian Rodríguez 2005-11-29 16:24:57 UTC
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_ ...
Comment 16 Christian Boltz 2005-12-22 10:41:33 UTC
Still waiting for an anwser. Petr?
Comment 17 Petr Ostadal 2006-01-16 09:52:12 UTC
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).
Comment 18 Christian Boltz 2006-01-16 16:55:18 UTC
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 ;-)
Comment 19 Cristian Rodríguez 2006-01-17 17:37:20 UTC
Petr: this is a real bug, since the default behaviour will not be the expected behaviour.
this will break a lot well written code.





Comment 20 Cristian Rodríguez 2006-01-26 07:16:36 UTC
this annoyance caused by a simple dot, has been fixed for 10.1 ;-)
Comment 21 Christian Boltz 2007-06-11 21:46:36 UTC
Indeed, and it is still fixed on 10.2 :-)