Example #1
0
 public function HandleUpload($uploadDirectory)
 {
     // Security issue: when upload is disabled, stop here
     if (!(bool) $this->Params->get("uploaddisplay", 0)) {
         return array('error' => " [upload disabled]");
     }
     if (!is_writable($uploadDirectory)) {
         return array('error' => JFactory::getLanguage()->_($GLOBALS["COM_NAME"] . '_ERR_DIR_NOT_WRITABLE'));
     }
     // Check file size
     $size = $this->get_file_size();
     if ($size == 0) {
         return array('error' => JFactory::getLanguage()->_($GLOBALS["COM_NAME"] . '_ERR_FILE_EMPTY'));
     }
     // uploadmax_file_size defaults to 0 to prevent hack attempts
     $max = $this->Params->get("uploadmax_file_size", 0) * KB;
     // and < max limit
     if ($size > $max) {
         return array('error' => JFactory::getLanguage()->_($GLOBALS["COM_NAME"] . '_ERR_FILE_TOO_LARGE'));
     }
     $realname = $this->get_file_name();
     // Keep the client name untouched, and start working on a server side name
     $filename = JFilterInput::getInstance()->clean($realname, "cmd");
     // Forbid Directory Traversal by removing residual directory
     $filename = basename($filename);
     // Forbid initial and final dots
     $realname = trim($this->get_file_name(), '.');
     // Block scripts based on their extension
     $forbidden_extensions = '/ph(p[345st]?|t|tml|ar)/i';
     // php|php3|php4|php5|phps|phpt|pht|phtml|phar
     if (preg_match($forbidden_extensions, $filename)) {
         $this->Log->Write("Blocked a file upload attempt [forbidden extension]: " . $filename);
         // dangerous file extension
         return array('error' => JFactory::getLanguage()->_($GLOBALS["COM_NAME"] . '_ERR_MIME') . " [forbidden extension]");
     }
     // Assign a random unique id to the file name
     $filename = uniqid() . "-" . $filename;
     $full_filename = $uploadDirectory . $filename;
     if (!$this->save_file($full_filename)) {
         return array('error' => JFactory::getLanguage()->_($GLOBALS["COM_NAME"] . '_ERR_SAVE_FILE'));
     }
     $mimetype = new FMimeType();
     if (!$mimetype->Check($full_filename, $this->Params)) {
         // Delete the file uploaded
         unlink($full_filename);
         return array('error' => JFactory::getLanguage()->_($GLOBALS["COM_NAME"] . '_ERR_MIME') . " [" . $mimetype->Mimetype . "]");
     }
     // Read the current file list from the session
     $filelist = $this->session->get("filelist", array(), $this->namespace);
     // Block further uploads once exceeded the max limit
     if (count($filelist) >= $this->Params->get("upload_max_files", 10)) {
         return array("error" => JText::_("COM_FOXCONTACT_ERR_MAX_UPLOAD_FILES_EXCEEDED"));
     }
     // Block scripts based on their content. To avoid memory limitations which may vary based on the server configuration, analyzes the file in chunks of a reasonable length.
     $chunk_size = 1048576;
     // 1Mb
     $back_step = -6;
     // Given by strlen('<script') - 1
     // Open the file
     $handle = fopen($full_filename, "rb");
     do {
         // Read a chunk
         $content = fread($handle, $chunk_size);
         // Take back the file pointer in case we are ended just in the middle of the string we have to find
         fseek($handle, $back_step, SEEK_CUR);
         // search for the string
         if (strpos($content, '<?php') !== false || strpos($content, '<script') !== false) {
             // contains php directive
             fclose($handle);
             unlink($full_filename);
             $this->Log->Write("Blocked a file upload attempt [forbidden content]: " . $filename);
             return array('error' => JFactory::getLanguage()->_($GLOBALS["COM_NAME"] . '_ERR_MIME') . " [forbidden content]");
         }
         // If we have read exactly it's highly probable that we have not reached the end of file
     } while (strlen($content) == $chunk_size);
     // Close the file
     fclose($handle);
     // Append this file to the file list
     $filelist[] = array("filename" => $filename, "realname" => $realname, "size" => $size);
     // Save the new list to the session
     $this->session->set("filelist", $filelist, $this->namespace);
     // move the internal pointer to the end of the array
     end($filelist);
     // fetches the key of the last element
     $last = key($filelist);
     $this->Log->Write("File " . $filename . " uploaded succesful.");
     return array("success" => true, "index" => $last);
 }
Example #2
0
 protected function DoUpload()
 {
     //Retrieve file details from uploaded file, sent from upload form
     $file = JRequest::getVar('foxstdupload', NULL, 'files', 'array');
     // $file is null when a browser with javascipt didn't send $_FILES at all
     // $file['error'] is UPLOAD_ERR_NO_FILE when a browser without javascipt sent $_FILES empty
     if (!$this->Submitted || !$file || $file['error'] == UPLOAD_ERR_NO_FILE) {
         return true;
     }
     $upload_directory = JPATH_SITE . "/components/" . $GLOBALS["com_name"] . "/uploads/";
     if (!is_writable($upload_directory)) {
         $this->MessageBoard->Add(JText::_($GLOBALS["COM_NAME"] . '_ERR_DIR_NOT_WRITABLE'), FoxMessageBoard::error);
         return false;
     }
     // Check for http $_FILES upload errors
     if ($file['error']) {
         // case 1 UPLOAD_ERR_INI_SIZE: 'The uploaded file exceeds the upload_max_filesize directive in php.ini';
         // case 2 UPLOAD_ERR_FORM_SIZE: 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form';
         // case 3 UPLOAD_ERR_PARTIAL: 'The uploaded file was only partially uploaded';
         // case 4 UPLOAD_ERR_NO_FILE: 'No file was uploaded';
         // case 6 UPLOAD_ERR_NO_TMP_DIR: 'Missing a temporary folder';
         // case 7 UPLOAD_ERR_CANT_WRITE: 'Failed to write file to disk';
         // case 8 UPLOAD_ERR_EXTENSION: 'File upload stopped by extension';
         $this->MessageBoard->Add(JText::sprintf($GLOBALS["COM_NAME"] . '_ERR_UPLOAD', $file['error']), FoxMessageBoard::error);
         return false;
     }
     // Check file size
     $size = $file['size'];
     if ($size == 0) {
         $this->MessageBoard->Add(JText::_($GLOBALS["COM_NAME"] . '_ERR_FILE_EMPTY'), FoxMessageBoard::error);
         return false;
     }
     $max_filesize = intval($this->Params->get("uploadmax_file_size", "0")) * KB;
     if ($size > $max_filesize) {
         $this->MessageBoard->Add(JText::_($GLOBALS["COM_NAME"] . '_ERR_FILE_TOO_LARGE'), FoxMessageBoard::error);
         return false;
     }
     $mimetype = new FMimeType();
     if (!$mimetype->Check($file['tmp_name'], $this->Params)) {
         // Noo need to delete the file uploaded
         //unlink($file['tmp_name']);
         $this->MessageBoard->Add(JText::_($GLOBALS["COM_NAME"] . '_ERR_MIME') . " [" . $mimetype->Mimetype . "]", FoxMessageBoard::error);
         return false;
     }
     //Import filesystem libraries. Perhaps not necessary, but does not hurt
     jimport('joomla.filesystem.file');
     //Clean up filename to get rid of strange characters like spaces and others
     $filename = JFile::makeSafe($file['name']);
     // Assign a random unique id to the file name, to avoid that lamers can force the server to execute their uploaded shit
     $filename = uniqid() . "-" . $filename;
     $dest = $upload_directory . $filename;
     // Todo: This attempt doesn't intercept the exception
     /*
     try
     {
     JFile::upload($file['tmp_name'], $dest);
     }
     catch (Exception $e)
     {
     //$e->getMessage()
     return false;
     }
     */
     if (!JFile::upload($file['tmp_name'], $dest)) {
         return false;
     }
     // Upload successful. Add an element to the uploads list
     $jsession =& JFactory::getSession();
     $fsession = new FSession($jsession->getId(), $this->Application->cid, $this->Application->mid);
     // session_id, cid, mid
     // Store the answer in the session
     $data = $fsession->Load('filelist');
     // Read the list from the session
     if ($data) {
         $filelist = explode("|", $data);
     } else {
         $filelist = array();
     }
     $filelist[] = $filename;
     // Append this file to the list
     $data = implode("|", $filelist);
     $fsession->Save($data, "filelist");
     return true;
 }
Example #3
0
 public function HandleUpload($uploadDirectory)
 {
     $this->DebugLog->Write("HandleUpload() started");
     if (!is_writable($uploadDirectory)) {
         $this->DebugLog->Write("Directory " . $uploadDirectory . " is not writable");
         return array('error' => JFactory::getLanguage()->_($GLOBALS["COM_NAME"] . '_ERR_DIR_NOT_WRITABLE'));
     }
     $this->DebugLog->Write("Directory " . $uploadDirectory . " is ok");
     // Check file size
     $size = $this->get_file_size();
     if ($size == 0) {
         $this->DebugLog->Write("File size is 0");
         return array('error' => JFactory::getLanguage()->_($GLOBALS["COM_NAME"] . '_ERR_FILE_EMPTY'));
     }
     $this->DebugLog->Write("File size is > 0");
     // uploadmax_file_size defaults to 0 to prevent hack attempts
     $max = $this->Params->get("uploadmax_file_size", 0) * KB;
     // and < max limit
     if ($size > $max) {
         $this->DebugLog->Write("File size too large ({$size} > {$max})");
         return array('error' => JFactory::getLanguage()->_($GLOBALS["COM_NAME"] . '_ERR_FILE_TOO_LARGE'));
     }
     $this->DebugLog->Write("File size ({$size} / {$max}) is ok");
     // Clean file name
     $filename = preg_replace("/[^\\w\\.-_]/", "_", $this->get_file_name());
     // Assign a random unique id to the file name, to avoid that lamers can force the server to execute their uploaded shit
     $filename = uniqid() . "-" . $filename;
     $full_filename = $uploadDirectory . $filename;
     if (!$this->save_file($full_filename)) {
         $this->DebugLog->Write("Error saving file");
         return array('error' => JFactory::getLanguage()->_($GLOBALS["COM_NAME"] . '_ERR_SAVE_FILE'));
     }
     $this->DebugLog->Write("File saved");
     $mimetype = new FMimeType();
     if (!$mimetype->Check($full_filename, $this->Params)) {
         // Delete the file uploaded
         unlink($full_filename);
         $this->DebugLog->Write("File type [" . $mimetype->Mimetype . "] is not allowed. Allowed types are:" . PHP_EOL . print_r($mimetype->Allowed, true));
         return array('error' => JFactory::getLanguage()->_($GLOBALS["COM_NAME"] . '_ERR_MIME') . " [" . $mimetype->Mimetype . "]");
     }
     $this->DebugLog->Write("File type [" . $mimetype->Mimetype . "] is allowed");
     $cid = JFactory::getApplication()->input->get("cid", NULL);
     $mid = JFactory::getApplication()->input->get("mid", NULL);
     $owner = JFactory::getApplication()->input->get("owner", NULL);
     $id = JFactory::getApplication()->input->get("id", NULL);
     $jsession = JFactory::getSession();
     $fsession = new FSession($jsession->getId(), $cid, $mid);
     // Store the answer in the session
     $data = $fsession->Load('filelist');
     // Read the list from the session
     if ($data) {
         $filelist = explode("|", $data);
     } else {
         $filelist = array();
     }
     $filelist[] = $filename;
     // Append this file to the list
     $data = implode("|", $filelist);
     $fsession->Save($data, "filelist");
     $this->Log->Write("File " . $filename . " uploaded succesful.");
     $this->DebugLog->Write("File uploaded succesful.");
     return array("success" => true);
 }