Hi all,

Concerning these phpMyAdmin security issues the following:

Thomas Babut wrote:
> 3 security issues were fixed with the new version of phpMyAdmin 2.9.1.1.
> All 3 issues affects all previous versions of phpMyAdmin. This also
> applies to Sarge.
> 
> See this security announcements:
> http://www.phpmyadmin.net/home_page/security.php?issue=PMASA-2006-7

This partially applies to sarge, but the part that applies is only
exploitable when register_globals = On. Is that setup security
supported? If it is, we can use the attached simple patch.

> http://www.phpmyadmin.net/home_page/security.php?issue=PMASA-2006-8

Path disclosure, hence not relevant to Debian.

> http://www.phpmyadmin.net/home_page/security.php?issue=PMASA-2006-9

This is a feature that was insecure by design: the X-Forwarded-For HTTP
header was used to determine the IP of a user to match it against an
allow/deny list; this HTTP header is of course easily settable by any
client.

The solution is that the behaviour is changed and an extra configuration
parameter has been added. Is this suitable for sarge? See also patch.


thanks,
Thijs
--- phpmyadmin-2.6.2.orig/libraries/display_tbl.lib.php
+++ phpmyadmin-2.6.2/libraries/display_tbl.lib.php
@@ -7,6 +7,16 @@
  */
 
 /**
+ * Avoids undefined variables
+ */
+if (!isset($pos)) {
+    $pos = 0;
+} else {
+    /* We need this to be a integer */
+    $pos = (int)$pos;
+}
+
+/**
  * Defines the display mode to use for the results of a sql query
  *
  * It uses a synthetic string that contains all the required informations.
Index: phpMyAdmin/Documentation.html
===================================================================
--- phpMyAdmin/Documentation.html	(revision 9680)
+++ phpMyAdmin/Documentation.html	(revision 9736)
@@ -976,7 +976,11 @@
         listed in the <i>allow</i> rules, and not listed in the <i>deny</i>
         rules. This is the <b>most</b> secure means of using Allow/Deny rules,
         and was available in Apache by specifying allow and deny rules without
-        setting any order.
+        setting any order.<br /><br />
+
+        Please also see <a
+        href="#cfg_TrustedProxies">$cfg['TrustedProxies']</a> for detecting IP
+        address behind proxies.
     </dd>
     <dt id="servers_allowdeny_rules">
         <span id="cfg_Servers_AllowDeny_rules">$cfg['Servers'][$i]['AllowDeny']['rules']</span> array of strings
@@ -1399,6 +1403,22 @@
         Character sets will be shown in same order as here listed, so if you
         frequently use some of these move them to the top.</dd>
 
+    <dt id="cfg_TrustedProxies">$cfg['TrustedProxies'] array</dt>
+    <dd>Lists proxies and HTTP headers which are trusted for <a
+        href="#servers_allowdeny_order">IP Allow/Deny</a>. This list is by
+        default empty, you need to fill in some trusted proxy servers if you
+        want to use rules for IP addresses behind proxy.<br /><br />
+
+        The following example specifies that phpMyAdmin should trust a 
+        HTTP_X_FORWARDED_FOR (<tt>X-Forwarded-For</tt>) header coming from the proxy 1.2.3.4:
+<pre>
+$cfg['TrustedProxies'] =
+     array('1.2.3.4' =&gt; 'HTTP_X_FORWARDED_FOR');
+</pre>
+        The $cfg['Servers'][$i]['AllowDeny']['rules'] directive uses the 
+        client's IP address as usual.
+    </dd>
+
     <dt id="cfg_GD2Available">$cfg['GD2Available'] string</dt>
     <dd>Specifies whether GD &gt;= 2 is available. If yes it can be used for
         MIME transformations.<br />
Index: phpMyAdmin/libraries/ip_allow_deny.lib.php
===================================================================
--- phpMyAdmin/libraries/ip_allow_deny.lib.php	(revision 9680)
+++ phpMyAdmin/libraries/ip_allow_deny.lib.php	(revision 9736)
@@ -17,74 +17,26 @@
  */
 function PMA_getIp()
 {
-    global $REMOTE_ADDR;
-    global $HTTP_X_FORWARDED_FOR, $HTTP_X_FORWARDED, $HTTP_FORWARDED_FOR, $HTTP_FORWARDED;
-    global $HTTP_VIA, $HTTP_X_COMING_FROM, $HTTP_COMING_FROM;
-
-    // Get some server/environment variables values
-    if (empty($REMOTE_ADDR) && PMA_getenv('REMOTE_ADDR')) {
-        $REMOTE_ADDR = PMA_getenv('REMOTE_ADDR');
+    /* Get the address of user */
+    if (!empty($_SERVER['REMOTE_ADDR'])) {
+        $direct_ip = $_SERVER['REMOTE_ADDR'];
+    } else {
+        /* We do not know remote IP */
+        return false;
     }
-    if (empty($HTTP_X_FORWARDED_FOR) && PMA_getenv('HTTP_X_FORWARDED_FOR')) {
-        $HTTP_X_FORWARDED_FOR = PMA_getenv('HTTP_X_FORWARDED_FOR');
-    }
-    if (empty($HTTP_X_FORWARDED) && PMA_getenv('HTTP_X_FORWARDED')) {
-        $HTTP_X_FORWARDED = PMA_getenv('HTTP_X_FORWARDED');
-    }
-    if (empty($HTTP_FORWARDED_FOR) && PMA_getenv('HTTP_FORWARDED_FOR')) {
-        $HTTP_FORWARDED_FOR = PMA_getenv('HTTP_FORWARDED_FOR');
-    }
-    if (empty($HTTP_FORWARDED) && PMA_getenv('HTTP_FORWARDED')) {
-        $HTTP_FORWARDED = PMA_getenv('HTTP_FORWARDED');
-    }
-    if (empty($HTTP_VIA) && PMA_getenv('HTTP_VIA')) {
-        $HTTP_VIA = PMA_getenv('HTTP_VIA');
-    }
-    if (empty($HTTP_X_COMING_FROM) && PMA_getenv('HTTP_X_COMING_FROM')) {
-        $HTTP_X_COMING_FROM = PMA_getenv('HTTP_X_COMING_FROM');
-    }
-    if (empty($HTTP_COMING_FROM) && PMA_getenv('HTTP_COMING_FROM')) {
-        $HTTP_COMING_FROM = PMA_getenv('HTTP_COMING_FROM');
-    }
 
-    // Gets the default ip sent by the user
-    if (!empty($REMOTE_ADDR)) {
-        $direct_ip = $REMOTE_ADDR;
-    }
-
-    // Gets the proxy ip sent by the user
-    $proxy_ip     = '';
-    if (!empty($HTTP_X_FORWARDED_FOR)) {
-        $proxy_ip = $HTTP_X_FORWARDED_FOR;
-    } elseif (!empty($HTTP_X_FORWARDED)) {
-        $proxy_ip = $HTTP_X_FORWARDED;
-    } elseif (!empty($HTTP_FORWARDED_FOR)) {
-        $proxy_ip = $HTTP_FORWARDED_FOR;
-    } elseif (!empty($HTTP_FORWARDED)) {
-        $proxy_ip = $HTTP_FORWARDED;
-    } elseif (!empty($HTTP_VIA)) {
-        $proxy_ip = $HTTP_VIA;
-    } elseif (!empty($HTTP_X_COMING_FROM)) {
-        $proxy_ip = $HTTP_X_COMING_FROM;
-    } elseif (!empty($HTTP_COMING_FROM)) {
-        $proxy_ip = $HTTP_COMING_FROM;
-    } // end if... elseif...
-
-    // Returns the true IP if it has been found, else false
-    if (empty($proxy_ip)) {
-        // True IP without proxy
-        return $direct_ip;
-    } else {
+    /* Do we trust this IP as a proxy? If yes we will use it's header. */
+    if (isset($GLOBALS['cfg']['TrustedProxies'][$direct_ip])) {
+        $proxy_ip = PMA_getenv($GLOBALS['cfg']['TrustedProxies'][$direct_ip]);
         $is_ip = preg_match('|^([0-9]{1,3}\.){3,3}[0-9]{1,3}|', $proxy_ip, $regs);
         if ($is_ip && (count($regs) > 0)) {
             // True IP behind a proxy
             return $regs[0];
-        } else {
-            // Can't define IP: there is a proxy but we don't have
-            // information about the true IP
-            return false;
         }
-    } // end if... else...
+    }
+
+    /* Return true IP */
+    return $direct_ip;
 } // end of the 'PMA_getIp()' function


Index: phpMyAdmin/libraries/config.default.php
===================================================================
--- phpMyAdmin/libraries/config.default.php	(revision 9680)
+++ phpMyAdmin/libraries/config.default.php	(revision 9736)
@@ -604,6 +604,8 @@
                                             // does autodetection, which is a bit expensive for
                                             // php < 4.3.0, but it is the only safe vay how to
                                             // determine GD version.
+$cfg['TrustedProxies']        = array();    // List of trusted proxies for IP allow/deny
+
 /**
  * SQL Parser Settings
  */

Attachment: signature.asc
Description: This is a digitally signed message part

Reply via email to