From f2fc77f29ce81b6493ab629e0f8f9da2b3df857d Mon Sep 17 00:00:00 2001
From: Till Brehm <tbrehm@ispconfig.org>
Date: Thu, 31 Jul 2014 15:46:18 -0400
Subject: [PATCH] Improved input validation.

---
 interface/web/sites/form/ftp_user.tform.php    |    5 ++
 interface/web/sites/shell_user_edit.php        |   14 +++++++
 interface/web/sites/form/shell_user.tform.php  |   13 +++++-
 interface/web/sites/ftp_user_edit.php          |   13 ++++++
 interface/lib/classes/functions.inc.php        |   12 +++++-
 interface/web/sites/lib/lang/en_shell_user.lng |    3 +
 interface/web/sites/lib/lang/en_ftp_user.lng   |    2 +
 server/lib/classes/system.inc.php              |   12 +++++-
 8 files changed, 67 insertions(+), 7 deletions(-)

diff --git a/interface/lib/classes/functions.inc.php b/interface/lib/classes/functions.inc.php
index ddee8da..29feffd 100644
--- a/interface/lib/classes/functions.inc.php
+++ b/interface/lib/classes/functions.inc.php
@@ -427,7 +427,11 @@
 	public function is_allowed_user($username, $restrict_names = false) {
 		global $app;
 		
-		if($username == 'root') return false;
+		$name_blacklist = array('root','ispconfig','vmail','getmail');
+		if(in_array($username,$name_blacklist)) return false;
+		
+		if(preg_match('/^[\w\.\-]{0,32}$/', $username) == false) return false;
+		
 		if($restrict_names == true && preg_match('/^web\d+$/', $username) == false) return false;
 		
 		return true;
@@ -436,7 +440,11 @@
 	public function is_allowed_group($groupname, $restrict_names = false) {
 		global $app;
 		
-		if($groupname == 'root') return false;
+		$name_blacklist = array('root','ispconfig','vmail','getmail');
+		if(in_array($groupname,$name_blacklist)) return false;
+		
+		if(preg_match('/^[\w\.\-]{0,32}$/', $groupname) == false) return false;
+		
 		if($restrict_names == true && preg_match('/^client\d+$/', $groupname) == false) return false;
 		
 		return true;
diff --git a/interface/web/sites/form/ftp_user.tform.php b/interface/web/sites/form/ftp_user.tform.php
index 2b97832..f328f7f 100644
--- a/interface/web/sites/form/ftp_user.tform.php
+++ b/interface/web/sites/form/ftp_user.tform.php
@@ -187,7 +187,10 @@
 				'datatype'  => 'VARCHAR',
 				'formtype'  => 'TEXT',
 				'validators'    => array (  0 => array (    'type'  => 'NOTEMPTY',
-						'errmsg'=> 'directory_error_empty'),
+															'errmsg'=> 'directory_error_empty'),
+											1 => array ( 	'type' => 'REGEX',
+															'regex' => '/^\/[a-zA-Z0-9\ \.\-\_\/]{10,128}$/',
+															'errmsg'=> 'directory_error_regex'),
 				),
 				'default'   => '',
 				'value'     => '',
diff --git a/interface/web/sites/form/shell_user.tform.php b/interface/web/sites/form/shell_user.tform.php
index ab7cef1..d8df458 100644
--- a/interface/web/sites/form/shell_user.tform.php
+++ b/interface/web/sites/form/shell_user.tform.php
@@ -197,6 +197,12 @@
 			'shell' => array (
 				'datatype' => 'VARCHAR',
 				'formtype' => 'TEXT',
+				'validators' => array ( 0 => array ( 	'type' => 'NOTEMPTY',
+														'errmsg'=> 'shell_error_empty'),
+										1 => array ( 	'type' => 'REGEX',
+															'regex' => '/^\/[a-zA-Z0-9\/]{5,20}$/',
+															'errmsg'=> 'shell_error_regex'),
+				),
 				'default' => '/bin/bash',
 				'value'  => '',
 				'width'  => '30',
@@ -205,8 +211,11 @@
 			'dir' => array (
 				'datatype' => 'VARCHAR',
 				'formtype' => 'TEXT',
-				'validators' => array (  0 => array ( 'type' => 'NOTEMPTY',
-						'errmsg'=> 'directory_error_empty'),
+				'validators' => array ( 0 => array ( 	'type' => 'NOTEMPTY',
+														'errmsg'=> 'directory_error_empty'),
+										1 => array ( 	'type' => 'REGEX',
+															'regex' => '/^\/[a-zA-Z0-9\ \.\-\_\/]{10,128}$/',
+															'errmsg'=> 'directory_error_regex'),
 				),
 				'default' => '',
 				'value'  => '',
diff --git a/interface/web/sites/ftp_user_edit.php b/interface/web/sites/ftp_user_edit.php
index 0346201..edf47a3 100644
--- a/interface/web/sites/ftp_user_edit.php
+++ b/interface/web/sites/ftp_user_edit.php
@@ -138,6 +138,11 @@
 		$dir = $app->db->quote($web["document_root"]);
 		$uid = $app->db->quote($web["system_user"]);
 		$gid = $app->db->quote($web["system_group"]);
+		
+		// Check system user and group
+		if($app->functions->is_allowed_user($uid) == false || $app->functions->is_allowed_group($gid) == false) {
+			$app->error('Invalid system user or group');
+		}
 
 		// The FTP user shall be owned by the same group then the website
 		$sys_groupid = $app->functions->intval($web['sys_groupid']);
@@ -148,7 +153,15 @@
 
 	function onBeforeUpdate() {
 		global $app, $conf, $interfaceConf;
+		
 
+		// Check system user and group
+		if(isset($this->dataRecord['uid'])) {
+			if($app->functions->is_allowed_user(strtolower($this->dataRecord['uid']),true) == false || $app->functions->is_allowed_group(strtolower($this->dataRecord['gid']),true) == false) {
+				$app->tform->errorMessage .= $app->tform->lng('invalid_system_user_or_group_txt');
+			}
+		}
+		
 		/*
 		 * If the names should be restricted -> do it!
 		 */
diff --git a/interface/web/sites/lib/lang/en_ftp_user.lng b/interface/web/sites/lib/lang/en_ftp_user.lng
index ed5fe02..2c8e2a9 100644
--- a/interface/web/sites/lib/lang/en_ftp_user.lng
+++ b/interface/web/sites/lib/lang/en_ftp_user.lng
@@ -32,4 +32,6 @@
 $wb['repeat_password_txt'] = 'Repeat Password';
 $wb['password_mismatch_txt'] = 'The passwords do not match.';
 $wb['password_match_txt'] = 'The passwords do match.';
+$wb['invalid_system_user_or_group_txt'] = 'Invalid system user or group';
+$wb['directory_error_regex'] = 'Invalid directory';
 ?>
diff --git a/interface/web/sites/lib/lang/en_shell_user.lng b/interface/web/sites/lib/lang/en_shell_user.lng
index c15d1b5..2ae9b4e 100644
--- a/interface/web/sites/lib/lang/en_shell_user.lng
+++ b/interface/web/sites/lib/lang/en_shell_user.lng
@@ -28,4 +28,7 @@
 $wb['password_match_txt'] = 'The passwords do match.';
 $wb['username_must_not_exceed_32_chars_txt'] = 'The username must not exceed 32 characters.';
 $wb['username_not_allowed_txt'] = 'The username is not allowed.';
+$wb['invalid_system_user_or_group_txt'] = 'Invalid system user or group';
+$wb['directory_error_regex'] = 'Invalid directory';
+$wb['shell_error_regex'] = 'Invalid shell';
 ?>
diff --git a/interface/web/sites/shell_user_edit.php b/interface/web/sites/shell_user_edit.php
index 3c72a5f..9731889 100644
--- a/interface/web/sites/shell_user_edit.php
+++ b/interface/web/sites/shell_user_edit.php
@@ -135,6 +135,8 @@
 			}
 		}
 		unset($blacklist);
+		
+		if($app->functions->is_allowed_user(trim(strtolower($this->dataRecord['username']))) == false) $app->tform->errorMessage .= $app->tform->lng('username_not_allowed_txt');
 
 		/*
 		 * If the names should be restricted -> do it!
@@ -163,6 +165,11 @@
 		$dir = $app->db->quote($web["document_root"]);
 		$uid = $app->db->quote($web["system_user"]);
 		$gid = $app->db->quote($web["system_group"]);
+		
+		// Check system user and group
+		if($app->functions->is_allowed_user($uid) == false || $app->functions->is_allowed_group($gid) == false) {
+			$app->error($app->tform->lng('invalid_system_user_or_group_txt'));
+		}
 
 		// The FTP user shall be owned by the same group then the website
 		$sys_groupid = $app->functions->intval($web['sys_groupid']);
@@ -183,6 +190,13 @@
 			}
 		}
 		unset($blacklist);
+		
+		// Check system user and group
+		if(isset($this->dataRecord['puser'])) {
+			if($app->functions->is_allowed_user(strtolower($this->dataRecord['puser']),true) == false || $app->functions->is_allowed_group(strtolower($this->dataRecord['pgroup']),true) == false) {
+				$app->tform->errorMessage .= $app->tform->lng('invalid_system_user_or_group_txt');
+			}
+		}
 
 		/*
 		 * If the names should be restricted -> do it!
diff --git a/server/lib/classes/system.inc.php b/server/lib/classes/system.inc.php
index 049eb61..3001c64 100644
--- a/server/lib/classes/system.inc.php
+++ b/server/lib/classes/system.inc.php
@@ -1821,7 +1821,11 @@
 	public function is_allowed_user($username, $check_id = true, $restrict_names = false) {
 		global $app;
 		
-		if($username == 'root') return false;
+		$name_blacklist = array('root','ispconfig','vmail','getmail');
+		if(in_array($username,$name_blacklist)) return false;
+		
+		if(preg_match('/^[\w\.\-]{0,32}$/', $username) == false) return false;
+		
 		if($check_id && intval($this->getuid($username)) < $this->min_uid) return false;
 		
 		if($restrict_names == true && preg_match('/^web\d+$/', $username) == false) return false;
@@ -1832,7 +1836,11 @@
 	public function is_allowed_group($groupname, $restrict_names = false) {
 		global $app;
 		
-		if($groupname == 'root') return false;
+		$name_blacklist = array('root','ispconfig','vmail','getmail');
+		if(in_array($groupname,$name_blacklist)) return false;
+		
+		if(preg_match('/^[\w\.\-]{0,32}$/', $groupname) == false) return false;
+		
 		if(intval($this->getgid($groupname)) < $this->min_gid) return false;
 		
 		if($restrict_names == true && preg_match('/^client\d+$/', $groupname) == false) return false;

--
Gitblit v1.9.1