phpbar.de logo

Mailinglisten-Archive

[php] WINDOWS-Version: Php v3.0.12

[php] WINDOWS-Version: Php v3.0.12

Kristian =?iso-8859-1?Q?K=F6hntopp?= kk_(at)_netuse.de
Thu, 11 Nov 1999 11:49:03 +0100


Andreas Otto wrote:
> > Wie ist in diesem Paket "--enable-force-cgi-redirect" gesetzt? Damit haben
> > eine ganze Menge PHPLIB-Anwender Probleme und man hat wohl auch ein
> > Sicherheitsloch, wenn es nicht gesetzt ist.
> 
> hier der ausschnitt aus meiner config.w32.h
> 
> #define FORCE_CGI_REDIRECT 1

Was macht FORCE_CGI_REDIRECT?
=============================

kk_(at)_wwwx ~/Source/php3 $ find . -name \*.c -print0 | 
> xargs -0 grep -l FORCE_CGI_REDIRECT
./main.c

Das Symbol tritt nur in main.c auf. Dort heißt es:

kk_(at)_wwwx ~/Source/php3 $ less -N main.c
  1454                  /* Build the special-case PHP_SELF variable for the CGI
  1454  version */
  1455                  char *pi;
  1456  #if FORCE_CGI_REDIRECT
  1457                  pi = GLOBAL(request_info).path_info;
  1458                  tmp.value.str.val = emalloc(((pi)?strlen(pi):0) + 1);
  1459                  tmp.value.str.len = _php3_sprintf(tmp.value.str.val, "%s
  1459  ", (pi ? pi : ""));     /* SAFE */
  1460                  tmp.type = IS_STRING;
  1461  #else
  1462                  int l = 0;
  1463                  char *sn;
  1464                  sn = GLOBAL(request_info).script_name;
  1465                  pi = GLOBAL(request_info).path_info;
  1466                  if (sn)
  1467                          l += strlen(sn);
  1468                  if (pi)
  1469                          l += strlen(pi);
  1470                  if (pi && sn && !strcmp(pi, sn)) {
  1471                          l -= strlen(pi);
  1472                          pi = NULL;
  1473                  }
  1474                  tmp.value.str.val = emalloc(l + 1);
  1475                  tmp.value.str.len = _php3_sprintf(tmp.value.str.val, "%s
  1475  %s", (sn ? sn : ""), (pi ? pi : ""));   /* SAFE */
  1476                  tmp.type = IS_STRING;
  1477  #endif
  1478                  _php3_hash_update(&GLOBAL(symbol_table), "PHP_SELF", siz
  1478  eof("PHP_SELF"), (void *) & tmp, sizeof(pval), NULL);

In Deutsch: Wenn wir ein CGI PHP bauen und FCR gesetzt ist, wird 
PHP_SELF als Kopie von PATH_INFO definiert. Wenn wir ein CGI PHP
bauen und FCR nicht gesetzt ist, wird PHP_SELF als Catenation von
SCRIPT_NAME und PATH_INFO gebaut. Das ist bei CGI PHP "falsch", weil
dann der Interpretername mit im Pfad bei PHP_SELF erscheint (Der
"/php/php.exe/test.php3"-Effekt). 

PHPLIB funktioniert so nicht, es sei denn, man tauscht alle Vorkommen 
von PHP_SELF durch PATH_INFO aus. Das ist nicht empfohlen, wegen des
Sicherheitsproblems weiter unten.



Außerdem entsteht folgendes Sicherheitsloch:

  1679  #if FORCE_CGI_REDIRECT
  1680                  if (!getenv("REDIRECT_STATUS")) {
  1681                          if (php3_header())
  1682                                  PUTS("<b>Security Alert!</b>  PHP CGI ca
  1682  nnot be accessed directly.\n\
  1683  \n\
[ ... ]
  1697                          /* remove that detailed explanation some time */
  1698
  1699                          return FAILURE;
  1700                  }
  1701  #endif                                                  /* FORCE_CGI_RED
  1701  IRECT */
  1702          }

Das bedeutet, ohne FORCE_CGI_REDIRECT sollte man problemlos auch
von außen /php/php.exe/../../../../../../../etc/passwd aufrufen können,
für die passende Anzahl von /../ und für die gewünschte Datei an Stelle
von /etc/passwd. Ich weiß nicht, mit welchen Rechten PHP auf einer Windows-
Kiste als CGI gestartet wird, aber unter Windows95/98 ist es natürlich root.


Dies sind die beiden einzigen Stellen in PHP3, an denen das Symbol 
FORCE_CGI_REDIRECT in *.c-Dateien vorkommt. Man kann also zusammenfassend
sagen, daß ein CGI PHP ohne FORCE_CGI_REDIRECT ein Dosenöffner ist und zwar
sowohl auf Unix als auch unter Windows. Das entsprechende Binary sollte
entfernt werden. Der Test besteht darin, für eine existierende Datei
außerhalb der DocRoot /php/php.exe/../../ und so weiter aufzurufen und
zu sehen, ob man den o.a. "Security Alert" bekommt. Wenn nicht -> PHP
Interpreter austauschen.

Ein PHP mit FCR ist auf Webservern nicht einsetzbar, die

- CGI nicht endungsbasiert starten können (etwa: Netscape Server
  ohne Kwazy Redirect-Module).
- die bei internen Redirects keine Variable REDIRECT_STATUS
  erzeugen (der Inhalt der Variablen ist egal).

Dort muß man ein PHP ohne FCR einsetzen, mit den oben erwähnten Sicherheits-
und Anpassungsproblemen. Es ist günstiger, in solchen Fällen nicht nur das PHP,
sondern auch den Webserver auszutauschen, weil man sonst in Nullkommanix
seine Kiste los ist ("You are owned!").

Kristian

-- 
Kristian Köhntopp, NetUSE Kommunikationstechnologie GmbH
Siemenswall, D-24107 Kiel, Germany, +49 431 386 436 00
Using PHP3? See our web development library at
http://phplib.netuse.de/ (We have moved! Update your bookmarks!)


php::bar PHP Wiki   -   Listenarchive