Upload файлов, безопасность

1. Владимир (04.08.2010 / 16:04)
Сейчас делаю загрузку файлов и хотел бы у вас спросить по поводу безопасности.
А именно, хочется узнать как лучше проверять файлы - по расширению, или по MIME Types?
Ну а так же буду признателен за любого рода советы по безопасному аплоаду файлов ;)

2. Саня (04.08.2010 / 16:12)
Проверяй по всему что только можно и по максимуму. Миме типы+ массив разрешенных расширений файлов.

3. Lugaro (04.08.2010 / 16:14)
Тут 2 варианта, пускать только определенные форматы файлов или же пускать абсолютно все, сохраняя их в виде 423535.up или к примеру в мд5, а реальное имя хранить в базе, ну и все это скриптом выдавать, я выбираю второй вариант т.к нет не каких ограничений+зашита от прямых ссылок ну и по скорости скачивания можно ограничивать
Тут уже смотря для чего тебе..

4. Lugaro (04.08.2010 / 16:19)
Кстати мим тип проверять нет смысла, при загрузке его можно подменить, это если мим брать с $_FILES, ну а функция mime_content_type определяет по расширению файла, так что смысла нет, пускай только определенные форматы или же скриптом файл выдавай

5. Владимир (04.08.2010 / 16:19)
В общем я делаю загрузку файлов в движке для админов. Тут скачивание ограничивать ненадо. Мне важно, чтобы если вдруг ктото получит доступ в админку, не моги залить в загруз-центр или еще куда либо вредоносный файл. Вот.

6. Владимир (04.08.2010 / 16:38)
Пока из предложенных вариантов подходит только отсеивать расширения. Хотелось бы еще совета - а какие расширения, нужно отсеивать? Знаю точно что нужно запретить php, phtml, phtm, pl, cgi, js, py

7. Михаил (04.08.2010 / 17:07)
Можно в папке с файлами поотключать php и всё остальное и принимать тогда можно будет любые файлы

8. Владимир (04.08.2010 / 17:17)
7. Flyd, тоже вариант. А если хост не держит .htaccess то уже не прокатит. А мне и это нужно учесть ;) Двиг то все таки больше новичкам. А они все на бесплатный хост ставят

9. Саня (04.08.2010 / 17:23)
Отсеивать расширения типа php , phtml старо и тупо. Лучше определи формат тех файлов которые можно заливать напр jpg, png, gif, a остальное рубить. Хотя лучше выдавать аттач файлы скриптом как писал Лугаро,так как там уже уверен на все 99.9%

10. Владимир (04.08.2010 / 18:11)
Ну если честно быстрее перечислить те файлы, которые ненужны, чем те которые нужны.
лучше выдавать аттач файлы скриптом
А вдруг злоумышленник сможет загрузить файл не в нужное мне место и будет иметь доступ к нему напрямую ну или там еще как нибудь. Эхх. Жаль что нет функции которая бы определяла мим тип по его содержимому а не по расширению.

11. Lugaro (04.08.2010 / 18:49)
CHUMA (4 Августа 2010 / 17:11)
А вдруг злоумышленник сможет загрузить файл не в нужное мне место и будет иметь доступ к нему напрямую ну или там еще как нибудь.
Каким образом? говорю же сохраняешь файлы с не реальным именем к примеру $fileName = time().'.up'; а реальное имя в базе храни, вот и всё.

12. Lugaro (04.08.2010 / 18:51)
Да и 2 перечисленных способа абсолютно безопасны, только в первом фильтруй имя и пускай только определенный круг файлов

13. Саня (04.08.2010 / 19:11)
CHUMA (4 Августа 2010 / 18:11)
Ну если честно быстрее перечислить те файлы, которые ненужны, чем те которые нужны.
А вдруг злоумышленник сможет загрузить файл не в нужное мне место и будет иметь доступ к нему напрямую ну или там еще как нибудь. Эхх. Жаль что нет функции которая бы определяла мим тип по его содержимому а не по расширению.
все запретные расширения не запишесь. Легко что-то упустить. Напр .php5 или .php6 или еще ченить. Дело то твое,но подумай хорошенько.

14. Мансур (04.08.2010 / 19:35)
Лови код на .htaccess
<Files ~ ".(php|html|shtml|wmls|php3|php4|pl)$">
Order allow,deny
Deny from all
</Files>

php_flag engine off


15. Мансур (04.08.2010 / 19:39)
Да и так можно
$file_name = unitime().'.up';

16. Мансур (04.08.2010 / 19:47)
Ыы вот маленкий код для тебя))

<?php
$newdown=$_FILES['file']['name']; //имя

$chk = strtolower(substr($newdown, 1   strrpos($newdown, ".")));
$chk2 = array("jpg", "gif", "png", "mp3", "3gp", "jar", "mp4", "zip", "jpeg", "sis", "sisx", "bmp", "txt", "nth");
if (!in_array($chk, $chk2)) {
echo '<div align="center" class="a">';
echo 'ПАШШОЛ НАХ!<br/>РАЗРЕШАЕТСЯ: <font color="#FF0000">jpg, jpeg, gif, bmp, png, mp3, mp4, 3gp, zip, jar, sis, sisx, nth </font> ФОРМАТы !!</div>';
echo '<br/><a href="ТВОЙСКРИПТ.php">ПОВТОР НАХ</a><br>';
exit;}
?>


17. Саня (04.08.2010 / 20:15)
$chk = strtolower(substr($newdown, 1 strrpos($newdown, ".")));
что это за велисапед?
Юзай pathinfo()

18. Мансур (04.08.2010 / 20:30)
17. sanzstez, ето проверка для расширение. Ну что делать я только такие вариантов знаю)) 3Ы. Ты же кодер все знаеш а я совсем не знаю про пазинфо()

19. Владимир (04.08.2010 / 22:38)
15. Джармен Келл, большое спасибо. Ну я чтото наподобии уже сделал, только не как у тебя реализовал поиск по расширениям. Твой вариант больше нравится.

20. Владимир (04.08.2010 / 22:41)
.::lugaro::. (4 Августа 2010 / 18:49)
сохраняешь файлы с не реальным именем к примеру $fileName = time().'.up'; а реальное имя в базе храни, вот и всё.
Это не подойдет. Мне чем проще тем лучше. Это же WAP-ENGINE. Плюс на файлах. Плюс загруз центр уже нормально отлажен. Переделывать не хочется. Поэтому думаю по расширению проверку сделаю и по $_FILES['file']['type']

А насколько это точная информация, что можно подменить мим тип? Можете как то показать на практике?

21. ramzes (04.08.2010 / 23:40)
.::lugaro::.функция mime_content_type определяет по расширению файла, так что смысла нет
интересно как тогда у меня определяет тип если файлы хранятся без расширений?)))

22. Nu3oN (04.08.2010 / 23:52)
delete не так понял гг

23. Nu3oN (05.08.2010 / 00:00)
Я делаю типа как лугаро сказал! только пишу типа такого: при создании категории создаю "Массив" в который указываю допустимые для этой категории расширения, потом при заливке файла, сохраняю файл с таким именем time().rand(111,999).'.'.$format; ранд на тот случай, если вдруг 2 пользователя, решат одновременно залить файл! случай один на миллион, но все же шанс есть! и на всякий случай запрещаю работу php! и потом просто выдаю файл скриптом!

24. Lugaro (05.08.2010 / 00:05)
21. ramzes, То что она работает по расширению я ошибся, но сама функция работает не везде http://wapnew.ru/test.php
Да и мим она будет узнавать по нескольким символам в начале файла "GIF89a" берешь просто рнр код в конец пишешь, а содержимое всего файла она не будет анализировать, следственно проверка мима при загрузки это лишняя трата времени, достаточно будет расширения

25. Lugaro (05.08.2010 / 00:13)
CHUMA (4 Августа 2010 / 21:41)
Это не подойдет. Мне чем проще тем лучше. Это же WAP-ENGINE. Плюс на файлах. Плюс загруз центр уже нормально отлажен. Переделывать не хочется. Поэтому думаю по расширению проверку сделаю и по $_FILES['file']['type']

А насколько это точная информация, что можно подменить мим тип? Можете как то показать на практике?
Мим при загрузке передается браузером в заголовках, любые заголовки можно подменить
POST /up/?mod=upload HTTP/1.1
Host: test1.ru
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.1.11) Gecko/20100701 Firefox/3.5.11 WebMoney Advisor
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: ru,en-us;q=0.7,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://test1.ru/up/?mod=upload
Cookie: SID=05f32e96f02324ec4f8b301ba0cce532
Content-Type: multipart/form-data; boundary=---------------------------41184676334
Content-Length: 8453
-----------------------------41184676334
Content-Disposition: form-data; name="file"; filename="30.jpg"
Content-Type: image/jpeg


26. Владимир (05.08.2010 / 08:45)
Спасибо огромное, очень много чего нового нашел для себя. Будем искать еще способы smile
А пока погоняю функцию mime_content_type при разных условиях smile

27. Владимир (05.08.2010 / 11:22)
Из инета я еще узнал, что определение мимов функцией mime_content_type из PHP 5.3.0 удалили.
Mimetype extensions has been removed from PHP 5.3.0
Так что похоже она уже не актуальна. Буду фильтровать расширения.

28. Владимир (05.08.2010 / 12:07)
Вот еще кое что узнал. Теперь сто процентов уверен что $_FILES['file']['type'] это браузер передает тип файла, и он как раз и зависит от расширения. Так что не смысла его проверять. Такими же темпами можно и расширения фильтровать.

29. ramzes (05.08.2010 / 12:13)
if(preg_match('/[a-z0-9\-\(\)\[\]]+\.(zip|rar|mp3|jpg|png|gif|jar|sis)$/i', $file)){
можно и так...

30. Владимир (05.08.2010 / 12:24)
Вот как сделал я:
<?php
$pinfo = pathinfo($_FILES['uploaded_file']['name']);
$ext = strtolower($pinfo['extension']);
$chek_ext = array('jpg', 'jpe', 'jpeg', 'gif', 'png', 'bmp', 'wbmp', 'mbm', 'tiff', 'mp3', 'mmf', 'imy', 'midi', 'mid', 'aac', 'amr', 'wav', 'wma', 'mp4', '3gp', 'mpeg', 'mpg', 'mpe', 'mov', 'avi', 'wmv', 'asf', 'dat', 'jar', 'jad', 'zip', '7z', 'rar', 'tar', 'gz', 'tgz', 'bz', 'bz2', 'sis', 'sisx', 'cab', 'app', 'txt', 'nth', 'thm', 'chm', 'mms', 'doc', 'pdf');
if(!in_array($ext, $chek_ext))
 {
  echo'<p class="err">Ошибка!!! Вы загружаете запрещенный тип файла.</p>';
 }
?>


31. Studentsov (05.08.2010 / 12:29)
Если сервер криво настроен можно шелл пропихнуть и при такой проверке

32. ramzes (05.08.2010 / 12:43)
30, это же дырко, точнее отсутствие запрета при непрохождении проверки, добавь exit();

33. ramzes (05.08.2010 / 12:48)
$ext = explode('.', $file);
$ext = $ext[count($ext)-1];
if(in_array($ext, $validext)){
}else{
echo'Error bad extension this file!';
}
я по старинке делаю))

34. Владимир (05.08.2010 / 13:14)
ramzes (5 Августа 2010 / 12:43)
30, это же дырко, точнее отсутствие запрета при непрохождении проверки, добавь exit();
Этот запрет есть smile Я просто тебе укороченный вариант написал сюда smile

35. Владимир (05.08.2010 / 13:15)
Студент_trollface (5 Августа 2010 / 12:29)
Если сервер криво настроен можно шелл пропихнуть и при такой проверке
А какую тогда использовать проверку? Остается хатыч использовать. Ну а если сервер хатыч не поддерживает?

36. Андрюха (06.08.2010 / 16:58)
35.че эт за сервер такой?((( он везде нужен

37. ramzes (06.08.2010 / 20:26)
он везде и есть, даже на говнохостах

38. Nu3oN (09.08.2010 / 02:49)
31. Это насколько хост должен быть "гомнохостом" что бы, разрешить исполнение php сценариев на мультимедийных и не предназначенных для этого файлах!

39. Nu3oN (09.08.2010 / 03:08)
ramzes (6 Августа 2010 / 20:26)
он везде и есть, даже на говнохостах
на некоторых php.ini

40. ramzes (09.08.2010 / 19:43)
это не суть важно

41. ramzes (09.08.2010 / 19:43)
дубль

42. Studentsov (09.08.2010 / 20:26)
Nu3oN (9 Августа 2010 / 02:49)
31. Это насколько хост должен быть "гомнохостом" что бы, разрешить исполнение php сценариев на мультимедийных и не предназначенных для этого файлах!
К сожалению, на некоторых хостах срабатывает php в файлах вида file.php.jpg

43. Владимир (09.08.2010 / 20:58)
Да и вот один хост который не дружит с хатычем: hut2.ru - скажу сразу, что это самый что ни на есть "говнохост", но даже на нем ангина пашет нормально.

44. Михаил (09.08.2010 / 23:46)
Nu3oN (9 Августа 2010 / 03:08)
на некоторых php.ini
Там тоже можно выключить

URL: https://visavi.net/topics/12278