diff --git a/interface/web/sites/ftp_user_edit.php b/interface/web/sites/ftp_user_edit.php index 337fe16d24d67734bf0f8ccebffad2e40e786f9f..f6d02887cd7aaddd0233e27b9b9a984d055ea624 100644 --- a/interface/web/sites/ftp_user_edit.php +++ b/interface/web/sites/ftp_user_edit.php @@ -106,6 +106,8 @@ class page_action extends tform_actions { if(isset($this->dataRecord['username']) && trim($this->dataRecord['username']) == '') $app->tform->errorMessage .= $app->tform->lng('username_error_empty').'
'; if(isset($this->dataRecord['username']) && empty($this->dataRecord['parent_domain_id'])) $app->tform->errorMessage .= $app->tform->lng('parent_domain_id_error_empty').'
'; + if(isset($this->dataRecord['dir']) && stristr($this->dataRecord['dir'],'..')) $app->tform->errorMessage .= $app->tform->lng('dir_dot_error').'
'; + if(isset($this->dataRecord['dir']) && stristr($this->dataRecord['dir'],'./')) $app->tform->errorMessage .= $app->tform->lng('dir_slashdot_error').'
'; parent::onSubmit(); } diff --git a/interface/web/sites/lib/lang/en_ftp_user.lng b/interface/web/sites/lib/lang/en_ftp_user.lng index 88c644ee740563bc36ab64264879b918c7dfe5f6..4598b03c692a42ffe84607049e77d745101b0ef9 100644 --- a/interface/web/sites/lib/lang/en_ftp_user.lng +++ b/interface/web/sites/lib/lang/en_ftp_user.lng @@ -26,4 +26,6 @@ $wb["directory_error_empty"] = 'Directory empty.'; $wb['directory_error_notinweb'] = 'Directory not inside of web root directory.'; $wb["parent_domain_id_error_empty"] = 'No website selected.'; $wb["quota_size_error_regex"] = 'Quota: enter a -1 for unlimited or a number > 0'; +$wb['dir_dot_error'] = 'No .. in path allowed.'; +$wb['dir_slashdot_error'] = 'No ./ in path allowed.'; ?> diff --git a/interface/web/sites/lib/lang/en_shell_user.lng b/interface/web/sites/lib/lang/en_shell_user.lng index e05fd258e403f60d06d0e6afc90ebb7b225f22a5..b703ad04bdfeb6eeed4af39da6fcdaee4d418a05 100644 --- a/interface/web/sites/lib/lang/en_shell_user.lng +++ b/interface/web/sites/lib/lang/en_shell_user.lng @@ -21,4 +21,6 @@ $wb["directory_error_empty"] = 'Directory empty.'; $wb["limit_shell_user_txt"] = 'The max number of shell users is reached.'; $wb["parent_domain_id_error_empty"] = 'No website selected.'; $wb["ssh_rsa_txt"] = 'SSH-RSA Public Key (for key-based logins)'; +$wb['dir_dot_error'] = 'No .. in path allowed.'; +$wb['dir_slashdot_error'] = 'No ./ in path allowed.'; ?> diff --git a/interface/web/sites/shell_user_edit.php b/interface/web/sites/shell_user_edit.php index bb93bf222212c6eddef4b7078d344650af63e7bf..e09d8dde960585ba3b5bee4c3ff79d559e0a926f 100644 --- a/interface/web/sites/shell_user_edit.php +++ b/interface/web/sites/shell_user_edit.php @@ -111,6 +111,8 @@ class page_action extends tform_actions { if(isset($this->dataRecord['username']) && trim($this->dataRecord['username']) == '') $app->tform->errorMessage .= $app->tform->lng('username_error_empty').'
'; if(isset($this->dataRecord['username']) && empty($this->dataRecord['parent_domain_id'])) $app->tform->errorMessage .= $app->tform->lng('parent_domain_id_error_empty').'
'; + if(isset($this->dataRecord['dir']) && stristr($this->dataRecord['dir'],'..')) $app->tform->errorMessage .= $app->tform->lng('dir_dot_error').'
'; + if(isset($this->dataRecord['dir']) && stristr($this->dataRecord['dir'],'./')) $app->tform->errorMessage .= $app->tform->lng('dir_slashdot_error').'
'; if(isset($this->dataRecord['ssh_rsa'])) $this->dataRecord['ssh_rsa'] = trim($this->dataRecord['ssh_rsa']); diff --git a/server/plugins-available/ftpuser_base_plugin.inc.php b/server/plugins-available/ftpuser_base_plugin.inc.php index 42edbb591c9e1f38c37ce77c9793c6d517403dc0..8cd2aa2dc1171bcee54d2e94dfe7090054d02cb4 100644 --- a/server/plugins-available/ftpuser_base_plugin.inc.php +++ b/server/plugins-available/ftpuser_base_plugin.inc.php @@ -74,6 +74,12 @@ class ftpuser_base_plugin { $web = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($data['new']['parent_domain_id'])); + //* Check if the resulting path is inside the docroot + if(substr(realpath($data['new']['dir']),0,strlen($web['document_root'])) != $web['document_root']) { + $app->log('User dir is outside of docroot.',LOGLEVEL_WARN); + return false; + } + exec('mkdir -p '.escapeshellcmd($data['new']['dir'])); exec('chown '.escapeshellcmd($web["system_user"]).':'.escapeshellcmd($web['system_group']).' '.$data['new']['dir']); @@ -90,6 +96,12 @@ class ftpuser_base_plugin { $web = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($data['new']['parent_domain_id'])); + //* Check if the resulting path is inside the docroot + if(substr(realpath($data['new']['dir']),0,strlen($web['document_root'])) != $web['document_root']) { + $app->log('User dir is outside of docroot.',LOGLEVEL_WARN); + return false; + } + exec('mkdir -p '.escapeshellcmd($data['new']['dir'])); exec('chown '.escapeshellcmd($web["system_user"]).':'.escapeshellcmd($web['system_group']).' '.$data['new']['dir']); diff --git a/server/plugins-available/shelluser_base_plugin.inc.php b/server/plugins-available/shelluser_base_plugin.inc.php index f411251b0b1b1a86479c5e88106eee695155bbb5..5c4186338195b0889c42e3fb6d72190f24e6e54d 100755 --- a/server/plugins-available/shelluser_base_plugin.inc.php +++ b/server/plugins-available/shelluser_base_plugin.inc.php @@ -72,6 +72,13 @@ class shelluser_base_plugin { $app->uses('system'); + //* Check if the resulting path is inside the docroot + $web = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($data['new']['parent_domain_id'])); + if(substr(realpath($data['new']['dir']),0,strlen($web['document_root'])) != $web['document_root']) { + $app->log('Directory of the shell user is outside of website docroot.',LOGLEVEL_WARN); + return false; + } + if($app->system->is_user($data['new']['puser'])) { // Get the UID of the parent user $uid = intval($app->system->getuid($data['new']['puser'])); @@ -121,6 +128,13 @@ class shelluser_base_plugin { $app->uses('system'); + //* Check if the resulting path is inside the docroot + $web = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($data['new']['parent_domain_id'])); + if(substr(realpath($data['new']['dir']),0,strlen($web['document_root'])) != $web['document_root']) { + $app->log('Directory of the shell user is outside of website docroot.',LOGLEVEL_WARN); + return false; + } + if($app->system->is_user($data['new']['puser'])) { // Get the UID of the parent user $uid = intval($app->system->getuid($data['new']['puser']));