<MyRusakov.ru />

Фреймворк Yii 2.0 с нуля. Пример создания сайта

Фреймворк Yii 2.0 с нуля. Пример создания сайта

Видеокурс "Фреймворк Yii 2.0 с нуля. Пример создания сайта" обучит Вас созданию профессиональных сайтов с использованием фреймворка Yii. В курсе есть 2 раздела: теоретический и практический. В теоретическом разделе будут разобраны возможности фреймворка Yii с примерами их использования, а в практической части будет создан сайт Blog.MyRusakov.ru с помощью полученных знаний из теоретического раздела.

Так же почти ко всем урокам идут упражнения для закрепления материала из урока на практике.

После прохождения курса Вы без труда сможете создавать любые сайты с использованием фреймворка Yii, причём делать это будете быстро и качественно.

Подробнее
Подписка

Подписавшись по E-mail, Вы будете получать уведомления о новых статьях.

Подписка Подписаться

Добавляйтесь ко мне в друзья ВКонтакте! Отзывы о сайте и обо мне оставляйте в моей группе.

Мой аккаунт Мой аккаунт Моя группа
Опрос

Каким движком Вы предпочитаете пользоваться?

Безопасность при загрузке файлов на сервер в PHP

Безопасность при загрузке файлов на сервер в PHP

В прошлой статье мы с Вами разбирали загрузку файлов на сервер в PHP. Однако, я Вам уже сказал, что использовать код, который там был рассмотрен, категорически нельзя! И в этой статье мы поговорим о безопасности при загрузке файлов на сервер в PHP.

Давайте напомню код, который мы вчера рассматривали:

<?php
  $uploadfile = "images/".$_FILES['somename']['name'];
  move_uploaded_file($_FILES['somename']['tmp_name'], $uploadfile);
?>

Фактически, на данный момент может быть загружено абсолютно всё, что угодно: любые исполняемые файлы, скрипты, HTML-страницы и другие весьма опасные вещи. Поэтому обязательно надо проверять загружаемые файлы очень тщательно. И сейчас мы с Вами займёмся их тщательной проверкой.

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

  1. Тип - только jpg (jpeg).
  2. Размер - менее 100 КБ.

Теперь реализуем скрипт "loading.php" в соответствии с этими требованиями:

<?php
  $blacklist = array(".php", ".phtml", ".php3", ".php4", ".html", ".htm");
  foreach ($blacklist as $item)
    if(preg_match("/$item\$/i", $_FILES['somename']['name'])) exit;
  $type = $_FILES['somename']['type'];
  $size = $_FILES['somename']['size'];
  if (($type != "image/jpg") && ($type != "image/jpeg")) exit;
  if ($size > 102400) exit;
  $uploadfile = "images/".$_FILES['somename']['name'];
  move_uploaded_file($_FILES['somename']['tmp_name'], $uploadfile);
?>

Теперь давайте подробно поясню, что здесь происходит. Первым делом мы проверяем на расширение загружаемого файла. Если оно представляет собой PHP-скрипт, то мы такой файл просто не пропускаем. Дальше мы получаем MIME-type и размер. Проверяем их на удовлетворение нашим условиям. Если всё хорошо, то мы загружаем файл.

Вы, наверное, можете спросить: "А зачем надо проверять и расширение, и MIME-type?". Тут очень важно понимать, что это далеко не одно и то же. Если злоумышленник попытается отправить PHP-файл через браузер, то и одной проверки MIME-type хватит, чтобы его попытка провалилась. А вот если он напишет какой-нибудь скрипт, который будет формировать запрос и отсылать вредосный файл, то этого не хватит. Почему? А потому, что MIME-type задаётся клиентом, а не сервером! И фактически, злоумышленник может поставить любой MIME-type (и картинки тоже), но при этом отсылать PHP-скрипт. И вот именно такую хитрую попытку мы и ломаем, проверяя на расширение файла.

Я сразу скажу, что данный код далеко не 100% защита (100% просто не существует), однако, взломать такой код будет очень и очень тяжело, поэтому можете смело утверждать, что Вы обеспечили высокую безопасность при загрузке файлов на сервер через PHP.

Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (http://myrusakov.ru)!

Добавляйтесь ко мне в друзья ВКонтакте: http://vk.com/myrusakov.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: http://vk.com/rusakovmy.

Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления

Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.

Порекомендуйте эту статью друзьям:

Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):

  1. Кнопка:

    Она выглядит вот так: Как создать свой сайт

  2. Текстовая ссылка:

    Она выглядит вот так: Как создать свой сайт

  3. BB-код ссылки для форумов (например, можете поставить её в подписи):

Комментарии (46):

sync.o sync.o 30.05.2011 15:43:31

Столкнулся с такой проблемой. Если попытаться загрузить файл больше, чем "выдерживает" сервер (у меня на Denwer'e - 10Mb), то массив $_FILES вообще не заполняется, и проверить размер файла через $_FILES['somename']['size'] становится невозможным. Как тогда защитить свою форму от таких попыток?

Ответить

Admin Admin 30.05.2011 15:50:51

Никак. Это и не важно, так как никакой нагрузки на сервер всё равно не идёт. Такой файл просто даже не рассматривается, поэтому бояться не надо. Главное написать пользователям о максимальном размере файла для загрузки.

Ответить

Alim_(I) Alim_(I) 30.06.2011 13:59:30

А как сделать чтобы не только jpg принимался?

Ответить

Admin Admin 30.06.2011 14:16:38

Надо добавить при проверке mime-type и другие тоже. Например, image/png и/или image/gif.

Ответить

Alim_(I) Alim_(I) 30.06.2011 15:02:15

<span><span>То есть вот так?: <span id="dtx-highlighting-item" dtx-highlight-backgroundcolor="yellow"> if </span><span>(($type<span id="dtx-highlighting-item" dtx-highlight-backgroundcolor="cyan"> != </span>"</span></span><span id="dtx-highlighting-item" dtx-highlight-backgroundcolor="lime">image/jpg</span><span>,g<span id="dtx-highlighting-item" dtx-highlight-backgroundcolor="yellow">if</span><span><span>,bmp,png")<span id="dtx-highlighting-item" dtx-highlight-backgroundcolor="lime"> && </span>($type</span><span id="dtx-highlighting-item" dtx-highlight-backgroundcolor="cyan"> != </span>"image/jpeg,g</span><span id="dtx-highlighting-item" dtx-highlight-backgroundcolor="yellow">if</span>,bmp,png")) exit; Или как?</span></span> P.S. Только к gif png bmp привязать image/ .

Ответить

Admin Admin 30.06.2011 15:03:43

Нет. if ($type != "image/jpg") && ($type != "image/png") && ($type != "image/gif") и так далее

Ответить

int int 27.03.2015 09:07:16

Регулярные выражения очень медленные и лучше избегать ситуация использования их в цикле. поэтому предлагаю взять расширение регулярным выражением и потом просто прогнать через in_array где будет массив расширений. Так будет гораздо лаконичнее

Ответить

mg15 mg15 18.08.2011 08:30:55

Здравствуйте,Михаил! Такая проблема:я поменял в Вашем скрипте путь сохранения файла с images на images_gallery,но загружаемые картинки всё равно упорно сохраняются в папку images... // <? $blacklist = array(".php", ".phtml", ".php3", ".php4", ".html", ".htm"); foreach ($blacklist as $item) if(preg_match("/$item$/i", $_FILES['somename']['name'])) exit; $type = $_FILES['somename']['type']; $size = $_FILES['somename']['size']; if (($type != "image/jpg") && ($type != "image/jpeg")) exit; if ($size > 102400) exit; $uploadfile = 'images_gallery/'.$_FILES['somename']['name']; move_uploaded_file($_FILES['somename']['tmp_name'], $uploadfile); ?> Подскажите,что я не так делаю? Заранее спасибо! p.s.Всё заработало!Я не понял,в чем прикол был....наверно,магнитные бури!))))

Ответить

razo razo 21.10.2011 18:06:13

таким способом $blacklist = array(".php", ".phtml", ".php3", ".php4", ".html", ".htm"); foreach ($blacklist as $item) if(preg_match("/$item\$/i", $_FILES['somename']['name'])) exit; мы защищаемся от дос атак

Ответить

haker haker 21.12.2012 22:55:42

Михаил,а как подставить редактор tiny MCE в свою админку?

Ответить

Admin Admin 22.12.2012 10:32:47

На официальном сайте есть подробная инструкция http://www.tinymce.com/wiki.php/Installation Если плохо знаете английский, то есть сайт http://translate.google.com

Ответить

haker haker 22.12.2012 10:46:53

Михаил,в меня токой вопрос,а в курсе с нуля до гуру Вы будите какой движок делать?

Ответить

Admin Admin 22.12.2012 13:06:55

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

Ответить

haker haker 22.12.2012 16:46:30

Михаил,я перечислил деньги за курс.Там проверьте свою почту там есть время оплаты и номер квитанции.Спасибо.

Ответить

maks1232123 maks1232123 22.12.2012 17:45:54

Михаил,а после перечисление денег за курс Вам указывать что надо??

Ответить

Admin Admin 22.12.2012 18:14:44

Зависит от способа оплаты.

Ответить

maks1232123 maks1232123 22.12.2012 19:24:51

Михаил,а как установить апачь сервер и создать свой сервер из компа?

Ответить

Admin Admin 22.12.2012 21:29:31

http://myrusakov.ru/php-make-server.html

Ответить

Adrenalin Adrenalin 05.03.2013 20:25:25

С момента написания статьи прошло больше года. Сейчас ты используешь дополнительную защиту для загрузки изображений? Какую? Можно пример :)

Ответить

Admin Admin 05.03.2013 21:40:05

Не использую.

Ответить

Adrenalin Adrenalin 06.03.2013 01:24:05

У меня папка для фото: foto Проверку mime пытаюсь выполнить так: $imageinfo = getimagesize($_FILES['somename']['tmp_name']); if($imageinfo["mime"] != "foto/gif" && $imageinfo["mime"] != "foto/GIF" && $imageinfo["mime"] != "foto/jpeg" ... Или нужно обязательно вот так: if($imageinfo["mime"] != "image/gif" && $imageinfo["mime"] != "image/GIF" && $imageinfo["mime"] != "image/jpeg" ...

Ответить

Admin Admin 06.03.2013 04:15:43

Mime-type foto не существует, поэтому только второй вариант.

Ответить

Adrenalin Adrenalin 06.03.2013 16:48:44

Понял. А что конкретно значит эта строка: $uploadfile = "images/".$_FILES['somename']['name']; move_uploaded_file($_FILES['somename']['tmp_name'], $uploadfile);

Ответить

Admin Admin 06.03.2013 23:17:26

Первая строка - это имя будущего файла, а вторая строка - это перемещение данных из временного файла в этот новый файл.

Ответить

Adrenalin Adrenalin 07.03.2013 02:51:11

Но это ещё не сохранение? Потому что у меня для этого существует свой каталог. Эти строки его нигде не скопируют?

Ответить

Admin Admin 07.03.2013 09:45:13

Это уже сохранение.

Ответить

Evg Evg 14.03.2013 21:41:56

Круто все объясняешь, молодец и спасибо тебе за это. Прочитал уже статьи про регулярные выражения, только не пойму $item\$ - это строки, которые заканчиваются на $item. а зачем тогда обратный слэш перед мета $? это мы его экранируем что ли? после переменных всегда так делается?

Ответить

alikhanov_k@mail.ru alikhanov_k@mail.ru 15.04.2013 11:13:02

Здравствуйте! Скрипт хорошо работает, спасибо вам. Только есть одно но... Если загружать файлы больше 100 кб, то экран становится белым и ничего там нет! Можно ли сделать вывод надписи вроде "Ошибка размер больше 100 кб!" или что-нибудь похожее?

Ответить

Admin Admin 15.04.2013 11:31:44

Можно, например, вместо exit можно поставить echo с соответствующим сообщением.

Ответить

alikhanov_k@mail.ru alikhanov_k@mail.ru 15.04.2013 11:47:13

Спасибо работает! А как сделать чтобы было сообщение о загрузке изображении. То есть если ошибка то пусть пишет "Error" а если загрузил то пусть пишет "ОК". Я полный Чайник в php, сижу с утра и не могу сделать это сам.

Ответить

Admin Admin 15.04.2013 12:51:03

Нужно освоить для начала оператор if, а затем move_uploaded_file($_FILES['somename']['tmp_name'], $uploadfile) - вот это поместить внутрь if, и если функция вернула true, значит, вывести, что файл загружен, иначе вывести ошибку.

Ответить

alikhanov_k@mail.ru alikhanov_k@mail.ru 15.04.2013 13:12:31

Спасибо большое все работает!

Ответить

kumakbtu kumakbtu 05.05.2013 22:04:57

$size > 102400 Здесь размер в битах показано?

Ответить

Admin Admin 06.05.2013 10:02:03

В байтах.

Ответить

t00039_jack t00039_jack 09.05.2013 23:13:40

Здравствуйте Михаил. У меня массив $_FILES пустой. В какой момент он заполняется и почему он может быть пустым ?

Ответить

Admin Admin 10.05.2013 11:47:13

Заполняется при отправке. Возможно, не указан атрибут enctype у формы.

Ответить

t00039_jack t00039_jack 11.05.2013 10:48:37

Спасибо, всё получилось. В enctype была опечатка.

Ответить

t00039_jack t00039_jack 11.05.2013 14:48:39

Здравствуйте Михаил. При попытке загрузить файл получаю сообщение: "Warning: POST Content-Length of 9956836 bytes exceeds the limit of 8388608 bytes in Unknown on line 0" Это ограничение метода POST или результат настроек сервера ?

Ответить

Admin Admin 11.05.2013 14:59:26

Это настройки сервера: http://myrusakov.ru/php-load-bigfile.html

Ответить

ketovpavel ketovpavel 30.07.2013 08:53:27

Привет, Михаил! Скрипт полезный весьма благодарин вам за это. Есть вопрос: Как сделать так чтоб все картинки при загрузке переименовывались в уникальные названия например вот этим способом: $token = md5(uniqid("")); $better_token = md5(uniqid(rand(),1)); Подскажите пожалуйста, куда его нужно прописать, чтоб применить этот способ вот в этот скрипт? Суть проблемы такова что при загрузке картинок сохроняются русские символы и при совпадении названия перезаписываются сами изображения

Ответить

ketovpavel ketovpavel 30.07.2013 11:02:29

Всё я сам решил! Добавил просто в скрипт следующий код: $uploadfile = "./uzer/images/".$_FILES['somename']['name']; $newfile = "./uzer/images/".$_FILES = md5(uniqid(rand(),1)).'.jpg'; rename($uploadfile, $newfile) or die("Unable to rename $uploadfile to $newfile.");

Ответить

vira vira 02.08.2013 09:02:35

Здравствуйте Михаил! У меня такой вопрос,можно ли при загрузке сделать чтобы файл переименовался? у меня не получается код вот такой: $type = $_FILES['filename']['type']; $size = $_FILES['filename']['size']; if ($size > 4194304) { echo("<b>Размер файла превышает четыре мегабайта</b><br>"); exit; } if (($type != "image/jpg") && ($type != "image/jpeg")&& ($type != "image/JPG")&& ($type != "image/JPEG")){ echo("<b>Вы можете загружать только jpg и jpeg</b><br>"); exit; } $uploaddir = './img/'; $file = $uploaddir . basename($_FILES['filename']['name']); if (move_uploaded_file($_FILES['filename']['tmp_name'], $file)) echo "<b>Файл загружен</b><br>"; else { echo "<b>Ошибка загрузки файла</b><br>";exit; }

Ответить

Admin Admin 02.08.2013 16:04:26

Можно, в move_uploaded_file() сразу и передаете нужное имя.

Ответить

phrenicum phrenicum 27.08.2014 13:10:24

Михаил, здравствуйте! Создавал хостинг изображений по бонусу из вашего курса PHP и MySQL с Нуля до Гуру, но возникла проблема: на странице вывода изображений выводится такая ошибка - "Fatal error: Call to private method Image::loadImage() from context '' in V:\home\localhost\www\myproject\show_image.php on line 3". 3 ряд совпадет с Вашим в обучающем видео. Как решить эту проблему?

Ответить

tikkiwiki tikkiwiki 01.09.2014 10:06:26

Ошибка может быть не обязательно в третьем ряду. Вообще интерпретатор Вам поясняет : Что Вы не можете получить доступ к защищенным методам из экземпляра класса. Чтобы получить доступ к защищенному методу родительского класса из экземпляра подкласса Вы должны объявить открытый метод в подклассе, а затем вызвать защищенный метод родительского класса от открытого метода подкласса.

Ответить

wapj wapj 21.09.2015 03:47:38

Почему пропускает файл mp4 после чего выводится 2 ошибки: 1 - Warning: POST Content-Length of 130113051 bytes exceeds the limit of 8388608 bytes in Unknown on line 0 2 - Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent in Z:\home\**********\www\*********\controller.php on line 6 Как этого избежать?

Ответить

Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.