/** * Upload a file with as much as security we can * * @param string $fileVarName, var name in which we can found the file in $_FILES * @param string $destinationDirFS, the destination dir in which we want the file to be moved * @return array of uploaded file meta datas */ function uploadFile($fileVarName = 'Filedata', $destinationDirFS = PATH_UPLOAD_FS) { //for security, clean all files older than 4h in both uploads directories $yesterday = time() - 14400; //4h try { foreach (new DirectoryIterator(PATH_UPLOAD_FS) as $file) { if ($file->isFile() && $file->getFilename() != ".htaccess" && $file->getMTime() < $yesterday) { @unlink($file->getPathname()); } } } catch (Exception $e) { } try { foreach (new DirectoryIterator(PATH_UPLOAD_VAULT_FS) as $file) { if ($file->isFile() && $file->getFilename() != ".htaccess" && $file->getMTime() < $yesterday) { @unlink($file->getPathname()); } } } catch (Exception $e) { } //init returned file datas $fileDatas = array('error' => 0, 'filename' => '', 'filepath' => '', 'filesize' => '', 'fileicon' => '', 'success' => false); // Check if the upload exists if (!isset($_FILES[$fileVarName]) || !is_uploaded_file($_FILES[$fileVarName]["tmp_name"]) || $_FILES[$fileVarName]["error"] != 0) { CMS_grandFather::raiseError('Uploaded file has an error : ' . print_r($_FILES, true)); $fileDatas['error'] = CMS_file::UPLOAD_UPLOAD_FAILED; $view->setContent($fileDatas); $view->show(); } //move uploaded file to upload vault (and rename it with a clean name if needed) $originalFilename = io::sanitizeAsciiString($_FILES[$fileVarName]["name"]); if (io::strlen($originalFilename) > 250) { $originalFilename = sensitiveIO::ellipsis($originalFilename, 250, '-'); } //remove multiple extensions to avoid double extension threat (cf. http://www.acunetix.com/websitesecurity/upload-forms-threat.htm) if (substr_count('.', $originalFilename) > 1) { $parts = pathinfo($originalFilename); $originalFilename = str_replace('.', '-', $parts['filename']) . '.' . $parts['extension']; } $count = 2; $filename = $originalFilename; while (file_exists(PATH_UPLOAD_VAULT_FS . '/' . $filename) || file_exists($destinationDirFS . '/' . $filename)) { $pathinfo = pathinfo($originalFilename); $filename = $pathinfo['filename'] . '-' . $count++ . '.' . $pathinfo['extension']; } if (!@move_uploaded_file($_FILES[$fileVarName]["tmp_name"], PATH_UPLOAD_VAULT_FS . '/' . $filename)) { CMS_grandFather::raiseError('Can\'t move uploaded file to : ' . PATH_UPLOAD_VAULT_FS . '/' . $filename); $fileDatas['error'] = CMS_file::UPLOAD_FILE_VALIDATION_FAILED; return $fileDatas; } $file = new CMS_file(PATH_UPLOAD_VAULT_FS . '/' . $filename); $file->chmod(FILES_CHMOD); //check uploaded file if (!$file->checkUploadedFile()) { $file->delete(); $fileDatas['error'] = CMS_file::UPLOAD_SECURITY_ERROR; return $fileDatas; } //move file to final directory if (!CMS_file::moveTo(PATH_UPLOAD_VAULT_FS . '/' . $filename, $destinationDirFS . '/' . $filename)) { $fileDatas['error'] = CMS_file::UPLOAD_FILE_VALIDATION_FAILED; return $fileDatas; } $file = new CMS_file($destinationDirFS . '/' . $filename); $file->chmod(FILES_CHMOD); //return file datas $fileDatas = array('error' => 0, 'filename' => $file->getName(false), 'filepath' => $file->getFilePath(CMS_file::WEBROOT), 'filesize' => $file->getFileSize(), 'fileicon' => $file->getFileIcon(CMS_file::WEBROOT), 'extension' => $file->getExtension(), 'success' => true); return $fileDatas; }