Я продолжаю получать отчет о манипулировании файлами и раскрытии файлов, когда запускаю свое приложение через checkmarx. В отчете говорится, что:
Ввод, полученный с помощью add в файле src / Controller / UploadsController. php в строке 67 используется для определения местоположения файла, в который необходимо записать, путем добавления в файл src / Controller / UploadsController. php в строке 67, потенциально позволяющий злоумышленнику изменить или повредить содержимое этого файла или создать новый файл в целом.
Фрагмент кода:
....
78. $filtered = filter_var_array($this->request->getData('bulk_name'), $args);
....
94. if(escapeshellcmd(escapeshellarg(move_uploaded_file($tmp_name, $destination)))) {
....
150. public function sanitizeData($input){
....
211. public function sanitize($string, $forceLowerCase = true, $anal = false) {
Это то, что я пытался сделать, но у меня продолжают появляться те же проблемы в отчете. Что еще я могу сделать, чтобы обойти это? Идеи / Решения приветствуются.
public function add() {
$upload = $this->Uploads->newEntity();
if (escapeshellcmd(escapeshellarg($this->request->is('post')))) {
$args = array(
'tmp_name' => FILTER_SANITIZE_URL,
'error' => FILTER_VALIDATE_INT,
'name' => FILTER_SANITIZE_ENCODED,
'type' => FILTER_SANITIZE_SPECIAL_CHARS,
'size' => FILTER_SANITIZE_ENCODED,
);
$filtered = filter_var_array($this->request->getData('bulk_name'), $args);
if (!empty($filtered)) {
$file = $this->sanitizeData($filtered);
if (isset($file['flashMessage'])) {
$flashMessage = $file['flashMessage'];
$this->Flash->error($flashMessage, ['key' => 'error']);
} else {
$uploadDirectory = getcwd() . DS . 'files' . DS;
$fileName = $file['name'];
$upload = $this->Uploads->patchEntity($upload, $this->request->getData());
$upload->file_name = $fileName;
$tmp_name = $file['tmp_name'];
$destination = $uploadDirectory . $fileName;
if (escapeshellcmd(escapeshellarg(move_uploaded_file($tmp_name, $destination)))) {
$datasource = ConnectionManager::get("default");
$datasource->begin();
$saveUpload = $this->Uploads->save($upload);
if ($saveUpload) {
$session = $this->getRequest()->getSession();
$clientID = $session->read('Auth.User.client_id');
$userID = $session->read('Auth.User.id');
$lastSavedId = $saveUpload->id;
$baseName = basename($fileName);
$uploadedCSVFile = $uploadDirectory . $baseName;
$csvFile = fopen($uploadedCSVFile, "r");
$totalAmount = 0;
while (($row = fgetcsv($csvFile)) !== false) {
if ($row[1] < 1) continue;
$totalAmount += trim($row[1]);
}
fclose($csvFile);
$uploadEntry = $this->Uploads->UploadEntries->newEntity();
$entryData = array();
$entryData['upload_id'] = $lastSavedId;
$entryData['client_id'] = $clientID;
$entryData['user_id'] = $userID;
$entryData['amount'] = $totalAmount;
$entryData['status'] = 0;
$uploadEntry = $this->Uploads->UploadEntries->patchEntity($UploadEntry, $entryData);
$saveUploadEntries = $this->Uploads->UploadEntries->save($uploadEntry);
if ($saveUploadEntries) {
$datasource->commit();
$this->Flash->success('The upload has been saved.', ['key' => 'success']);
return $this->redirect('/');
}
$this->Flash->error(__('The upload could not be saved. Please, try again.'));
}
$this->Flash->error(__('The upload could not be saved. Please, try again.'));
}
$this->Flash->error(__('The upload could not be saved. Please, try again.'));
}
} else {
$this->Flash->error(__('Empty Upload', ['key' => 'error']));
}
}
$this->set(compact('upload'));
}
public function sanitizeData($input){
$args = array(
'tmp_name' => FILTER_SANITIZE_URL,
'error' => FILTER_VALIDATE_INT,
'name' => FILTER_SANITIZE_ENCODED,
'type' => FILTER_SANITIZE_SPECIAL_CHARS,
'size' => FILTER_SANITIZE_ENCODED,
);
$filtered = filter_var_array($input, $args);
$fileExtensionsAllowed = ['csv']; // These will be the only file extensions allowed
$mimes = array('application/vnd.ms-excel', 'text/plain', 'text/csv', 'text/tsv');
$fileName = $filtered['name'];
$fileSize = $filtered['size'];
$fileTmpName = $filtered['tmp_name'];
$fileType = $filtered['type'];
$fileError = $filtered['error'];
$file = explode('.', $fileName);//Split file name with extension
$ext = end($file); //get extension name
$fileExtension = strtolower($ext); //if change extension to lowercase
$output = array();
if (!is_readable($fileTmpName)) {
$output['flashMessage'] = 'File is not readable';
} elseif (!in_array($fileExtension, $fileExtensionsAllowed) && !in_array($fileType, $mimes)) {
$output['flashMessage'] = 'Unsupported File Type';
} elseif ($fileSize > 50000) {
$output['flashMessage'] = 'File is too large for upload';
} elseif (!$fileError == 0) {
$output['flashMessage'] = 'An error occurred';
}
$csvName = $file[0];
$newfilename = $csvName . date("YmdHis") . '.' . $ext; //new file name
$output['name'] = $this->sanitize($newfilename); //sanitize file name
$output['error'] = $fileError;
$output['tmp_name'] = $fileTmpName;
$output['type'] = $fileType;
$output['size'] = $fileSize;
return $output;
}
public function sanitize($string, $forceLowerCase = true, $anal = false) {
if($this->Auth->user()) {
$strip = array(".","~", "`", "!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "_", "=", "+", "[", "{", "]", "}", "\\", "|", ";", ":", "\"", "'", "‘", "’", "“", "”", "–", "—", "—", "–", ",", "<", ">", "/", "?");
$clean = trim(str_replace($strip, "", strip_tags($string)));
$clean = preg_replace('/\s+/', "-", $clean);
$clean = ($anal) ? preg_replace("/[^a-zA-Z0-9]/", "", $clean) : $clean;
return ($forceLowerCase) ?
(function_exists('mb_strtolower')) ?
mb_strtolower($clean, 'UTF-8') :
strtolower($clean) :
$clean;
}
}