Fix #yogosha19665

This commit is contained in:
Laurent Destailleur 2023-12-21 11:43:30 +01:00
parent 1838bc0031
commit fbf91cc211
4 changed files with 33 additions and 30 deletions

View File

@ -18,7 +18,7 @@
/**
* \file htdocs/core/ajax/fileupload.php
* \brief File to return Ajax response on file upload
* \brief File to return Ajax response on common file upload. For large files, see flowjs-server.php
*/
if (!defined('NOREQUIREMENU')) {
@ -36,7 +36,7 @@ if (!defined('NOREQUIRESOC')) {
// Load Dolibarr environment
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/fileupload.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/fileupload.class.php'; // Class to upload common files
require_once DOL_DOCUMENT_ROOT.'/core/class/genericobject.class.php';
$id = GETPOST('fk_element', 'int');

View File

@ -18,7 +18,7 @@
/**
* \file htdocs/core/class/fileupload.class.php
* \brief File to return Ajax response on file upload
* \brief File to return Ajax response on common file upload. For large files, see flowjs-server.php
*/
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
@ -44,7 +44,7 @@ class FileUpload
*/
public function __construct($options = null, $fk_element = null, $element = null)
{
global $db, $conf;
global $db;
global $hookmanager;
$hookmanager->initHooks(array('fileupload'));
@ -56,8 +56,8 @@ class FileUpload
$this->element = $element;
$pathname = str_replace('/class', '', $element_prop['classpath']);
$filename = $element_prop['classfile'];
$dir_output = $element_prop['dir_output'];
$filename = dol_sanitizeFileName($element_prop['classfile']);
$dir_output = dol_sanitizePathName($element_prop['dir_output']);
//print 'fileupload.class.php: element='.$element.' pathname='.$pathname.' filename='.$filename.' dir_output='.$dir_output."\n";
@ -131,7 +131,7 @@ class FileUpload
*/
'thumbnail' => array(
'upload_dir' => $dir_output.'/'.$object_ref.'/thumbs/',
'upload_url' => DOL_URL_ROOT.'/document.php?modulepart='.urlencode($element).'&attachment=1&file=/'.$object_ref.'/thumbs/',
'upload_url' => DOL_URL_ROOT.'/document.php?modulepart='.urlencode($element).'&attachment=1&file='.urlencode('/'.$object_ref.'/thumbs/'),
'max_width' => 80,
'max_height' => 80
)
@ -211,20 +211,20 @@ class FileUpload
*/
protected function getFileObject($file_name)
{
$file_path = $this->options['upload_dir'].$file_name;
if (is_file($file_path) && $file_name[0] !== '.') {
$file_path = $this->options['upload_dir'].dol_sanitizeFileName($file_name);
if (dol_is_file($file_path) && $file_name[0] !== '.') {
$file = new stdClass();
$file->name = $file_name;
$file->mime = dol_mimetype($file_name, '', 2);
$file->size = filesize($file_path);
$file->url = $this->options['upload_url'].rawurlencode($file->name);
$file->url = $this->options['upload_url'].urlencode($file->name);
foreach ($this->options['image_versions'] as $version => $options) {
if (is_file($options['upload_dir'].$file_name)) {
if (dol_is_file($options['upload_dir'].$file_name)) {
$tmp = explode('.', $file->name);
// We save the path of mini file into file->... (seems not used)
$keyforfile = $version.'_url';
$file->$keyforfile = $options['upload_url'].rawurlencode($tmp[0].'_mini.'.$tmp[1]);
$file->$keyforfile = $options['upload_url'].urlencode($tmp[0].'_mini.'.$tmp[1]);
}
}
$this->setFileDeleteUrl($file);
@ -280,7 +280,7 @@ class FileUpload
}
/**
* Enter description here ...
* Make validation on an uploaded file
*
* @param string $uploaded_file Uploade file
* @param object $file File
@ -303,7 +303,7 @@ class FileUpload
return false;
}
if ($uploaded_file && is_uploaded_file($uploaded_file)) {
$file_size = filesize($uploaded_file);
$file_size = dol_filesize($uploaded_file);
} else {
$file_size = $_SERVER['CONTENT_LENGTH'];
}
@ -379,15 +379,14 @@ class FileUpload
{
// Remove path information and dots around the filename, to prevent uploading
// into different directories or replacing hidden system files.
// Also remove control characters and spaces (\x00..\x20) around the filename:
$file_name = trim(basename(stripslashes($name)), ".\x00..\x20");
$file_name = basename(dol_sanitizeFileName($name));
// Add missing file extension for known image types:
$matches = array();
if (strpos($file_name, '.') === false && preg_match('/^image\/(gif|jpe?g|png)/', $type, $matches)) {
$file_name .= '.'.$matches[1];
}
if ($this->options['discard_aborted_uploads']) {
while (is_file($this->options['upload_dir'].$file_name)) {
while (dol_is_file($this->options['upload_dir'].$file_name)) {
$file_name = $this->upcountName($file_name);
}
}
@ -414,12 +413,16 @@ class FileUpload
$file->size = intval($size);
$file->type = $type;
// Sanitize to avoid stream execution when calling file_size(). Not that this is a second security because
// most streams are already disabled by stream_wrapper_unregister() in filefunc.inc.php
$uploaded_file = preg_replace('/\s*(http|ftp)s?:/i', '', $uploaded_file);
$validate = $this->validate($uploaded_file, $file, $error, $index);
if ($validate) {
if (dol_mkdir($this->options['upload_dir']) >= 0) {
$file_path = $this->options['upload_dir'].$file->name;
$append_file = !$this->options['discard_aborted_uploads'] && is_file($file_path) && $file->size > filesize($file_path);
$file_path = dol_sanitizePathName($this->options['upload_dir']).dol_sanitizeFileName($file->name);
$append_file = !$this->options['discard_aborted_uploads'] && dol_is_file($file_path) && $file->size > dol_filesize($file_path);
clearstatcache();
@ -434,16 +437,16 @@ class FileUpload
// Non-multipart uploads (PUT method support)
file_put_contents($file_path, fopen('php://input', 'r'), $append_file ? FILE_APPEND : 0);
}
$file_size = filesize($file_path);
$file_size = dol_filesize($file_path);
if ($file_size === $file->size) {
$file->url = $this->options['upload_url'].rawurlencode($file->name);
$file->url = $this->options['upload_url'].urlencode($file->name);
foreach ($this->options['image_versions'] as $version => $options) {
if ($this->createScaledImage($file->name, $options)) { // Creation of thumbs mini and small is ok
$tmp = explode('.', $file->name);
// We save the path of mini file into file->... (seems not used)
$keyforfile = $version.'_url';
$file->$keyforfile = $options['upload_url'].rawurlencode($tmp[0].'_mini.'.$tmp[1]);
$file->$keyforfile = $options['upload_url'].urlencode($tmp[0].'_mini.'.$tmp[1]);
}
}
} elseif ($this->options['discard_aborted_uploads']) {
@ -537,7 +540,7 @@ class FileUpload
/* disabled. Param redirect seems not used
$redirect = isset($_REQUEST['redirect']) ? stripslashes($_REQUEST['redirect']) : null;
if ($redirect) {
header('Location: '.sprintf($redirect, rawurlencode($json)));
header('Location: '.sprintf($redirect, urlencode($json)));
return;
}
*/
@ -559,14 +562,13 @@ class FileUpload
*/
public function delete()
{
$file_name = isset($_REQUEST['file']) ?
basename(stripslashes($_REQUEST['file'])) : null;
$file_path = $this->options['upload_dir'].$file_name;
$success = is_file($file_path) && $file_name[0] !== '.' && unlink($file_path);
$file_name = GETPOST('file') ? basename(GETPOST('file')) : null;
$file_path = $this->options['upload_dir'].dol_sanitizeFileName($file_name);
$success = dol_is_file($file_path) && $file_name[0] !== '.' && unlink($file_path);
if ($success) {
foreach ($this->options['image_versions'] as $version => $options) {
$file = $options['upload_dir'].$file_name;
if (is_file($file)) {
if (dol_is_file($file)) {
unlink($file);
}
}

View File

@ -81,6 +81,7 @@ $result = @include_once $conffile; // Keep @ because with some error reporting t
// Disable some not used PHP stream
$listofwrappers = stream_get_wrappers();
// We need '.phar' for geoip2. TODO Replace phar in geoip with exploded files so we can disable phar by default.
// phar stream does not auto unserialize content (possible code execution) since PHP 8.1
$arrayofstreamtodisable = array('compress.zlib', 'compress.bzip2', 'ftp', 'ftps', 'glob', 'data', 'expect', 'ogg', 'rar', 'zip', 'zlib');
if (!empty($dolibarr_main_stream_to_disable) && is_array($dolibarr_main_stream_to_disable)) {
$arrayofstreamtodisable = $dolibarr_main_stream_to_disable;

View File

@ -111,8 +111,8 @@ if ($action == 'uploadfile') {
$nbfile = count($_FILES['userfile']['name']);
for ($i = 0; $i < $nbfile; $i++) {
$newsection = $newsectioniso;
$fileupload = $_FILES['userfile']['name'][$i];
$fileuploadpath = $_FILES['userfile']['tmp_name'][$i];
$fileupload = dol_sanitizeFileName($_FILES['userfile']['name'][$i]);
$fileuploadpath = dol_sanitizePathName($_FILES['userfile']['tmp_name'][$i]);
$result = dol_ftp_put($conn_id, $fileupload, $fileuploadpath, $newsection);
if ($result) {