Перейти до вмісту
Пошук в
  • Детальніше...
Шукати результати, які ...
Шукати результати в ...

Recommended Posts

Отзывы с изображениями


Отзывы с изображениями


Описание:

Создание отзывов о магазине на отдельной странице, с возможностью размещения отзывов в отдельном модуле.

Отзывы добавляют клиенты магазина, заполняя форму. Можно прикрепить изображения.

Отзыв, заполненный клиентом, по-умолчанию отключен, для публикации требуется включить его в панели управления магазином.

Отзывы публикуются от нового к старым, по дате публикации.

Настройки/возможности:

1. Администратор магазина может редактировать, удалять, создавать отзыв.

2. Мультиязык.

3. Нет поддержки мульти-магазина.

4. Общие настройки модуля:

  • оповещать о новом отзыве по e-mail или нет
  • размеры фото
  • размеры прикрепленных изображений
  • размеры всплывающего изображения
  • размер фото kB
  • размер прикрепленных изображений kB
  • количество отзывов в модуле
  • разрешенные для загрузки типы файлов
  • seo url
  • заголовок страницы отзывов
  • title страницы отзывов
  • description страницы отзывов
  • keywords страницы отзывов

5. Настройки модуля в позициях

  • схему
  • расположение
  • статус
  • размеры фото
  • лимит
  • порядок сортировки

6. Настройки отзыва

  • дата публикации
  • рейтинг
  • статус
  • автор
  • текст
  • фото
  • дополнительные фото

Функциональные возможности:

Модуль использует стандартную схему работы upload opencart v1.5.6.4 с модификацией защиты(getimagesize, resize).

В случае неудачи upload изображений отзыва, изображения удаляются с сервера, отзыв не добавляется, покупателю отображается ошибка.

Валидация полей формы двухэтапная - js с дублированием на php. Осуществляется проверка расширения, размера, длинны имени файла.

Возможно назначить отдельной странице модуля h1, теги: title, description, keywords. Seo-url отдельной страницы работает при установленном расширении SeoPro.

Реализовано оповещение администрации магазина по средствам e-mail, указанной в разделе "Система-Настройки-Общие".

Стандартный input type=file кастомизирован, возможно использовать <a>, input и прочее, привязка к class тэга/поля и т.п.

Загрузка файлов без использования iframe, XMLHttpRequest, Flash, что позволяет на базе модуля реализовать любой интерфейс, используя только нужные технологии и решения.

Публичная оферта:

1. Автор не несет ответственности за код модуля и последствия его использования.

2. Модуль поддерживается/развивается силами сообщества opencartforum, автор не берет на себя обязательство поддержки/развития модуля.

3. Автор не заинтересован в платных доработках.


  • Автор
  • долучення
    21.03.16
  • Категорія
  • Системные требования
  • Метод активации
  • Ioncube Loader
  • ocStore
  • OpenCart.Pro, ocShop
  • Звернення до сервера розробника

 

Надіслати
Поділитися на інших сайтах

Модуль с пробоем безопасности. Можно подделать псевдо изображение с php "бомбой" внутри. Далее уже все будет зависеть только от квалификации хакера.

Ну нельзя давать прямой доступ к загруженному файлу

Надіслати
Поділитися на інших сайтах

Код "private function upload", "/catalog/controller/information/arbitrage.php"

	private function upload($upload_dir) {
		$upload_file = true;
		$uploaded_files = array();
		$files_unlink = array();

		foreach ($this->request->files['files']['name'] as $key => $file_name) {
			$file_usr_name = basename(preg_replace('/[^a-zA-Z0-9\.\-\s+]/', '', html_entity_decode($file_name, ENT_QUOTES, 'UTF-8')));

			if (is_uploaded_file($this->request->files['files']['tmp_name'][$key]) && file_exists($this->request->files['files']['tmp_name'][$key])) {
				$file = $upload_dir . md5(mt_rand()) . basename($file_usr_name);
				$uploaded_files[] = $file;
				$file = DIR_IMAGE . $file;

				$files_unlink[] = $file;

				if (@move_uploaded_file($this->request->files['files']['tmp_name'][$key], $file)) {
					$settings = $this->config->get('arbitrage_description');

					$image = new Image($file);

					if ($key) {
						$width = $settings['image_popup']['width'] ? $settings['image_popup']['width'] : 800;
						$height = $settings['image_popup']['height'] ? $settings['image_popup']['height'] : 600;
					} else {
						$width = $settings['dimension']['width'] ? $settings['dimension']['width'] : 50;
						$height = $settings['dimension']['height'] ? $settings['dimension']['height'] : 50;
					}

					$image->resize($width, $height);

					$image->save($file);
				} else {
					$upload_file = false;

					$this->error['upload_file'][$key] = $this->language->get('error_upload');
				}
			}
		}

		if (!$upload_file) {
			foreach ($files_unlink as $uploaded_file) {
				unlink($uploaded_file);
			}
		}

		return $uploaded_files;
	}


Код "protected function validate() {", "/catalog/controller/information/arbitrage.php"

protected function validate() {
		$this->language->load('information/arbitrage');

		if ($this->request->server['REQUEST_METHOD'] == 'POST') {
			if ((utf8_strlen($this->request->post['author']) < 3) || (utf8_strlen($this->request->post['author']) > 25)) {
				$this->error['author'] = $this->language->get('error_author');
			}

			if ((utf8_strlen($this->request->post['description']) < 25) || (utf8_strlen($this->request->post['description']) > 3000)) {
				$this->error['description'] = $this->language->get('error_description');
			}

			if (empty($this->request->post['rating'])) {
				$this->error['rating'] = $this->language->get('error_rating');
			}

			if (empty($this->session->data['captcha']) || ($this->session->data['captcha'] != $this->request->post['captcha'])) {
				$this->error['captcha'] = $this->language->get('error_captcha');
			}
		}

		foreach ($this->request->files['files']['name'] as $key => $file_name) {
			if (!empty($this->request->files['files']['name'][$key])) {
				$settings = $this->config->get('arbitrage_description');

				$file_usr_name = basename(preg_replace('/[^a-zA-Z0-9\.\-\s+]/', '', html_entity_decode($file_name, ENT_QUOTES, 'UTF-8')));

				// Allowed file extension types
				$allowed = array();

				$filetypes = explode(',', $settings['upload_allowed']);

				foreach ($filetypes as $filetype) {
					$allowed[] = trim($filetype);
				}

				$content = file_get_contents($this->request->files['files']['tmp_name'][$key]);

				if ($key) {
					$size = $settings['attached_size'] ? $settings['attached_size'] : 100;
				} else {
					$size = $settings['photo_size'] ? $settings['photo_size'] : 1000;
				}

				if (preg_match('/\<\?php/i', $content)) {
					$this->error['upload_file'][$key] = $this->language->get('error_filetype');
				} elseif (!in_array(substr(strrchr($file_usr_name, '.'), 1), $allowed)) {
					$this->error['upload_file'][$key] = $this->language->get('error_filetype');
				} elseif ((utf8_strlen($file_usr_name) < 1) || (utf8_strlen($file_usr_name) > 255)) {
					$this->error['upload_file'][$key] = $this->language->get('error_filename');
				} elseif (($this->request->files['files']['size'][$key] / 1000) > $size) {
					$this->error['upload_file'][$key] = sprintf($this->language->get('error_filesize'), $size);
				} elseif ($this->request->files['files']['error'][$key] != UPLOAD_ERR_OK) {
					$this->error['upload_file'][$key] = $this->language->get('error_upload');
				} elseif (@getimagesize($this->request->files['files']['tmp_name'][$key]) == FALSE) {
					$this->error['upload_file'][$key] = $this->language->get('error_upload');
				} elseif ($this->error) {
					$this->error['upload_file'][$key] = $this->language->get('error_upload');
				}
			} else {
				$this->error['upload_file'][$key] = $this->language->get('error_select_file');
			}
		}

		if (!$this->error) {
			return true;
		} else {
			return false;
		}
	}


1. $this->request->files['files']['error'][$key] != UPLOAD_ERR_OK
2. @getimagesize($this->request->files['files']['tmp_name'][$key]) == FALSE
3. preg_match('/\<\?php/i', $content)
4. $file = $upload_dir . md5(mt_rand()) . basename($file_usr_name);
5. $image->resize($width, $height);

6. прошлая беседа, на ту же тему, с вами Отзывы покупателей о магазине (отдельная страница)

Надіслати
Поділитися на інших сайтах

Код ..

<img src="<?php echo $arbitrage['image']; ?>" 

;)

И посмотрите класс Image, условие при котором не происходит ресайз ;)

preg_match - тоже можно обойти (врапперы, потоки)

Надіслати
Поділитися на інших сайтах

preg_match - тоже можно обойти

Ключевые методы:

2. @getimagesize($this->request->files['files']['tmp_name'][$key]) == FALSE

4. $file = $upload_dir . md5(mt_rand()) . basename($file_usr_name);

5. $image->resize($width, $height);

 

<img src="<?php echo $arbitrage['image']; ?>"

?

И посмотрите класс Image, условие при котором не происходит ресайз ;)

Надеюсь вы не об этом, т.к. там resize не для безопасности

 if ($result['image']) {
$image = $this->model_tool_image->resize($result['image'], $image_width, $image_height);
} else {
$image = '';
}
Если вы об этом

$image->resize($width, $height);
То о каком условии речь?
Надіслати
Поділитися на інших сайтах

....

 if ($result['image']) {
$image = $this->model_tool_image->resize($result['image'], $image_width, $image_height);
} else {
$image = '';
}
Если вы об этом

$image->resize($width, $height);
То о каком условии речь?

 

 

    public function resize($width = 0, $height = 0, $default = '') {

        if (!$this->width || !$this->height) {

            return;

        }

...

 

        if ($scale == 1 && $scale_h == $scale_w && $this->mime != 'image/png') {

            return;

        }

 

 

Т е без ресайза ЗАГРУЖЕННОЙ бомбы

Напомню, что через врапперы и потоки можно обойти preg_match

file_get_contents - тоже пробойная в принципе функция через врапперы и потоки

Надіслати
Поділитися на інших сайтах

Враппер php://filter — это вид метаобертки, позволяющий применять фильтры к потоку во время открытия. Использование фильтров дает возможность трансформировать данные, получаемые из файла или записываемые в файл. В PHP есть встроенные фильтры, доступные по умолчанию, но с помощью враппера php://filter также можно задействовать и пользовательские фильтры, созданные с помощью функции stream_filter_register. При этом использование неопределенных фильтров не влияет на обработку данных другими фильтрами. Например, если фильтр anyfilter не определен, то функция readfile просто выведет содержимое /etc/hosts полностью в верхнем регистре.

readfile("php://filter/read=string.toupper|\  anyfilter/resource=/etc/hosts");

Эта особенность может быть полезна для обхода проверок, на основе strpos, preg_match и других.

 

Надіслати
Поділитися на інших сайтах

 

Обход проверки на основе getimagesize

С помощью фильтров можно удалять не только стопперы. Можно, например, модифицировать содержимое изображения, после того как оно прошло проверку на основе функции getimagesize. В качестве примера рассмотрим скрипт, в котором присутствуют такие участки кода:

extract($_REQUEST); ..................include $templatedir.'/header.html'; ..................if(!empty($_FILES) )  {   $file_info = getimagesize($_FILES['image']['tmp_name']);   if($file_info['mime'] == 'image/jpeg'){   if(move_uploaded_file($_FILES['image']\ ['tmp_name'], $folder.'/avatar.jpg')).................

При отсутствии NULL-байта может показаться, что нет возможности ни проэксплуатировать RFI, ни загрузить что-то, кроме файла avatar.jpg. Но врапперы предоставляют нам новые способы эксплуатации подобного рода уязвимостей.

....

 

Надіслати
Поділитися на інших сайтах

 

Т е без ресайза ЗАГРУЖЕННОЙ бомбы

Не понял смысл.

 

Как писал ранее preg_match не ключевой метод проверки.

Изображение модифицируется изменением размера, что позволяет думать о полном удалении присутствующего в нем скрипта.

Опубликуйте источники откуда цитаты брали.

Надіслати
Поділитися на інших сайтах

Как вы заметили ранее это не эффективный метод, тем не менее его наличие позволяет в некоторых случаях сэкономить на getimagesize.

Интересует что вы хотели сказать этим

    public function resize($width = 0, $height = 0, $default = '') {
        if (!$this->width || !$this->height) {
            return;
        }

...

 

        if ($scale == 1 && $scale_h == $scale_w && $this->mime != 'image/png') {
            return;
        }
Надіслати
Поділитися на інших сайтах

Пруфов очень много

Один из них

https://xakep.ru/2012/11/22/php-filter-wrapper-attacks/

 

Вообще давать загружать пользователям ХОТЬ ЧТО ТО на сервер очень опасно

 

Для этого мало ресайзить, тем более через стандартный класс Image, первое что надо сделать отдавать файлы не на прямую, а через скрипты, а ресайзить через "рандом"

Надіслати
Поділитися на інших сайтах

 

Как вы заметили ранее это не эффективный метод, тем не менее его наличие позволяет в некоторых случаях сэкономить на getimagesize.

Интересует что вы хотели сказать этим

    public function resize($width = 0, $height = 0, $default = '') {
        if (!$this->width || !$this->height) {
            return;
        }

...

 

        if ($scale == 1 && $scale_h == $scale_w && $this->mime != 'image/png') {
            return;
        }

Как видите при этих условиях стандартная библиотека Image не ресайзит

Как вариант сделать  свою функцию ресайза, причем с "рандом" величинами а потом уже их преобразовывать в нужное

Когда хакер знает изначальные величины при которых не будет ресайза - он через враппер может их подделать

А как видите стандартная библиотека при этих условиях просто не ресайзит

Надіслати
Поділитися на інших сайтах

 

Для этого мало ресайзить, тем более через стандартный класс Image

Почему вы так думаете?

 

первое что надо сделать отдавать файлы не на прямую, а через скрипты

Что имеете ввиду?

 

Спасибо за ссылку, ознакомлюсь.

Надіслати
Поділитися на інших сайтах

Как видите при этих условиях стандартная библиотека Image не ресайзит

Как вариант сделать  свою функцию ресайза, причем с "рандом" величинами а потом уже их преобразовывать в нужное

Когда хакер знает изначальные величины при которых не будет ресайза - он через враппер может их подделать

А как видите стандартная библиотека при этих условиях просто не ресайзит

 

Опередили с ответом. Ознакомлюсь со статьей.

Надіслати
Поділитися на інших сайтах

И "отдавайте" <img как это сделано в opencart через скрипт download

К примеру <img src="index.php?route=information/arbitrage/image&image_id=...">

Надіслати
Поділитися на інших сайтах

Какой именно скрипт download имеете ввиду?

 

index.php?route=account/download/download&order_download_id=...

 

Также надо отдавать <img

 

<img src="index.php?route=information/arbitrage/image&image_id=...">

Надіслати
Поділитися на інших сайтах

index.php?route=account/download/download&order_download_id=...

 

Также надо отдавать <img

 

<img src="index.php?route=information/arbitrage/image&image_id=...">

Зачем?

 

И не забудьте вставить проверку не только на <?php но и на <?xml

Считаю что лишнее.

Надіслати
Поділитися на інших сайтах

Зачем?

 

Считаю что лишнее.

 

Не надо считать, надо сделать

Из <?xml можно выполнить что угодно

 

 

XXE-атаки

XML — широко распространенный текстовый формат, предназначенный для хранения структурированных данных, которые используются при обмене информацией между программами. Хорошо известно, что в XML-документ можно добавлять содержимое внешних файлов с помощью внешних сущностей (external entities), но при этом итоговый документ должен быть well-formed. В PHP обойти это ограничение можно с помощью фильтра convert.base64-encode.

Bypass well-formed XML output check<?xml version='1.0' standalone='yes'?><!DOCTYPE scan   [  <!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=./db.php">  ]><scan>&xxe;</scan>

Но врапперы можно использовать не только внутри XML-документа, но и в функции simplexml_load_file и в методе DOMDocument::load. Это дает возможность произвести XXE-атаку при allow_url_fopen =Off, если есть возможность манипулировать именем файла.

 

Надіслати
Поділитися на інших сайтах

И "отдавайте" <img как это сделано в opencart через скрипт download

К примеру <img src="index.php?route=information/arbitrage/image&image_id=...">

index.php?route=account/download/download&order_download_id=...

 

Также надо отдавать <img

 

<img src="index.php?route=information/arbitrage/image&image_id=...">

 

Если не затруднит, поясните свою точку зрения.

Надіслати
Поділитися на інших сайтах

Спасибо за замечание, позже прочту статью, по вашей ссылке.

Не подымал бы этот вопрос, если бы не хотел помочь хоть немного сделать безопасным

Вообще любая загрузка файлов на сервер разных хостеров может привести к пробою, очень много зависит от настроек сервера

Полностью безопасно, это когда код загрузки пишется под конкретный сервер.

Надіслати
Поділитися на інших сайтах

 

Если не затруднит, поясните свою точку зрения.

В каком смысле? Нет прямого линка на файл, пусть даже вы его там тысячу раз "ресайзили" и проверяли, все это обходится. Нельзя давать линк на файл прямо на сервере. А этим методом вы маскируете, заодно можно еще пару раз там "проверить" :)

Надіслати
Поділитися на інших сайтах

Створіть аккаунт або увійдіть для коментування

Ви повинні бути користувачем, щоб залишити коментар

Створити обліковий запис

Зареєструйтеся для отримання облікового запису. Це просто!

Зареєструвати аккаунт

Вхід

Уже зареєстровані? Увійдіть тут.

Вхід зараз
×
×
  • Створити...

Important Information

На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність.