Заметки о загрузке файлов с PHP

Знаете, я не специалист по безопастности, но постоянно встречаюсь с элементарными проблемами любого WEB-программиста. А за последнюю неделю в жизни/работе призошло не мало изменений, связанных с безопасностью. Первое что очень сильно повлияло – это PHP Security conference, на котором показали на сколько бывают глупы создатели сайтов. Второе – это то, что я уже проверить и накопать на окружающих сайтах и своём коде.

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

Элементарная форма. Элементарный скрипт. Для того, что-бы нормально обработать картинку на “любом” сервере, её в начале нужно двигать в свой каталог на сервере. Чаще всего это где-то внутри DocumentRoot, и в редких случаях вне его. Почему? А никто не отменял случаев с включенным open_basedir. И вроде нет ничего опасного в том, что я написал, но, если файл попал в DocumentRoot – его можно соответственно вызвать броузером. А если вы не проверили что это за файл – могут быть проблемы. Ведь могли загрузить и PHP или Perl скрипт, в котором может быть бог знает что.

И я не буду скрывать, что я купился на этой форме. Да, тут я лажанулся. Я понадеялся на getimagesize. Оказалось – зря. В первую очередь нужно проверять расширение файла в массиве $_FILES[‘userfile’][‘name’] и ещё перед выполнением move_uploaded_file. И не забудьте провериться перед этим с is_uploaded_file.

Вот на расширении файла я и попался. Я этим (по непонятным мне причинам) очень сильно принебрёг и понадеялся на функцию getimagesize. А вот она то и подвела. Оказывается (установлено экспериментальным путём на локальном PHP версии 4.4) – при загрузке файла с расширением .php (помните, я этим принебрёг), если в этот файл всунуть первые 128 байт из PNG файла, getimagesize считает что это картинка. Соответственно PHP файл попал на сервер, а что дальше бывает, я вам рассказывать не буду.

Некоторые говорят, что нужно ещё проверять $_FILES[‘userfile’][‘type’], но доверять ему нельзя – это данные, которые нам посылает клиент и они могут быть легко потделаны на строне клиента.

Загружая файл, не рекомендуют полностью доверят и $_FILES[‘userfile’][‘name’] – только профильтровав, или только расширение. Если же его прямо вписать, возможна атака путём подделки имени файла (скажем впишут вам ../../../index.php, а если у вас suEXEC или su_php можно и пострадать). Причём, они (создатели PHP) даже не подумали это дело отфильтровать автоматически, хотя в примере Validating file uploads создатели мануала об этом подумали (сам пример на данный момент мне не понятен).

Если разобрать пример Validating file uploads, а мне он виден вот таким совсем не понятно, каким образом они установили что происходит “Possible file upload attack!”? Ведь файл будет сдвинут в каталог /var/www/uploads/, а если он не будет сдвинут – следовательно, либо нету прав на это, либо исходный файл пропал. По моему, там должна была функция is_uploaded_file, а move_uploaded_file уже потом.

Итак, короткое резюме: проверять файл по разрешению и разрешать загружать только те файлы, которые 100% не будут выполнены сервером как скрипты (я бы разрешал загружать только картинки); не доверять $_FILES[‘userfile’][‘name’], проверять и фильтровать её, если используете; если файл переноситься во временное место для обработки, постарайтесь это место либо держать вне DocumentRoot, либо закрыть его при помощи .htaccess; не доверять вообще $_FILES[‘userfile’][‘type’]; пользуйтесь функциями is_uploaded_file и move_uploaded_file; проверяйте и перепроверяйте параметры.

Если у вас есть комментарии на эту тему, советы или замечания какие – пишите.

PHP Security conference в Каунасе

Итак, прошёл PHP Security conference или PHP Security training в Каунасе.

XSS, SQL-Injections, Code Executions, Code Inclusions, Using google to find a Target, Shell Executions, Intranet Exploits, Output Encodings hacks и прочие вкусные вещи прошли огромным кол-вом через мои мозги. Часть осела, часть знал, о части даже не подозревал.

Johann-Peter Hartmann очень правильно подобрал материал, с немцам присущей пунктуальностью провёл не только лекции, но и hands-on курс с примерами взлома сайтов местных. 30 минут на взлом, несколько минут на поиск потенциальных мест для взлома, анализ кода (были даны примеры кода из зала, а он показал как надо это делать).

Вообще, очень много вещей в безопастности, связанной с PHP проектами, завязано на самом языке, а так-же на особенностях броузеров. Очень сильно убило то, как некоторые куски абсолютно не валидного кода, с огромными ошибками, отрабатывают броузеры, то как себя ведут броузеры и как их можно поймать с неуказанными чарсетами. Я об этом даже не подозревал.

Были затронуты вопросы безопастности на уровне сервера (в смысле Apache, Linux/Unix конфигурации), но очень поверхностно, так как это от части не совсем забота программиста.

Вообще, очень полезная инвестиция, как денег фирмы, так и личных. Очень прочистило мозг. Очень! Чаще бы так.

Начало весны 2007

Начало весны (хотя уже середина) многообещающее.

14 марта прошла первая конференция блогеров Литвы, в которой я участвовал и описал ключевые моменты: Часть первая, Часть вторая, Фотографии, Награждения, Послесловие..

Как тут-же, 28 апреля пройдут “Круглые столы блогеров”. Итак, 28 апреля, Вильнюс, Факультет коммуникаций Вильнюсского университета, алея Саулетикио 9-I, 205 аудитория (VU komunikacijos fakultetas, Saulėtekio al. 9-I, 205 auditorija). Конечно, всё будет на Литовском языке. Официальное заявления организаторов альтернативной конференции.

К этому всему добавиться Kaunas PHP::Conf 2007, которая пройдёт 14 апреля в Каунасском технологическом университете.

А кроме всего: PHP Security training, который пройдёт 16-17 апреля в Каунас. Ведёт его Johann-Peter Hartmann, участвует в разработке PEAR и PECL, а также член документирующей команды PHP. Вот только вопрос, почему оно стоит таких смешных денег 60 Литов за 2 дня, правда ничего не включено – ни проживание в Каунасе, ни обеды, ни что либо ещё.

И везде я принимаю участие. Потратиться не малое количество денег на езду, еду и удовольствия. Но дело того стоит.

PECL на Unix/Linux

Меня всё волновал вопрос, как ставить PECL на PHP из исходников. Сегодня я не только наконец нашёл ответ не этот вопрос (я не сильно искал его, если честно), но и попробывал сам это сделать.

Итак, есть 3 способа поставить PECL под Unix/Linux:

Как это делает PEAR я не знаю, не делал я этого с ним, зато провёл живой эксперимент с memcache-2.1.0, PHP 5.2.0 на Ubuntu 6.06 LTS (The Dapper Drake). Всё что от меня потребовалось сделать:

wget http://pecl.php.net/get/memcache-2.1.0.tgz
gunzip memcache-2.1.0.tgz
tar -xf memcache-2.1.0.tar
cd memcache-2.1.0
phpize
./configure
make
make install

Оно само всё сделало, и даже положило в нужную папку. Осталось только активировать его в php.ini.

Сделать это statically мне не удалось – всё остальное было поставлено из packages или как это у них называлось и компилировать все исходники с нуля никто не хотел.

Они сговорились, да? Обновления у Prototype.js, script.aculo.us, Zend Framework и Ruby on Rails

Неделя полна новостей: новый сайт Prototype.js + версия 1.5.0, script.aculo.us 1.7.0 с новым и сильно анонсированным эффектом Morph. Надо в понедельник будет обновить текущие проекты и посмотреть, как будет работать в Opera, FireFox, IE6, IE7.

Zend выпустил Zend Framework Preview 0.7.0, чесно говоря, я ожидал что Zend будет быстрее его разрабатывать.

Ilia Alshanetsky анонсировал выход PHP 5.2.1 RC3.

А 37signals с командой разработчиков выпустил Ruby on Rails 1.2 – все акцентируют REST, вот бы знать, что это и как это едят (я в данный момент далёк от RoR). Говорят они победили проблемы с UTF-8 и обновили библиотеки Prototype.js до версии 1.5. Эх, хочется усесться в этот локомотив и катить с ним, но можно быть средним RoRовцем или быть хорошим PHPистом с уклоном на администрирование и load-balancing решения (PHP проектов).
Кстати, надо написать памятки по установки CentOS 4 с ServerCD, а то эту операцию я делаю не слишком часто, а может ещё и пригодиться.

Кстати, вышел WordPress 2.0.7 – они настоятельно рекомендуют обновиться, и это через 6 дней после выхода WordPress 2.0.6.

Load-Balancing, PHP, FreeBSD и Suhosin

Последние 2 недели ужасно много времени (как свободного, так и часть рабочего) я посветил вопросам load-balancing. Пришлось “бегло” пройтись по nginx, поставить Cygwin и поиграться с LightTPD (причём он отработал как load-balancer примерно около 2 часов для теста), перечитать мануалы у Apache HTTP Server (mod_rewrite и mod_proxy). Чесно говоря, всё работает в тепличных условиях очень даже отлично и без особых временных затрат.

Потом уже начал собирать FreeBSD 6.2 RC2 с Apache 2 и PHP 5.2.0. Так вот, у FreeBSD с PHP 5.2.0 сразу идёт возможность установить Suhosin (опционально, по умолчанию – включено). Пока всё собирается нормально, но вот Suhosin я временно выкинул – это сервер не для shared hosting, а эксперимент в тепличных условиях, и Suhosin там не нужен.

А что такое Suhosin? Suhosin is an advanced protection system for PHP installations. Что означает – современная система защиты для PHP. Предназначена защищать нас от самих-же себя и дыр в PHP в общем. Зачал её уже известный Stefan Esser. Кстати, эта-же комманда сообщила о нескольких дырочках и в WordPress, поэтому рекомендуется обновиться до версии 2.0.6.

Немного новостей о Netcraft, Wi-Fi (идеи) и PHP Security Blog

Дали ссылку на Netcraft, их новый репорт о падениях хостеров. Большинство там для меня не знакомых хостеров, но, замечен www.1and1.com, а им пользуется один мой знакомый (он даволен соотношением цены и качества). Возможно это очень не плохой подсказчик для выбора хорошего хостинга.

Добрался я и до Security Lab. Больше всего внимания я уделил статье: Ученые предупреждают об опасности Wi-Fi излучения. Подумалось, что наверно в ближайшее время станут популярной одежда не только из кевлара, но и с мелкими вкраплениями металлической сетки для образования экрана из костюма или прочей офисной одежды. Может и опасно – если мокро и вдруг какое электричество подадут, можно и не выжить.

Но больше всего меня убила (немножко запоздавшая) новость: Stefan Esser ушёл из команды PHP Security Response Team. Вобщем, это обещает очень много интересных сообщений в PHP Security Blog. Кому интересно, то здесь совсем свежая и горячая дисскусия о безопастности.

Установка WordPress 2.0.4 на хостинг NetFirms.

На днях пришлось ставить WordPress 2.0.4 на хостинг NetFirms. Стокнулся я там с такой маленькой проблемой: если permalink установить в режим /%postname%/ WordPress их совсем не видит. Вообще, любой режим, кроме по умолчанию, не работает. Как оказалось, PHP 4-ой версии там установлен как CGI и, при включенной поддержке .htaccess (их поддержка для хоста по умолчанию выклячена и её нужно включать через Control Panel) и mod_rewrite, в переменных окружения нет ни малейшего упоминания о том, что находиться в адресной строке. Не приятно очень, подумал я, а «клиента» не устраивала классическая (по умолчанию) структура permalink, а вид /index.php/%postname%/ тоже никто не хотел. Дальнейшие эксперименты показали, что на сервере прекрастно поддерживалась работа в «режиме» MultiViews и WordPress в таком режиме прекрастно работает.

Чтож, подумал я, раз есть mod_rewrite и поддержка MultiViews да и WordPress всё это поддерживает, почему бы не переписать стандартный RewriteRule . /index.php [L] на свой, так, что-бы использовался MultiViews. В итоге мы получили RewriteRule ^(.*)$ /index.php/$1 [L,QSA]. Запретив права записи в этот файл, мы получили желанный результат. Даже не смотря на то, что в настройках permalink было /%postname%/, а WordPress получал /index.php/%postname%/. Так как, всё чудестным способом заработало – все были довольны!

Что будет, скажите вы, если «клиент» захочет поменять структуру permalink? Возможно всё развалиться, но «клиент» предупреждён, да и структуру permalink он менять наврятли будет – я не превый раз ставлю для него WordPress, и это его самая самая излюблення конфигурация. Хотя, он без меня, на такие резкие шаги не пойдёт, дизайн сменит обязательно, а вот в структуре системы кардинально менять не будет ничего.

Что я могу сказать о хостинге NetFirms? А практически ничего. Я вошёл, разобрался во всём (долго привыкал к их Control Panel), установил то, что просили, всё заработало и почти никакой головной боли. По крайней мере пока головной боли нет.