Skip to content

Commit 37be9ce

Browse files
authored
Security: Avoid relative path traversal to execute ppt2png and escape shell command used to execute PPT converter
1 parent 0ced3ed commit 37be9ce

File tree

2 files changed

+29
-9
lines changed

2 files changed

+29
-9
lines changed

Diff for: main/inc/lib/security.lib.php

+3-1
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,9 @@ public static function getPasswordRequirementsToString(array $evaluatedCondition
632632
*/
633633
public static function sanitizeExecParam(string $param): string
634634
{
635-
return preg_replace('/[`;&|]/', '', $param);
635+
$param = preg_replace('/[`;&|]/', '', $param);
636+
637+
return escapeshellarg($param);
636638
}
637639

638640
private static function generateSecTokenVariable(string $prefix = ''): string

Diff for: main/webservices/additional_webservices.php

+26-8
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,26 @@ function wsConvertPpt($pptData)
3030
}
3131
$fileData = $pptData['file_data'];
3232
// Clean filename to avoid hacks. Prevents "&" and ";" to be used in filename, notably
33-
$sanitizedFileName = Security::sanitizeExecParam($pptData['file_name']);
33+
34+
if (strpos($pptData['file_name'], '..') !== false) {
35+
return false;
36+
}
37+
38+
$sanitizedFileName = $pptData['file_name'];
3439
$dataInfo = pathinfo($sanitizedFileName);
3540
$fileName = basename($sanitizedFileName, '.'.$dataInfo['extension']);
3641
// Add additional cleaning of .php and .htaccess files
3742
$fullFileName = Security::filter_filename($sanitizedFileName);
38-
$size = Security::sanitizeExecParam($pptData['service_ppt2lp_size']);
43+
$size = $pptData['service_ppt2lp_size'];
3944
$w = '800';
4045
$h = '600';
4146
if (!empty($size)) {
4247
list($w, $h) = explode('x', $size);
4348
}
4449

50+
$w = (int) $w;
51+
$h = (int) $h;
52+
4553
$tempArchivePath = api_get_path(SYS_ARCHIVE_PATH);
4654
$tempPath = $tempArchivePath.'wsConvert/'.$fileName.'/';
4755
$tempPathNewFiles = $tempArchivePath.'wsConvert/'.$fileName.'-n/';
@@ -56,8 +64,12 @@ function wsConvertPpt($pptData)
5664
$file = base64_decode($fileData);
5765
file_put_contents($tempPath.$fullFileName, $file);
5866

59-
$cmd = pptConverterGetCommandBaseParams();
60-
$cmd .= ' -w '.$w.' -h '.$h.' -d oogie "'.$tempPath.$fullFileName.'" "'.$tempPathNewFiles.$fileName.'.html"';
67+
$cmd = pptConverterGetCommandBaseParams(
68+
$w,
69+
$h,
70+
$tempPath.$fullFileName,
71+
$tempPathNewFiles.$fileName.'.html'
72+
);
6173

6274
//$perms = api_get_permissions_for_new_files();
6375
chmod($tempPathNewFiles.$fileName, $perms);
@@ -137,21 +149,27 @@ function pptConverterDirectoriesCreate($tempPath, $tempPathNewFiles, $fileName,
137149
*
138150
* @return string $cmd
139151
*/
140-
function pptConverterGetCommandBaseParams()
152+
function pptConverterGetCommandBaseParams(int $w, int $h, string $inputPath, string $outputPath)
141153
{
154+
$cd = '';
155+
142156
if (IS_WINDOWS_OS) { // IS_WINDOWS_OS has been defined in main_api.lib.php
143157
$converterPath = str_replace('/', '\\', api_get_path(SYS_PATH).'main/inc/lib/ppt2png');
144158
$classPath = $converterPath.';'.$converterPath.'/jodconverter-2.2.2.jar;'.$converterPath.'/jodconverter-cli-2.2.2.jar';
145-
$cmd = 'java -Dfile.encoding=UTF-8 -cp "'.$classPath.'" DokeosConverter';
159+
$cmd = 'java -Dfile.encoding=UTF-8 -cp "'.$classPath.'"';
146160
} else {
147161
$converterPath = api_get_path(SYS_PATH).'main/inc/lib/ppt2png';
148162
$classPath = ' -Dfile.encoding=UTF-8 -cp .:jodconverter-2.2.2.jar:jodconverter-cli-2.2.2.jar';
149-
$cmd = 'cd '.$converterPath.' && java '.$classPath.' DokeosConverter';
163+
$cd = 'cd '.$converterPath.' && ';
164+
$cmd = 'java '.$classPath;
150165
}
151166

167+
$cmd .= ' DokeosConverter';
152168
$cmd .= ' -p '.api_get_setting('service_ppt2lp', 'port');
169+
$cmd .= ' -w '.$w.' -h '.$h;
170+
$cmd .= ' -d oogie '.Security::sanitizeExecParam($inputPath).' '.Security::sanitizeExecParam($outputPath);
153171

154-
return $cmd;
172+
return $cd.escapeshellcmd($cmd);
155173
}
156174

157175
$uri = api_get_path(WEB_CODE_PATH).'webservices/';

0 commit comments

Comments
 (0)