Перейти к публикации
Поиск в
  • Дополнительно...
Искать результаты, содержащие...
Искать результаты в...

Рекомендованные сообщения

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


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


Описание:

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

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

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

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

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

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 не ключевой метод проверки.

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

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

Ссылка на комментарий
Поделиться на других сайтах

И надо не только на <?php проверять, но можно атаковать через

<?xml
Ссылка на комментарий
Поделиться на других сайтах

Как вы заметили ранее это не эффективный метод, тем не менее его наличие позволяет в некоторых случаях сэкономить на 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=...">

Ссылка на комментарий
Поделиться на других сайтах

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

Ссылка на комментарий
Поделиться на других сайтах

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=...">

 

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

Ссылка на комментарий
Поделиться на других сайтах

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

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

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

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

Ссылка на комментарий
Поделиться на других сайтах

 

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

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

Ссылка на комментарий
Поделиться на других сайтах

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас
 Поделиться

×
×
  • Создать...

Важная информация

На нашем сайте используются файлы cookie и происходит обработка некоторых персональных данных пользователей, чтобы улучшить пользовательский интерфейс. Чтобы узнать для чего и какие персональные данные мы обрабатываем перейдите по ссылке. Если Вы нажмете «Я даю согласие», это означает, что Вы понимаете и принимаете все условия, указанные в этом Уведомлении о Конфиденциальности.