Skip to content

Commit e2a6024

Browse files
author
Marius Burkard
committed
Implement a more secure way to use exec, system and shell_exec, fixes #5355
1 parent 2b60a7a commit e2a6024

29 files changed

+574
-752
lines changed

interface/lib/classes/system.inc.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ public function last_exec_retcode() {
6565

6666
public function exec_safe($cmd) {
6767
$arg_count = func_num_args();
68+
if($arg_count != substr_count($cmd, '?') + 1) {
69+
trigger_error('Placeholder count not matching argument list.', E_USER_WARNING);
70+
return false;
71+
}
6872
if($arg_count > 1) {
6973
$args = func_get_args();
7074

server/lib/classes/aps_installer.inc.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,6 @@ private function doInstallation($task, $sxe)
544544
chmod($this->local_installpath.'install_scripts/'.$cfgscript, 0755);
545545

546546
// Change to the install folder (import for the exec() below!)
547-
//exec('chown -R '.$this->file_owner_user.':'.$this->file_owner_group.' '.escapeshellarg($this->local_installpath));
548547
chdir($this->local_installpath.'install_scripts/');
549548

550549
// Set the enviroment variables

server/lib/classes/cron.d/150-webalizer.inc.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,9 @@ function setConfigVar( $filename, $varName, $varValue, $append = 0 ) {
9494
$log_folder .= '/' . $subdomain_host;
9595
unset($tmp);
9696
}
97-
$logfile = escapeshellcmd($rec['document_root'].'/' . $log_folder . '/'.$yesterday.'-access.log');
97+
$logfile = $rec['document_root'].'/' . $log_folder . '/'.$yesterday.'-access.log';
9898
if(!@is_file($logfile)) {
99-
$logfile = escapeshellcmd($rec['document_root'].'/' . $log_folder . '/'.$yesterday.'-access.log.gz');
99+
$logfile = $rec['document_root'].'/' . $log_folder . '/'.$yesterday.'-access.log.gz';
100100
if(!@is_file($logfile)) {
101101
continue;
102102
}

server/lib/classes/cron.d/200-logfiles.inc.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ public function onRunJob() {
147147
}
148148

149149
// rotate and compress the error.log
150-
$error_logfile = escapeshellcmd($rec['document_root'].'/' . $log_folder . '/error.log');
150+
$error_logfile = $rec['document_root'].'/' . $log_folder . '/error.log';
151151
// rename older files (move up by one)
152152
$num = $log_retention;
153153
while($num >= 1) {
@@ -187,7 +187,7 @@ public function onRunJob() {
187187
$ispconfig_logfiles = array('ispconfig.log', 'cron.log', 'auth.log');
188188
foreach($ispconfig_logfiles as $ispconfig_logfile) {
189189
$num = $max_syslog;
190-
$ispconfig_logfile = escapeshellcmd($conf['ispconfig_log_dir'].'/'.$ispconfig_logfile);
190+
$ispconfig_logfile = $conf['ispconfig_log_dir'].'/'.$ispconfig_logfile;
191191
// rename older files (move up by one)
192192
while($num >= 1) {
193193
if(is_file($ispconfig_logfile . '.' . $num . '.gz')) rename($ispconfig_logfile . '.' . $num . '.gz', $ispconfig_logfile . '.' . ($num + 1) . '.gz');

server/lib/classes/cron.d/500-backup_mail.inc.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,9 @@ public function onRunJob() {
6969
$records = $app->db->queryAllRecords("SELECT * FROM mail_user WHERE server_id = ? AND maildir != ''", intval($conf['server_id']));
7070
if(is_array($records) && $run_backups) {
7171
if(!is_dir($backup_dir)) {
72-
mkdir(escapeshellcmd($backup_dir), $backup_dir_permissions, true);
72+
mkdir($backup_dir, $backup_dir_permissions, true);
7373
} else {
74-
chmod(escapeshellcmd($backup_dir), $backup_dir_permissions);
74+
chmod($backup_dir, $backup_dir_permissions);
7575
}
7676
system('which pigz > /dev/null', $ret);
7777
if($ret === 0) {
@@ -122,7 +122,7 @@ public function onRunJob() {
122122
if ($rec['maildir_format'] == 'mdbox') {
123123
if (empty($this->tmp_backup_dir)) $this->tmp_backup_dir = $rec['maildir'];
124124
// Create temporary backup-mailbox
125-
exec("su -c ?", 'dsync backup -u "'.$rec["email"].'" mdbox:' . $this->tmp_backup_dir . '/backup');
125+
$app->system->exec_safe("su -c ?", 'dsync backup -u "'.$rec["email"].'" mdbox:' . $this->tmp_backup_dir . '/backup');
126126

127127
if($backup_mode == 'userzip') {
128128
$mail_backup_file.='.zip';

server/lib/classes/system.inc.php

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1601,22 +1601,20 @@ function maildirmake($maildir_path, $user = '', $subfolder = '', $group = '') {
16011601
$mail_config = $app->getconf->get_server_config($conf["server_id"], 'mail');
16021602

16031603
if($subfolder != '') {
1604-
$dir = escapeshellcmd($maildir_path.'/.'.$subfolder);
1604+
$dir = $maildir_path.'/.'.$subfolder;
16051605
} else {
1606-
$dir = escapeshellcmd($maildir_path);
1606+
$dir = $maildir_path;
16071607
}
16081608

16091609
if(!is_dir($dir)) mkdir($dir, 0700, true);
16101610

16111611
if($user != '' && $user != 'root' && $this->is_user($user)) {
1612-
$user = escapeshellcmd($user);
16131612
if(is_dir($dir)) $this->chown($dir, $user);
16141613

16151614
$chown_mdsub = true;
16161615
}
16171616

16181617
if($group != '' && $group != 'root' && $this->is_group($group)) {
1619-
$group = escapeshellcmd($group);
16201618
if(is_dir($dir)) $this->chgrp($dir, $group);
16211619

16221620
$chgrp_mdsub = true;
@@ -1638,7 +1636,7 @@ function maildirmake($maildir_path, $user = '', $subfolder = '', $group = '') {
16381636
// Courier
16391637
if($mail_config['pop3_imap_daemon'] == 'courier') {
16401638
if(!is_file($maildir_path.'/courierimapsubscribed')) {
1641-
$tmp_file = escapeshellcmd($maildir_path.'/courierimapsubscribed');
1639+
$tmp_file = $maildir_path.'/courierimapsubscribed';
16421640
touch($tmp_file);
16431641
chmod($tmp_file, 0744);
16441642
chown($tmp_file, 'vmail');
@@ -1650,7 +1648,7 @@ function maildirmake($maildir_path, $user = '', $subfolder = '', $group = '') {
16501648
// Dovecot
16511649
if($mail_config['pop3_imap_daemon'] == 'dovecot') {
16521650
if(!is_file($maildir_path.'/subscriptions')) {
1653-
$tmp_file = escapeshellcmd($maildir_path.'/subscriptions');
1651+
$tmp_file = $maildir_path.'/subscriptions';
16541652
touch($tmp_file);
16551653
chmod($tmp_file, 0744);
16561654
chown($tmp_file, 'vmail');
@@ -2059,6 +2057,10 @@ public function last_exec_retcode() {
20592057

20602058
public function exec_safe($cmd) {
20612059
$arg_count = func_num_args();
2060+
if($arg_count != substr_count($cmd, '?') + 1) {
2061+
trigger_error('Placeholder count not matching argument list.', E_USER_WARNING);
2062+
return false;
2063+
}
20622064
if($arg_count > 1) {
20632065
$args = func_get_args();
20642066

server/mods-available/remoteaction_core_module.inc.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ private function _execActions() {
150150
$parts = explode(':', $action['action_param']);
151151
$veid = intval($parts[0]);
152152
$template_cache_dir = '/vz/template/cache/';
153-
$template_name = escapeshellcmd($parts[1]);
153+
$template_name = $parts[1];
154154
if($veid > 0 && $template_name != '' && is_dir($template_cache_dir)) {
155155
$command = "vzdump --suspend --compress --stdexcludes --dumpdir ? ?";
156156
$app->system->exec_safe($command, $template_cache_dir, $veid);

0 commit comments

Comments
 (0)