Fix vulnerability

This commit is contained in:
Jose Gonzalez 2021-09-03 13:30:15 +02:00
parent a2ef804cec
commit fa101db3b6
4 changed files with 58 additions and 73 deletions

View File

@ -219,34 +219,15 @@ if ($filemanager) {
$id_plugin = (int) get_parameter('id_plugin', 0); $id_plugin = (int) get_parameter('id_plugin', 0);
// Add custom directories here // Add custom directories here.
$fallback_directory = 'attachment/plugin'; $fallback_directory = 'attachment/plugin';
// Get directory.
$directory = (string) get_parameter('directory', $fallback_directory); $directory = (string) get_parameter('directory');
if (empty($directory) === true) {
$directory = $fallback_directory;
} else {
$directory = str_replace('\\', '/', $directory); $directory = str_replace('\\', '/', $directory);
$directory = filemanager_safe_directory($directory, $fallback_directory);
// A miminal security check to avoid directory traversal
if (preg_match('/\.\./', $directory)) {
$directory = $fallback_directory;
}
if (preg_match('/^\//', $directory)) {
$directory = $fallback_directory;
}
if (preg_match('/^manager/', $directory)) {
$directory = $fallback_directory;
}
$banned_directories['include'] = true;
$banned_directories['godmode'] = true;
$banned_directories['operation'] = true;
$banned_directories['reporting'] = true;
$banned_directories['general'] = true;
$banned_directories[ENTERPRISE_DIR] = true;
if (isset($banned_directories[$directory])) {
$directory = $fallback_directory;
} }
$real_directory = realpath($config['homedir'].'/'.$directory); $real_directory = realpath($config['homedir'].'/'.$directory);
@ -263,12 +244,12 @@ if ($filemanager) {
$default_real_directory = realpath($config['homedir'].'/'.$fallback_directory); $default_real_directory = realpath($config['homedir'].'/'.$fallback_directory);
if ($upload_file_or_zip) { if ($upload_file_or_zip === true) {
upload_file($upload_file_or_zip, $default_real_directory); upload_file($upload_file_or_zip, $default_real_directory, $real_directory);
} }
if ($create_text_file) { if ($create_text_file === true) {
create_text_file($default_real_directory); create_text_file($default_real_directory, $real_directory);
} }
filemanager_file_explorer( filemanager_file_explorer(

View File

@ -58,18 +58,6 @@ if (empty($directory) === true) {
$directory = filemanager_safe_directory($directory, $fallback_directory); $directory = filemanager_safe_directory($directory, $fallback_directory);
} }
// Banned directories.
$banned_directories['include'] = true;
$banned_directories['godmode'] = true;
$banned_directories['operation'] = true;
$banned_directories['reporting'] = true;
$banned_directories['general'] = true;
$banned_directories[ENTERPRISE_DIR] = true;
if (isset($banned_directories[$directory]) === true) {
$directory = $fallback_directory;
}
$real_directory = realpath($config['homedir'].'/'.$directory); $real_directory = realpath($config['homedir'].'/'.$directory);
echo '<h4>'.__('Index of %s', $directory).'</h4>'; echo '<h4>'.__('Index of %s', $directory).'</h4>';
@ -80,11 +68,11 @@ $create_text_file = (bool) get_parameter('create_text_file');
$default_real_directory = realpath($config['homedir'].'/'); $default_real_directory = realpath($config['homedir'].'/');
if ($upload_file_or_zip === true) { if ($upload_file_or_zip === true) {
upload_file($upload_file_or_zip, $default_real_directory); upload_file($upload_file_or_zip, $default_real_directory, $real_directory);
} }
if ($create_text_file === true) { if ($create_text_file === true) {
create_text_file($default_real_directory); create_text_file($default_real_directory, $real_directory);
} }
filemanager_file_explorer( filemanager_file_explorer(

View File

@ -128,15 +128,16 @@ require_once $config['homedir'].'/vendor/autoload.php';
* *
* @param boolean $upload_file_or_zip Upload file or zip. * @param boolean $upload_file_or_zip Upload file or zip.
* @param string $default_real_directory String with default directory. * @param string $default_real_directory String with default directory.
* @param string $destination_directory String with destination directory.
* *
* @return void * @return void
*/ */
function upload_file($upload_file_or_zip, $default_real_directory) function upload_file($upload_file_or_zip, $default_real_directory, $destination_directory)
{ {
global $config; global $config;
$config['filemanager'] = []; $config['filemanager'] = [];
$config['filemanager']['correct_upload_file'] = 0; $config['filemanager']['correct_upload_file'] = 0;
$config['filemanager']['message'] = null; $config['filemanager']['message'] = '';
check_login(); check_login();
@ -164,7 +165,7 @@ function upload_file($upload_file_or_zip, $default_real_directory)
if ($upload_file === true) { if ($upload_file === true) {
if (isset($_FILES['file']) === true && empty($_FILES['file']['name']) === false) { if (isset($_FILES['file']) === true && empty($_FILES['file']['name']) === false) {
$filename = $_FILES['file']['name']; $filename = $_FILES['file']['name'];
$real_directory = filemanager_safe_directory((string) get_parameter('real_directory')); $real_directory = filemanager_safe_directory($destination_directory);
$umask = io_safe_output((string) get_parameter('umask')); $umask = io_safe_output((string) get_parameter('umask'));
if (strpos($real_directory, $default_real_directory) !== 0) { if (strpos($real_directory, $default_real_directory) !== 0) {
@ -173,23 +174,34 @@ function upload_file($upload_file_or_zip, $default_real_directory)
// user is not trying to access an external path (avoid // user is not trying to access an external path (avoid
// execution of PHP files in directories that are not explicitly // execution of PHP files in directories that are not explicitly
// controlled by corresponding .htaccess). // controlled by corresponding .htaccess).
ui_print_error_message(__('Security error')); $config['filemanager']['message'] = ui_print_error_message(__('Security error'));
} else { } else {
// Copy file to directory and change name. // Copy file to directory and change name.
$nombre_archivo = $real_directory.'/'.$filename; $nombre_archivo = sprintf('%s/%s', $real_directory, $filename);
if (! @copy($_FILES['file']['tmp_name'], $nombre_archivo)) { try {
$config['filemanager']['message'] = ui_print_error_message(__('Upload error')); $result = copy($_FILES['file']['tmp_name'], $nombre_archivo);
} else { } catch (Exception $ex) {
if (empty($umask) === false) { $result = false;
chmod($nombre_archivo, $umask);
} }
$config['filemanager']['correct_upload_file'] = 1; if ($result === true) {
ui_print_success_message(__('Upload correct')); // If umask is provided, set.
if (empty($umask) === false) {
try {
chmod($nombre_archivo, $umask);
} catch (Exception $ex) {
$config['filemanager']['message'] = ui_print_error_message(__('Issue setting umask: %s', $ex->getMessage()));
}
}
// Upload performed properly.
$config['filemanager']['message'] .= ui_print_success_message(__('Upload correct'));
$config['filemanager']['correct_upload_file'] = 1;
// Delete temporal file. // Delete temporal file.
unlink($_FILES['file']['tmp_name']); unlink($_FILES['file']['tmp_name']);
} else {
$config['filemanager']['message'] = ui_print_error_message(__('Upload error'));
} }
} }
} }
@ -202,7 +214,7 @@ function upload_file($upload_file_or_zip, $default_real_directory)
) { ) {
$filename = $_FILES['file']['name']; $filename = $_FILES['file']['name'];
$filepath = $_FILES['file']['tmp_name']; $filepath = $_FILES['file']['tmp_name'];
$real_directory = filemanager_safe_directory((string) get_parameter('real_directory')); $real_directory = filemanager_safe_directory($destination_directory);
if (strpos($real_directory, $default_real_directory) !== 0) { if (strpos($real_directory, $default_real_directory) !== 0) {
// Perform security check to determine whether received upload // Perform security check to determine whether received upload
@ -213,10 +225,10 @@ function upload_file($upload_file_or_zip, $default_real_directory)
ui_print_error_message(__('Security error')); ui_print_error_message(__('Security error'));
} else { } else {
if (PandoraFMS\Tools\Files::unzip($filepath, $real_directory) === false) { if (PandoraFMS\Tools\Files::unzip($filepath, $real_directory) === false) {
ui_print_error_message(__('It was impossible to uncompress your file')); $config['filemanager']['message'] = ui_print_error_message(__('It was impossible to uncompress your file'));
} else { } else {
unlink($_FILES['file']['tmp_name']); unlink($_FILES['file']['tmp_name']);
ui_print_success_message(__('Upload correct')); $config['filemanager']['message'] = ui_print_success_message(__('Upload correct'));
$config['filemanager']['correct_upload_file'] = 1; $config['filemanager']['correct_upload_file'] = 1;
} }
} }
@ -234,7 +246,7 @@ if (isset($_SERVER['CONTENT_LENGTH']) === true) {
} }
function create_text_file($default_real_directory) function create_text_file($default_real_directory, $destination_directory)
{ {
global $config; global $config;
@ -253,7 +265,7 @@ function create_text_file($default_real_directory)
$filename = filemanager_safe_directory((string) get_parameter('name_file')); $filename = filemanager_safe_directory((string) get_parameter('name_file'));
if (empty($filename) === false) { if (empty($filename) === false) {
$real_directory = filemanager_safe_directory((string) get_parameter('real_directory')); $real_directory = filemanager_safe_directory($destination_directory);
$umask = (string) get_parameter('umask'); $umask = (string) get_parameter('umask');
if (strpos($real_directory, $default_real_directory) !== 0) { if (strpos($real_directory, $default_real_directory) !== 0) {
@ -980,6 +992,15 @@ function filemanager_safe_directory(
// Safe output. // Safe output.
$directory = io_safe_output($directory); $directory = io_safe_output($directory);
$forbiddenAttempting = false; $forbiddenAttempting = false;
// Banned directories.
$bannedDirectory = [
'include',
'godmode',
'operation',
'reporting',
'general',
ENTERPRISE_DIR,
];
if ((bool) preg_match('/(\.){2}/', $directory) !== false) { if ((bool) preg_match('/(\.){2}/', $directory) !== false) {
$directory = preg_replace('/(\.){2}/', '', (empty($safedDirectory) === true) ? $directory : $safedDirectory); $directory = preg_replace('/(\.){2}/', '', (empty($safedDirectory) === true) ? $directory : $safedDirectory);
@ -991,6 +1012,12 @@ function filemanager_safe_directory(
$forbiddenAttempting = true; $forbiddenAttempting = true;
} }
if (in_array($directory, $bannedDirectory) === true) {
// Setted images for default (usually in file manager).
$directory = (empty($safedDirectory) === false) ? $safedDirectory : 'images';
$forbiddenAttempting = true;
}
if ($forbiddenAttempting === true) { if ($forbiddenAttempting === true) {
db_pandora_audit('File manager', 'Attempting to use a forbidden file or directory name'); db_pandora_audit('File manager', 'Attempting to use a forbidden file or directory name');
} }

View File

@ -78,17 +78,6 @@ if (empty($directory) === true) {
$directory = filemanager_safe_directory($directory, $fallback_directory); $directory = filemanager_safe_directory($directory, $fallback_directory);
} }
$banned_directories['include'] = true;
$banned_directories['godmode'] = true;
$banned_directories['operation'] = true;
$banned_directories['reporting'] = true;
$banned_directories['general'] = true;
$banned_directories[ENTERPRISE_DIR] = true;
if (isset($banned_directories[$directory]) === true) {
$directory = $fallback_directory;
}
$real_directory = realpath($config['homedir'].'/'.$directory); $real_directory = realpath($config['homedir'].'/'.$directory);
ui_print_info_message(__('MIB files will be installed on the system. Please note that a MIB may depend on other MIB. To customize trap definitions use the SNMP trap editor.')); ui_print_info_message(__('MIB files will be installed on the system. Please note that a MIB may depend on other MIB. To customize trap definitions use the SNMP trap editor.'));
@ -99,11 +88,11 @@ $create_text_file = (bool) get_parameter('create_text_file');
$default_real_directory = realpath($config['homedir'].'/'.$fallback_directory); $default_real_directory = realpath($config['homedir'].'/'.$fallback_directory);
if ($upload_file_or_zip === true) { if ($upload_file_or_zip === true) {
upload_file($upload_file_or_zip, $default_real_directory); upload_file($upload_file_or_zip, $default_real_directory, $real_directory);
} }
if ($create_text_file === true) { if ($create_text_file === true) {
create_text_file($default_real_directory); create_text_file($default_real_directory, $real_directory);
} }
filemanager_file_explorer( filemanager_file_explorer(