[21217] Fixing CVE-2010-0404, update the CHANGELOG, prepare the already done 16.016 release

Caeies <[email protected]> Wed, 02 Jun 2010 09:21:48 +0000
Newsgroups gmane.comp.web.phpgroupware.cvs
Message-ID <[email protected]>
Revision: 21217
          http://svn.sv.gnu.org/viewvc/?view=rev&root=phpgroupware&revision=21217
Author:   Caeies
Date:     2010-06-02 09:21:48 +0000 (Wed, 02 Jun 2010)
Log Message:
-----------
Fixing CVE-2010-0404, update the CHANGELOG, prepare the already done 16.016 release

Modified Paths:
--------------
    modules/phpgwapi/branches/branch_0_9_16/doc/CHANGELOG
    modules/phpgwapi/branches/branch_0_9_16/inc/class.auth_sql.inc.php
    modules/phpgwapi/branches/branch_0_9_16/inc/class.auth_sqlssl.inc.php
    modules/phpgwapi/branches/branch_0_9_16/inc/class.crypto.inc.php
    modules/phpgwapi/branches/branch_0_9_16/inc/class.sessions.inc.php
    modules/phpgwapi/branches/branch_0_9_16/inc/class.sessions_db.inc.php
    modules/phpgwapi/branches/branch_0_9_16/inc/class.translation_sql.inc.php
    modules/phpgwapi/branches/branch_0_9_16/inc/common_functions.inc.php
    modules/phpgwapi/branches/branch_0_9_16/inc/functions.inc.php
    modules/phpgwapi/branches/branch_0_9_16/setup/setup.inc.php

Modified: modules/phpgwapi/branches/branch_0_9_16/doc/CHANGELOG
===================================================================
--- modules/phpgwapi/branches/branch_0_9_16/doc/CHANGELOG	2010-06-02 09:19:57 UTC (rev 21216)
+++ modules/phpgwapi/branches/branch_0_9_16/doc/CHANGELOG	2010-06-02 09:21:48 UTC (rev 21217)
@@ -1,4 +1,8 @@
 [0.9.16.016]
+	Security Fixes, Most Credits go to VUPEN Security for pointing them out :
+		- CVE-2010-0403 Local file inclusion.
+		- CVE-2010-0404 Multiple SQL injection.
+
 	phpgwapi :
 		- fix the session not listed in case of using php4 session (which is recommanded). Fixing #23386
 		- fix the Port for postgresql in case of not using the default one.

Modified: modules/phpgwapi/branches/branch_0_9_16/inc/class.auth_sql.inc.php
===================================================================
--- modules/phpgwapi/branches/branch_0_9_16/inc/class.auth_sql.inc.php	2010-06-02 09:19:57 UTC (rev 21216)
+++ modules/phpgwapi/branches/branch_0_9_16/inc/class.auth_sql.inc.php	2010-06-02 09:21:48 UTC (rev 21217)
@@ -32,7 +32,7 @@
 		function authenticate($username, $passwd, $passwd_type)
 		{
 			$db = $GLOBALS['phpgw']->db;
-
+			$username = $db->db_addslashes($username);
 			if ($passwd_type == 'text')
 			{
 				$_passwd = md5($passwd);

Modified: modules/phpgwapi/branches/branch_0_9_16/inc/class.auth_sqlssl.inc.php
===================================================================
--- modules/phpgwapi/branches/branch_0_9_16/inc/class.auth_sqlssl.inc.php	2010-06-02 09:19:57 UTC (rev 21216)
+++ modules/phpgwapi/branches/branch_0_9_16/inc/class.auth_sqlssl.inc.php	2010-06-02 09:21:48 UTC (rev 21217)
@@ -24,7 +24,7 @@
 		function authenticate($username, $passwd)
 		{
 			$db = $GLOBALS['phpgw']->db;
-
+			$username = $db->db_addslashes($username);
 			$local_debug = False;
 
 			if($local_debug)
@@ -46,7 +46,7 @@
 			{
 				// use username only for authentication, ignore X.509 subject in $passwd for now
 				$db->query('SELECT * FROM phpgw_accounts'
-					. " WHERE account_lid = '" . $db->db_addslashes($username) . "'"
+					. " WHERE account_lid = '$username'"
 					. "AND account_status ='A'",__LINE__,__FILE__);
 				$db->next_record();
 			}

Modified: modules/phpgwapi/branches/branch_0_9_16/inc/class.crypto.inc.php
===================================================================
--- modules/phpgwapi/branches/branch_0_9_16/inc/class.crypto.inc.php	2010-06-02 09:19:57 UTC (rev 21216)
+++ modules/phpgwapi/branches/branch_0_9_16/inc/class.crypto.inc.php	2010-06-02 09:21:48 UTC (rev 21217)
@@ -18,7 +18,7 @@
 	class crypto
 	{
 		var $enabled = False;
-		var $debug = False;
+		var $debug = True;
 
 		var $mcrypt_version = '';
 		var $algo = MCRYPT_TRIPLEDES;
@@ -125,8 +125,13 @@
 				echo '<br />' . time() . ' crypto->encrypt() unencrypted data: ---->>>>' . $data . "\n";
 			}
 
-			if(is_array($data) || is_object($data))
+			//XXX CAEIES : always serialize datas to catch wrong keys.
+			//if(is_array($data) || is_object($data))
+			if($data === False)
 			{
+				$data = 'BoolFalse';
+			}
+			{
 				if($this->debug)
 				{
 					echo '<br />' . time() . ' crypto->encrypt() found an "' . gettype($data) . '".  Serializing...' . "\n";
@@ -134,6 +139,7 @@
 				$data = serialize($data);
 				$_obj = True;
 			}
+			/*
 			else
 			{
 				if($this->debug)
@@ -141,7 +147,7 @@
 					echo '<br />' . time() . ' crypto->encrypt() found "' . gettype($data) . '". No serialization...' . "\n";
 				}
 			}
-
+			*/
 			/* Disable all encryption if the admin didn't set it up */
 			if ($this->enabled)
 			{
@@ -246,6 +252,8 @@
 					echo '<br />' . time() . ' crypto->decrypt() found serialized "' . gettype($newdata) . '".  Unserializing...' . "\n";
 					echo '<br />' . time() . ' crypto->decrypt() returning: '; _debug_array($newdata);
 				}
+				if($newdata == 'BoolFalse')
+					return False;
 				return $newdata;
 			}
 			else
@@ -255,7 +263,9 @@
 					echo '<br />' . time() . ' crypto->decrypt() found UNserialized "' . gettype($data) . '".  No unserialization...' . "\n";
 					echo '<br />' . time() . ' crypto->decrypt() returning: ' . $data;
 				}
-				return $data;
+				$GLOBALS['phpgw']->redirect_link('/login.php', 'cd=75');
+				$GLOBALS['phpgw']->common->phpgw_exit(True);
+				return '';
 			}
 		}
 	} // class crypto

Modified: modules/phpgwapi/branches/branch_0_9_16/inc/class.sessions.inc.php
===================================================================
--- modules/phpgwapi/branches/branch_0_9_16/inc/class.sessions.inc.php	2010-06-02 09:19:57 UTC (rev 21216)
+++ modules/phpgwapi/branches/branch_0_9_16/inc/class.sessions.inc.php	2010-06-02 09:21:48 UTC (rev 21217)
@@ -126,8 +126,7 @@
 		function sessions_()
 		{
 			$this->db = $GLOBALS['phpgw']->db;
-			$this->sessionid = get_var('sessionid',array('GET','COOKIE'));
-			$this->kp3       = get_var('kp3',array('GET','COOKIE'));
+			$this->retrieve_values();
 			
 			/* Create the crypto object */
 			$GLOBALS['phpgw']->crypto = CreateObject('phpgwapi.crypto');
@@ -248,13 +247,19 @@
 		{
 			if(empty($sessionid) || !$sessionid)
 			{
-				$sessionid = get_var('sessionid',array('GET','COOKIE'));
-				$kp3       = get_var('kp3',array('GET','COOKIE'));
+				$this->retrieve_values();
+				$sessionid = $this->sessionid;
+				$kp3	   = $this->kp3;
 			}
+			else
+			{
+				//XXX Caeies : Trying something wrong, we are not able to handle that
+				if(!sanitize($sessionid, 'alphanumeric') || !sanitize($kp3, 'alphanumeric'))
+					return False;
+				$this->sessionid = $sessionid;
+				$this->kp3       = $kp3;
+			}
 			
-			$this->sessionid = $sessionid;
-			$this->kp3       = $kp3;
-			
 			$session = $this->read_session($sessionid);
 			//echo "<p>session::verify(id='$sessionid'): \n"; print_r($session); echo "</p>\n";
 			
@@ -592,7 +597,7 @@
 		function log_access($sessionid,$login='',$user_ip='',$account_id='')
 		{
 			$now = time();
-
+			$sessionid = $this->db->db_addslashes($sessionid);
 			if ($login != '')
 			{
 				$GLOBALS['phpgw']->db->query('INSERT INTO phpgw_access_log(sessionid,loginid,ip,li,lo,account_id)'.
@@ -1201,6 +1206,12 @@
 			/* if no extravars then we return the cleaned up url/scriptname */
 			return $url;
 		}
+
+		function retrieve_values()
+		{
+			$this->sessionid = reg_var('sessionid',array('GET','COOKIE'), 'alphanumeric', '', False);
+			$this->kp3       = reg_var('kp3',array('GET','COOKIE'), 'alphanumeric', '', False);
+		}
 		
 		/**
 		* The remaining methods are abstract - as they are unique for each session handler

Modified: modules/phpgwapi/branches/branch_0_9_16/inc/class.sessions_db.inc.php
===================================================================
--- modules/phpgwapi/branches/branch_0_9_16/inc/class.sessions_db.inc.php	2010-06-02 09:19:57 UTC (rev 21216)
+++ modules/phpgwapi/branches/branch_0_9_16/inc/class.sessions_db.inc.php	2010-06-02 09:21:48 UTC (rev 21217)
@@ -25,7 +25,7 @@
 		
 		function read_session($sessionid)
 		{
-			$this->db->query("SELECT * FROM phpgw_sessions WHERE session_id='" . $this->sessionid . "'",__LINE__,__FILE__);
+			$this->db->query("SELECT * FROM phpgw_sessions WHERE session_id='" . $this->db->db_addslashes($this->sessionid) . "'",__LINE__,__FILE__);
 			$this->db->next_record();
 			
 			return $this->db->Record;
@@ -47,9 +47,10 @@
 
 		function register_session($login,$user_ip,$now,$session_flags)
 		{
-			$GLOBALS['phpgw']->db->query("INSERT INTO phpgw_sessions VALUES ('" . $this->sessionid
-				. "','".$login."','" . $user_ip . "','"
-				. $now . "','" . $now . "','" . $_SERVER['PHP_SELF'] . "','" . $session_flags
+			$GLOBALS['phpgw']->db->query("INSERT INTO phpgw_sessions VALUES ('" . $this->db->db_addslashes($this->sessionid)
+				. "','".$this->db->db_addslashes($login)."','" . $this->db->db_addslashes($user_ip) . "','"
+				. $this->db->db_addslashes($now) . "','" . $this->db->db_addslashes($now) . "','" . $this->db->db_addslashes($_SERVER['PHP_SELF']) . "','" 
+				. $this->db->db_addslashes($session_flags)
 				. "')",__LINE__,__FILE__);
 		}
 
@@ -71,12 +72,12 @@
 			{
 				$action = $this->xmlrpc_method_called;
 			}
-
+			$action = $this->db->db_addslashes($action);
 			$GLOBALS['phpgw']->db->query("UPDATE phpgw_sessions SET session_dla='" . time() . "', session_action='$action' "
-				. "WHERE session_id='" . $this->sessionid."'",__LINE__,__FILE__);
+				. "WHERE session_id='" . $this->db->db_addslashes($this->sessionid)."'",__LINE__,__FILE__);
 
 			$GLOBALS['phpgw']->db->query("UPDATE phpgw_app_sessions SET session_dla='" . time() . "' "
-				. "WHERE sessionid='" . $this->sessionid."'",__LINE__,__FILE__);
+				. "WHERE sessionid='" . $this->db->db_addslashes($this->sessionid)."'",__LINE__,__FILE__);
 			return True;
 		}
 
@@ -86,7 +87,7 @@
 			{
 				return False;
 			}
-
+			$sessionid = $this->db->db_addslashes($sessionid);
 			$GLOBALS['phpgw']->db->transaction_begin();
 			$GLOBALS['phpgw']->db->query("DELETE FROM phpgw_sessions WHERE session_id='"
 				. $sessionid . "'",__LINE__,__FILE__);
@@ -112,7 +113,7 @@
 		{
 			$account_id = get_account_id($accountid,$this->account_id);
 
-			$query = "DELETE FROM phpgw_app_sessions WHERE loginid = '".$account_id."'"
+			$query = "DELETE FROM phpgw_app_sessions WHERE loginid = '".intval($account_id)."'"
 				." AND app = 'phpgwapi' AND location = 'phpgw_info_cache'";
 
 			$GLOBALS['phpgw']->db->query($query);
@@ -129,8 +130,8 @@
 			if ($data == '##NOTHING##')
 			{
 				$query = "SELECT content FROM phpgw_app_sessions WHERE"
-					." sessionid='".$this->sessionid."' AND loginid='".$this->account_id."'"
-					." AND app = '".$appname."' AND location='".$location."'";
+					." sessionid='".$this->db->db_addslashes($this->sessionid)."' AND loginid='".intval($this->account_id)."'"
+					." AND app = '".$this->db->db_addslashes($appname)."' AND location='".$this->db->db_addslashes($location)."'";
 	
 				$GLOBALS['phpgw']->db->query($query,__LINE__,__FILE__);
 				$GLOBALS['phpgw']->db->next_record();
@@ -155,8 +156,8 @@
 			else
 			{
 				$GLOBALS['phpgw']->db->query("SELECT content FROM phpgw_app_sessions WHERE "
-					. "sessionid = '".$this->sessionid."' AND loginid = '".$this->account_id."'"
-					. " AND app = '".$appname."' AND location = '".$location."'",__LINE__,__FILE__);
+					. "sessionid = '".$this->db->db_addslashes($this->sessionid)."' AND loginid = '".intval($this->account_id)."'"
+					. " AND app = '".$this->db->db_addslashes($appname)."' AND location = '".$this->db->db_addslashes($location)."'",__LINE__,__FILE__);
 
 				$encrypteddata = $GLOBALS['phpgw']->crypto->encrypt($data);
 				$encrypteddata = $GLOBALS['phpgw']->db->db_addslashes($encrypteddata);
@@ -164,15 +165,15 @@
 				if ($GLOBALS['phpgw']->db->num_rows()==0)
 				{
 					$GLOBALS['phpgw']->db->query("INSERT INTO phpgw_app_sessions (sessionid,loginid,app,location,content,session_dla) "
-						. "VALUES ('".$this->sessionid."','".$this->account_id."','".$appname
-						. "','".$location."','".$encrypteddata."','" . time() . "')",__LINE__,__FILE__);
+						. "VALUES ('".$this->db->db_addslashes($this->sessionid)."','".intval($this->account_id)."','".$this->db->db_addslashes($appname)
+						. "','".$this->db->db_addslashes($location)."','".$encrypteddata."','" . time() . "')",__LINE__,__FILE__);
 				}
 				else
 				{
 					$GLOBALS['phpgw']->db->query("UPDATE phpgw_app_sessions SET content='".$encrypteddata."'"
-						. "WHERE sessionid = '".$this->sessionid."'"
-						. "AND loginid = '".$this->account_id."' AND app = '".$appname."'"
-						. "AND location = '".$location."'",__LINE__,__FILE__);
+						. "WHERE sessionid = '".$this->db->db_addslashes($this->sessionid)."'"
+						. "AND loginid = '".intval($this->account_id)."' AND app = '".$this->db->db_addslashes($appname)."'"
+						. "AND location = '".$this->db->db_addslashes($location)."'",__LINE__,__FILE__);
 				}
 				return $data;
 			}

Modified: modules/phpgwapi/branches/branch_0_9_16/inc/class.translation_sql.inc.php
===================================================================
--- modules/phpgwapi/branches/branch_0_9_16/inc/class.translation_sql.inc.php	2010-06-02 09:19:57 UTC (rev 21216)
+++ modules/phpgwapi/branches/branch_0_9_16/inc/class.translation_sql.inc.php	2010-06-02 09:21:48 UTC (rev 21217)
@@ -35,6 +35,7 @@
 			// php-nuke and postnuke are using $GLOBALS['lang'] too
 			// as string
 			// this makes many problems
+        $db = $GLOBALS['phpgw']->db;
 			if (!isset($GLOBALS['lang']) || !$GLOBALS['lang'] || !is_array($GLOBALS['lang']))
 			{
 				$GLOBALS['lang'] = array();
@@ -48,7 +49,7 @@
 					$userlang = 'en';
 				}
 				$sql = "select message_id,content from phpgw_lang where lang = '".$userlang."' ".
-					"and (app_name = '".$GLOBALS['phpgw_info']['flags']['currentapp']."' or app_name = 'common' or app_name = 'all')";
+					"and (app_name = '".$db->db_addslashes($GLOBALS['phpgw_info']['flags']['currentapp'])."' or app_name = 'common' or app_name = 'all')";
 
 				if (strcasecmp ($GLOBALS['phpgw_info']['flags']['currentapp'], 'common')>0)
 				{
@@ -59,7 +60,6 @@
 					$sql .= ' order by app_name desc';
 				}
         
-        $db = $GLOBALS['phpgw']->db;				
         $db->query($sql,__LINE__,__FILE__);
         while ($db->next_record())
         {
@@ -103,7 +103,7 @@
 			{
 				$userlang = 'en';
 			}
-			$sql = "select message_id,content from phpgw_lang where lang like '".$userlang."' and app_name like '".$app."'";
+			$sql = "select message_id,content from phpgw_lang where lang like '".$userlang."' and app_name like '".$GLOBALS['phpgw']->db->db_addslashes($app)."'";
 			$GLOBALS['phpgw']->db->query($sql,__LINE__,__FILE__);
 			$GLOBALS['phpgw']->db->next_record();
 			$count = $GLOBALS['phpgw']->db->num_rows();

Modified: modules/phpgwapi/branches/branch_0_9_16/inc/common_functions.inc.php
===================================================================
--- modules/phpgwapi/branches/branch_0_9_16/inc/common_functions.inc.php	2010-06-02 09:19:57 UTC (rev 21216)
+++ modules/phpgwapi/branches/branch_0_9_16/inc/common_functions.inc.php	2010-06-02 09:21:48 UTC (rev 21217)
@@ -189,7 +189,7 @@
 				}
 				break;
 			case 'alphanumeric':
-				if (preg_match("/^[a-z0-9 -._]+$/i", $string))
+				if (preg_match("/^[a-z0-9\.]+$/i", $string))
 				{
 					return True;
 				}

Modified: modules/phpgwapi/branches/branch_0_9_16/inc/functions.inc.php
===================================================================
--- modules/phpgwapi/branches/branch_0_9_16/inc/functions.inc.php	2010-06-02 09:19:57 UTC (rev 21216)
+++ modules/phpgwapi/branches/branch_0_9_16/inc/functions.inc.php	2010-06-02 09:21:48 UTC (rev 21217)
@@ -96,13 +96,13 @@
 		$GLOBALS['login'] = $_POST['login'];
 		if (strstr($GLOBALS['login'],'@') === False)
 		{
-			$GLOBALS['login'] .= '@' . get_var('logindomain',array('POST'),$GLOBALS['phpgw_info']['server']['default_domain']);
+			$GLOBALS['login'] .= '@' . reg_var('logindomain',array('POST'), 'alphanumeric',$GLOBALS['phpgw_info']['server']['default_domain'], false);
 		}
 		list(,$GLOBALS['phpgw_info']['user']['domain']) = explode('@',$GLOBALS['login']);
 	}
 	else	// on "normal" pageview
 	{
-		$GLOBALS['phpgw_info']['user']['domain'] = get_var('domain', array('GET', 'COOKIE'), FALSE);
+		$GLOBALS['phpgw_info']['user']['domain'] = reg_var('domain', array('GET', 'COOKIE'), 'alphanumeric', false, false);
 	}
 
 	if (@isset($GLOBALS['phpgw_domain'][$GLOBALS['phpgw_info']['user']['domain']]))
@@ -282,6 +282,21 @@
 	\****************************************************************************/
 	register_shutdown_function(array($GLOBALS['phpgw']->common, 'phpgw_final'));
 
+	//XXX Check if the application we ask for is known :
+	$GLOBALS['phpgw']->applications->read_installed_apps();	// to get translated app-titles
+	//The not registred applications potentially present in our installation
+	$all_applications = array('login' => 'login', 'logout' => 'logout', 'home' => 'home', 'notifywindow' => 'notifywindow', 'et_media' => 'et_media', 'et_notes'=>'et_notes', 'sitemgr_link' => 'sitemgr_link', 'sitemgr_site' => 'sitemgr_site', 'about' => 'about');
+	//merge them all
+	$all_applications = array_merge($all_applications, $GLOBALS['phpgw_info']['apps']);
+	//check that the app is known
+	if(!array_key_exists($GLOBALS['phpgw_info']['flags']['currentapp'], $all_applications))
+	{
+		$lang_args = array('text'=>'W-Permissions, Attempted to access %1','p1'=>$GLOBALS['phpgw_info']['flags']['currentapp']);
+		$GLOBALS['phpgw_info']['flags']['currentapp'] = 'login';
+		$GLOBALS['phpgw']->log->write($lang_args);
+		echo '<p><center><b>'.lang('Access not permitted').'</b></center>';
+		exit;
+	}
 	/****************************************************************************\
 	* Stuff to use if logging in or logging out                                  *
 	\****************************************************************************/
@@ -458,7 +473,7 @@
 		{
 			$GLOBALS['phpgw']->datetime = CreateObject('phpgwapi.phpgw_datetime');
 		}
-		$GLOBALS['phpgw']->applications->read_installed_apps();	// to get translated app-titles
+		//$GLOBALS['phpgw']->applications->read_installed_apps();	// to get translated app-titles
 		
 		/*************************************************************************\
 		* Load the header unless the developer turns it off                       *

Modified: modules/phpgwapi/branches/branch_0_9_16/setup/setup.inc.php
===================================================================
--- modules/phpgwapi/branches/branch_0_9_16/setup/setup.inc.php	2010-06-02 09:19:57 UTC (rev 21216)
+++ modules/phpgwapi/branches/branch_0_9_16/setup/setup.inc.php	2010-06-02 09:21:48 UTC (rev 21217)
@@ -15,7 +15,7 @@
 	/* Basic information about this app */
 	$setup_info['phpgwapi']['name']      = 'phpgwapi';
 	$setup_info['phpgwapi']['title']     = 'phpgwapi';
-	$setup_info['phpgwapi']['version']   = '0.9.16.015';
+	$setup_info['phpgwapi']['version']   = '0.9.16.016';
 	$setup_info['phpgwapi']['versions']['current_header'] = '1.24';
 	$setup_info['phpgwapi']['enable']    = 3;
 	$setup_info['phpgwapi']['app_order'] = 1;