From 37b29231e47a0c4458dc1c15d98588f16f07e1e2 Mon Sep 17 00:00:00 2001
From: Marius Cramer <m.cramer@pixcept.de>
Date: Thu, 06 Aug 2015 03:18:44 -0400
Subject: [PATCH] - don't set password via remoting if field is empty

---
 interface/lib/classes/tform_base.inc.php |  114 +++++++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 90 insertions(+), 24 deletions(-)

diff --git a/interface/lib/classes/tform_base.inc.php b/interface/lib/classes/tform_base.inc.php
index e27940d..784e96a 100644
--- a/interface/lib/classes/tform_base.inc.php
+++ b/interface/lib/classes/tform_base.inc.php
@@ -98,6 +98,7 @@
 	var $errorMessage = '';
 
 	var $dateformat = "d.m.Y";
+	var $datetimeformat = 'd.m.Y H:i';
 	var $formDef = array();
 	var $wordbook;
 	var $module;
@@ -153,6 +154,7 @@
 		$this->wordbook = $wb;
 
 		$this->dateformat = $app->lng('conf_format_dateshort');
+		$this->datetimeformat = $app->lng('conf_format_datetime');
 
 		return true;
 	}
@@ -347,7 +349,7 @@
 				return $values;
 			} else {
 				$client_group_id = $_SESSION["s"]["user"]["default_group"];
-				$client = $app->db->queryOneRecord("SELECT ".$limit_parts[1]." as lm FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id");
+				$client = $app->db->queryOneRecord("SELECT ".$limit_parts[1]." as lm FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = ?", $client_group_id);
 				$allowed = explode(',', $client['lm']);
 			}
 		}
@@ -359,19 +361,19 @@
 			} else {
 				//* Get the limits of the client that is currently logged in
 				$client_group_id = $_SESSION["s"]["user"]["default_group"];
-				$client = $app->db->queryOneRecord("SELECT parent_client_id FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id");
+				$client = $app->db->queryOneRecord("SELECT parent_client_id FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = ?", $client_group_id);
 				//echo "SELECT parent_client_id FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id";
 				//* If the client belongs to a reseller, we will check against the reseller Limit too
 				if($client['parent_client_id'] != 0) {
 
 					//* first we need to know the groups of this reseller
-					$tmp = $app->db->queryOneRecord("SELECT userid, groups FROM sys_user WHERE client_id = ".$client['parent_client_id']);
+					$tmp = $app->db->queryOneRecord("SELECT userid, groups FROM sys_user WHERE client_id = ?", $client['parent_client_id']);
 					$reseller_groups = $tmp["groups"];
 					$reseller_userid = $tmp["userid"];
 
 					// Get the limits of the reseller of the logged in client
 					$client_group_id = $_SESSION["s"]["user"]["default_group"];
-					$reseller = $app->db->queryOneRecord("SELECT ".$limit_parts[1]." as lm FROM client WHERE client_id = ".$client['parent_client_id']);
+					$reseller = $app->db->queryOneRecord("SELECT ".$limit_parts[1]." as lm FROM client WHERE client_id = ?", $client['parent_client_id']);
 					$allowed = explode(',', $reseller['lm']);
 				} else {
 					return $values;
@@ -412,6 +414,28 @@
 		if(!is_array($this->formDef)) $app->error("No form definition found.");
 		if(!is_array($this->formDef['tabs'][$tab])) $app->error("The tab is empty or does not exist (TAB: $tab).");
 
+		/* CSRF PROTECTION */
+		// generate csrf protection id and key
+		$csrf_token = $app->auth->csrf_token_get($this->formDef['name']);
+		$_csrf_id = $csrf_token['csrf_id'];
+		$_csrf_value = $csrf_token['csrf_key'];
+		
+		$this->formDef['tabs'][$tab]['fields']['_csrf_id'] = array(
+			'datatype' => 'VARCHAR',
+			'formtype' => 'TEXT',
+			'default' => $_csrf_id,
+			'value' => $_csrf_id
+		);
+		$this->formDef['tabs'][$tab]['fields']['_csrf_key'] = array(
+			'datatype' => 'VARCHAR',
+			'formtype' => 'TEXT',
+			'default' => $_csrf_value,
+			'value' => $_csrf_value
+		);
+		$record['_csrf_id'] = $_csrf_id;
+		$record['_csrf_key'] = $_csrf_value;
+		/* CSRF PROTECTION */
+		
 		$new_record = array();
 		if($action == 'EDIT') {
 			$record = $this->decode($record, $tab);
@@ -445,7 +469,7 @@
 						if(is_array($field['value'])) {
 							foreach($field['value'] as $k => $v) {
 								$selected = ($k == $val)?' SELECTED':'';
-								if(!empty($this->wordbook[$v]))
+								if(isset($this->wordbook[$v]))
 									$v = $this->wordbook[$v];
 								$out .= "<option value='$k'$selected>".$this->lng($v)."</option>\r\n";
 							}
@@ -667,8 +691,46 @@
 	 */
 	protected function _encode($record, $tab, $dbencode = true, $api = false) {
 		global $app;
-		if($api == true) $fields = &$this->formDef['fields'];
-		else $fields = &$this->formDef['tabs'][$tab]['fields'];
+		if($api == true) {
+			$fields = &$this->formDef['fields'];
+		} else {
+			$fields = &$this->formDef['tabs'][$tab]['fields'];
+			/* CSRF PROTECTION */
+			if(isset($_POST) && is_array($_POST)) {
+				$_csrf_valid = false;
+				if(isset($_POST['_csrf_id']) && isset($_POST['_csrf_key'])) {
+					$_csrf_id = trim($_POST['_csrf_id']);
+					$_csrf_key = trim($_POST['_csrf_key']);
+					if(isset($_SESSION['_csrf']) && isset($_SESSION['_csrf'][$_csrf_id]) && isset($_SESSION['_csrf_timeout']) && isset($_SESSION['_csrf_timeout'][$_csrf_id])) {
+						if($_SESSION['_csrf'][$_csrf_id] === $_csrf_key && $_SESSION['_csrf_timeout'] >= time()) $_csrf_valid = true;
+					}
+				}
+				if($_csrf_valid !== true) {
+					$app->log('CSRF attempt blocked. Referer: ' . (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : 'unknown'), LOGLEVEL_WARN);
+					$errmsg = 'err_csrf_attempt_blocked';
+					$this->errorMessage .= ($api == true ? $errmsg : $this->wordbook[$errmsg]."<br />") . "\r\n";
+					unset($_POST);
+					unset($record);
+				}
+				
+				if(isset($_SESSION['_csrf_timeout']) && is_array($_SESSION['_csrf_timeout'])) {
+					$to_unset = array();
+					foreach($_SESSION['_csrf_timeout'] as $_csrf_id => $timeout) {
+						if($timeout < time()) $to_unset[] = $_csrf_id;
+					}
+					foreach($to_unset as $_csrf_id) {
+						$_SESSION['_csrf'][$_csrf_id] = null;
+						$_SESSION['_csrf_timeout'][$_csrf_id] = null;
+						unset($_SESSION['_csrf'][$_csrf_id]);
+						unset($_SESSION['_csrf_timeout'][$_csrf_id]);
+					}
+					unset($to_unset);
+				}
+			}
+			/* CSRF PROTECTION */
+		}
+		
+		$new_record = array();
 		if(is_array($record)) {
 			foreach($fields as $key => $field) {
 
@@ -708,13 +770,8 @@
 					if($record[$key] != '' && $record[$key] != '0000-00-00') {
 						if(function_exists('date_parse_from_format')) {
 							$date_parts = date_parse_from_format($this->dateformat, $record[$key]);
-							//list($tag,$monat,$jahr) = explode('.',$record[$key]);
-							$new_record[$key] = $date_parts['year'].'-'.$date_parts['month'].'-'.$date_parts['day'];
-							//$tmp = strptime($record[$key],$this->dateformat);
-							//$new_record[$key] = ($tmp['tm_year']+1900).'-'.($tmp['tm_mon']+1).'-'.$tmp['tm_mday'];
+							$new_record[$key] = $date_parts['year'].'-'.str_pad($date_parts['month'], 2, "0", STR_PAD_LEFT).'-'.str_pad($date_parts['day'], 2, "0", STR_PAD_LEFT);
 						} else {
-							//$tmp = strptime($record[$key],$this->dateformat);
-							//$new_record[$key] = ($tmp['tm_year']+1900).'-'.($tmp['tm_mon']+1).'-'.$tmp['tm_mday'];
 							$tmp = strtotime($record[$key]);
 							$new_record[$key] = date('Y-m-d', $tmp);
 						}
@@ -724,8 +781,6 @@
 					break;
 				case 'INTEGER':
 					$new_record[$key] = (isset($record[$key]))?$app->functions->intval($record[$key]):0;
-					//if($new_record[$key] != $record[$key]) $new_record[$key] = $field['default'];
-					//if($key == 'refresh') die($record[$key]);
 					break;
 				case 'DOUBLE':
 					$new_record[$key] = $record[$key];
@@ -735,7 +790,7 @@
 					break;
 
 				case 'DATETIME':
-					if (is_array($record[$key]))
+					/*if (is_array($record[$key]))
 					{
 						$filtered_values = array_map(create_function('$item', 'return (int)$item;'), $record[$key]);
 						extract($filtered_values, EXTR_PREFIX_ALL, '_dt');
@@ -743,7 +798,14 @@
 						if ($_dt_day != 0 && $_dt_month != 0 && $_dt_year != 0) {
 							$new_record[$key] = date( 'Y-m-d H:i:s', mktime($_dt_hour, $_dt_minute, $_dt_second, $_dt_month, $_dt_day, $_dt_year) );
 						}
-					}
+					} else {*/
+						if($record[$key] != '' && $record[$key] != '0000-00-00 00:00:00') {
+							$tmp = strtotime($record[$key]);
+							$new_record[$key] = date($this->datetimeformat, $tmp);
+						} else {
+							$new_record[$key] = '0000-00-00 00:00:00';
+						}
+					/*}*/
 					break;
 				}
 
@@ -810,6 +872,9 @@
 				case 'IDNTOUTF8':
 					$returnval = $app->functions->idn_decode($returnval);
 					break;
+				case 'TRIM':
+					$returnval = trim($returnval);
+					break;
 				default:
 					$this->errorMessage .= "Unknown Filter: ".$filter['type'];
 					break;
@@ -853,7 +918,7 @@
 				if($validator['allowempty'] != 'y') $validator['allowempty'] = 'n';
 				if($validator['allowempty'] == 'n' || ($validator['allowempty'] == 'y' && $field_value != '')){
 					if($this->action == 'NEW') {
-						$num_rec = $app->db->queryOneRecord("SELECT count(*) as number FROM ".$escape.$this->formDef['db_table'].$escape. " WHERE $field_name = '".$app->db->quote($field_value)."'");
+						$num_rec = $app->db->queryOneRecord("SELECT count(*) as number FROM ?? WHERE ?? = ?", $this->formDef['db_table'], $field_name, $field_value);
 						if($num_rec["number"] > 0) {
 							$errmsg = $validator['errmsg'];
 							if(isset($this->wordbook[$errmsg])) {
@@ -863,7 +928,7 @@
 							}
 						}
 					} else {
-						$num_rec = $app->db->queryOneRecord("SELECT count(*) as number FROM ".$escape.$this->formDef['db_table'].$escape. " WHERE $field_name = '".$app->db->quote($field_value)."' AND ".$this->formDef['db_table_idx']." != ".$this->primary_id);
+						$num_rec = $app->db->queryOneRecord("SELECT count(*) as number FROM ?? WHERE ?? = ? AND ?? != ?", $this->formDef['db_table'], $field_name, $field_value, $this->formDef['db_table_idx'], $this->primary_id);
 						if($num_rec["number"] > 0) {
 							$errmsg = $validator['errmsg'];
 							if(isset($this->wordbook[$errmsg])) {
@@ -876,7 +941,7 @@
 				}
 				break;
 			case 'NOTEMPTY':
-				if(empty($field_value)) {
+				if(!isset($field_value) || $field_value === '') {
 					$errmsg = $validator['errmsg'];
 					if(isset($this->wordbook[$errmsg])) {
 						$this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
@@ -1108,6 +1173,7 @@
 	 * @param primary_id
 	 * @return record
 	 */
+	 /* TODO: check for double quoting */
 	protected function _getSQL($record, $tab, $action = 'INSERT', $primary_id = 0, $sql_ext_where = '', $api = false) {
 
 		global $app;
@@ -1139,7 +1205,7 @@
 								$record[$key] = $app->auth->crypt_password(stripslashes($record[$key]));
 								$sql_insert_val .= "'".$app->db->quote($record[$key])."', ";
 							} elseif (isset($field['encryption']) && $field['encryption'] == 'MYSQL') {
-								$tmp = $app->db->queryOneRecord("SELECT PASSWORD('".$app->db->quote(stripslashes($record[$key]))."') as `crypted`");
+								$tmp = $app->db->queryOneRecord("SELECT PASSWORD(?) as `crypted`", stripslashes($record[$key]));
 								$record[$key] = $tmp['crypted'];
 								$sql_insert_val .= "'".$app->db->quote($record[$key])."', ";
 							} else {
@@ -1167,7 +1233,7 @@
 								$record[$key] = $app->auth->crypt_password(stripslashes($record[$key]));
 								$sql_update .= "`$key` = '".$app->db->quote($record[$key])."', ";
 							} elseif (isset($field['encryption']) && $field['encryption'] == 'MYSQL') {
-								$tmp = $app->db->queryOneRecord("SELECT PASSWORD('".$app->db->quote(stripslashes($record[$key]))."') as `crypted`");
+								$tmp = $app->db->queryOneRecord("SELECT PASSWORD(?) as `crypted`", stripslashes($record[$key]));
 								$record[$key] = $tmp['crypted'];
 								$sql_update .= "`$key` = '".$app->db->quote($record[$key])."', ";
 							} else {
@@ -1359,8 +1425,8 @@
 	function getDataRecord($primary_id) {
 		global $app;
 		$escape = '`';
-		$sql = "SELECT * FROM ".$escape.$this->formDef['db_table'].$escape." WHERE ".$this->formDef['db_table_idx']." = ".$primary_id." AND ".$this->getAuthSQL('r', $this->formDef['db_table']);
-		return $app->db->queryOneRecord($sql);
+		$sql = "SELECT * FROM ?? WHERE ?? = ? AND ".$this->getAuthSQL('r', $this->formDef['db_table']);
+		return $app->db->queryOneRecord($sql, $this->formDef['db_table'], $this->formDef['db_table_idx'], $primary_id);
 	}
 
 

--
Gitblit v1.9.1