Category Archives: Web

Обо всём, что связано с WEB технологиями и мной

Первый более мение серьёзный WEB проект

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

Тогда я только начинал свою карьеру WEB-программиста, работал в маленькой конторе с классным брендом "META Grupė". Бренд считался солидным, так как в нём было слово "Grupė" (в переводе с литовского: группа). У компании было 3 отдела – коммуникации (занимался продажами какой-то там телефонии), компьютерный (продажа, сервисное и послесервисное обслуживание компьютеров в офисах) и WEB (в котором собственно работал я). В команде нас тогда работала трое (говорят идеальное число) – Я, Vladimiras Lekečinskas (aka Xekc) и Rudolfas Cybulskas (aka Asperix). Xekc в этой шайке был главным (после руководства компании), Asperix был программистом, а я так, человек который делал всё остальное (тексты ввести, за блондинку по интерфейсам покликать, что-то где-то найти в интернете, прочая не квалифицированная работа). А ещё я был на третьем курсе программирования в VIKO (тогда правда он назывался VAEM).

Значит, все мои знания и желание творить подтолкнули меня к тому, что в начале я начал писать код. В начале HTML, простенький, не валидный но рабочий. Как сейчас помню – толстый талмуд с надписью HTML 4 который я листал по вечерам изучая этот язык разметки. Знакомился и с CSS, правда, всё знакомство было основано на копировании кусков чужих стилей для табличной вёрстки. За этим последовали первые куски кода на PHP 3 (да да, тогда в Литве было много серверов с поддержкой PHP 3). Первый "Hello World!", первое соединение с базой, потом первый снифер (вообще-то это был логер, записывавший IP, Бродилку, URL и время посещения), первая гостевая книга на My SQL (интересно, если бы сейчас её откопать, сколько XSS и SQL атак на ней можно было-бы провести?).

И меня заметили и первым моим заданием стал форум для сайта Lietuvos Sveikata. Это была уже полностью командная работа – ну как, 2 программиста. Никакого API, никакого опыта командной работы, никакого CVS/SVN. Знали только одно – общую структуру таблицы пользователей и несколько переменных в сессии, от которых зависело залоглен ли пользователь. Естественно, когда написали код, без API, пришлось ещё пару дней это всё соединять. И оно заработало. Ошибки потом ещё долго отлавливали.

Паралелно я где-то увидел (или мне показали) первые XSS атаки. Это был <script>alert(‘You a hacked!’);</script> – оно вроде тогда ещё то и названия XSS не имело. Тогда весь ввод мы позакрывали при помощи PHP функции strip_tags. Я не знаю, хорошо ли она работала на тот момент, но, нам казалось что всё в порядке.

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

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

О dip.:studija в печати (Naujoji komunikacija № 8)

O Dabarties interneto prokektų studija (dip.:studija или dip.:studio) и её поездке в Каны наконец опубликовали статью в NK: Naujoji komunikacija № 8 – “Medijų karas”. Единственное средство массовой информации в Литве, которое уделило должное внимание достижениям компании. Пусть только в печатном виде, пусть и с опозданием – но огромной статьёй с фотографиями на 3 страницы.

Вот такая короткая новость о компании, в которой я работаю.

Google Toolbar для Firefox

Не прошло и года, как Google выпустила toolbar для нашего всеми любимого Firefox с поддержкой своих кнопок, Google bookmark а так-же можно любой документ, поддерживаемый в Google Docs & Spreadsheets втащить в Firefox и он откроется в Google Docs & Spreadsheets. При установки сам взял кнопки, которые я использую в Google toolbar у Internet Explorer 6. С праздником!

Что ищут здесь посетители

Вообще, самый популярный запрос в этот блог: где/как/от куда/каким способом скачать IE6 или просто Internet Explorer. Так вот, скачать его можно было прямо с сайта Microsoft. Вообще, весь процесс описан в статье: Download IE6 – In FULL….. We show you HOW!. Ну или коротко, но запутано тут: Как скачать Microsoft Internet Explorer 6.

А теперь 13 самых интересных запросов за последние 30 дней, по которым люди пришли в этот блог:

  • водочное меню – хорошее сочетание, правда про водку я особо не писал никогда, за исключением одного раза
  • кол-во запросов в live.com – вот чего не знаю, того не знаю, вообще, народ, зачем вам это?
  • установка ajax на apache – а вам основы учить надо, а лучше вообще, бросить строить web
  • взлом zaza – производиться ломом, монтировкой, любым тупым предметом по голове
  • делаем реактивный двигатель на велосипед – обязательно опишу потом, как к ракете приделывали педеальную тягу и прочие нетрадиционные способы передвижения между галактик
  • исследование скачать – можно конкретнее, какое исследование вы ищите?
  • регистрация домена в зоне lt – элементарно, Ватсон – domreg.lt
  • установка – обязательно произведу установку памятника, операционной системы любой сложности и размера, крана, красной клизмы и прочих устанавливаемых; интересно, установку чего они искали?
  • польша идиотизм – как странно некоторые страницы трактуют поисковые страницы
  • острые полиморфические психические растройства – да да, встречаются иногда, но мы с ними боремся, да; а ещё я как суслик свистеть умею и мысли читать на расстоянии
  • готовые баннеры скачать – а вот зачем вам скачивать чьито готовые баннеры? Свои сделать/заказать слабо?
  • как apache читает – как и любой другой индеец, apache читает свои письмена в стандарном направлении для древне-америнакского проязыка, если индеец старый – он их не читает а знает наизусть
  • apache хватает только на 4 часа – экий вы маньяк, замучить индейца за 4 часа в щепки – да вы монстр просто и главное его вам мало, вы ещё хотите; современные жители того материка, на котором жили индейцы, их истребляли долгие годы, а вы за 4 часа со всеми детьми

А остальное совсем по теме.

5 лет на одном CMS

Не прошло и 5 лет, как Вильнюсская коллегия сменила CMS, который поддерживал её главный сайт. Наконец, мой (ладно, наш) RISING CMS отдохнёт в архивах на болванках и не будет отдавать страницы пользователям интернета. Сайты факультетов пока не изменились, но я думаю, они очень скоро это изменят. Ко всему прочему, коллегия сменила и дизайн сайта, который весьма не дурной, по сравнения с прошлым разом.

А мне теперь придётся во всех CV и портфолио пометить, что сайт Вильнюсской коллегии мой CMS поддерживал с 2002 по 2007 год. RIP, RISING, RIP.

На замену RISING CMS они выбрали CMS Made Simple, в котором за 15 минут удалось найти XSS type1 (они знают и уже залатали его у себя на сервер). Посмотрим, как им будет везти дальше.

Как, бывает, хранят пароли

Я, пока, опущу ту вкусную часть, как при помощи SQL-Injection можно получить пароли пользователей, но желающие могут самостоятельно прочесть IV раздел мануала о Безопастности – SQL Injection . И расскажу о самой неприятной (ок, не всем не приятной) привычке – открытых паролях и том как их хранят в других случаях.

Итак, первый и самый простой случай, когда пароли хранятся в таблице (название не имеет значения, но очень часто это бывает таблица users, admins или members, возможны разные префиксы), в поле password (обычно нужные поля очень легко узнать по форме регистрации или логина). Оно очень приятно, когда у сайта есть уязвимость ввиде SQL-Injection – вытянуть пароль и логин нужного вам пользователя не составит никакого труда. Время, нужно на поиск, занимает от 10 минут до нескольких часов – всё зависит от мастерства и фортуны (но не стоит исключать человеческий фактор). Кстати, если базу уводят (физический дамп с сервера), создателям скажут “спасибо”. Такие разработчики обычто оставляют незащищённый phpMyAdmin на сервере в легко доступном месте, а иногда оставляют SQL-Injection в скрипте логина в CMS. Вы конечно скажете – бред, не может быть, но всё-же такие случаи встречаются в моей практике и не раз.

Более сложный вариан для взломщиков – когда пароли хешируют. Обычно, встречаются варианты когда пароль просто хеширую при помощи md5 или других функций. Хотя тут, народ исхитрился иметь небольшие базы готовых хешей. Значит и тут пароли могут пострадать – вопрос размера базы хешей и то, какой это хеш. Конечно, все пароли не раскроют. Часто в базе – словари, фразы, а всякие “kld8jSkhYakKd772” там наврятли будут – всё зависит от размера базы, вашей удачи и, иногда, от теории вероятности (про коллизию не забываем, да).

Итак, в резюме, получается, что с паролями излишняя параноидальность вам/нам не помешает. Если вы поманипулируете с паролями пользователей (да и администраторов) – вам это не повредит ни в коем случае. Сделать пару SALT, докинуть чего из “логина”, добавить битовую операцию, потом сделать base64 енкодинг и только потом хеш – это наверняка затруднит восстановление ворованного пароля.

А что вы посоветуете?

Что я знаю о register_globals

Постоянно сталкиваюсь с серверами, где по умолчанию register_globals = On. Да, мне ничто не мешает взять .htaccess и отключить: php_value register_globals Off или написать письмо администратору сервера. Однако, иногда и сам забываешь о той угрозе, которую несёт в себе register_globals = On.

Для того, что-бы воспользоваться чем-то, что даёт вам register_globals = On, нужно либо иметь на руках исходники скрипта, либо быть очень счастливым с…м сыном (ну ещё есть шанс, что ошибки, выбрасываемые PHP вам помогут). Естественно, речь идёт о Global Scope.

На днях я перебирал один маленький сайтик, где PHP используется только для того, что бы можно было удобно и быстро подключить хедер и футер, меню и для страниц легко менять тайтл и мета данные. Такой классический сайт из учебника, плюс несколько наворотов, которые позволяют кешировать сайт на стороне клиента так, как будто это статически HTML. Теоретически, если отключить expose_php и сделать ServerSignature Off, а ServerTokens Prod мало кто догадается, что это PHP.
И нашёл я там одну переменную, которая отвечала за подключение отдельного CSS для страницы. Она была задекларированна не во всех файлах, а толxко там, где требовался дополнительный CSS файл. Именно в тех файлах, где эта переменная не была установлена, её можно было установить при помощи GET, POST или COOKIE (ведь мы помним о variables_order). Плюс никакой фильтрации. Идеальное место для XSS type1 атаки. Но для такой атаки имя переменной нужно знать.

Есть ещё такой стиль программирования, когда массивы никто не декларирует, а сразу к ним обращается. Я имею ввиду, что некоторые программисты не пользуются таким выражением: $arr = array ();, а сразу выполнят присваивание: $arr[] = ‘some value’;. Опять же через GET, POST или COOKIE в таком случае можно передать первые ключи для массива $arr. И тогда сколько таких переменных есть у них, которые можно поменять, зная их имена?

Вроде и нет ничего страшного, действует только на Global Scope, надо знать название переменной, но вы не можете гарантировать, что копия сайта е попала в руки мальчишам-плохишам. Так, однажды, получив исходники одной CMS, можно досконально изучить её код, найти уязвимые места, а потом вскрыть этак сайтов 10-15 с одной и той-же ошибкой. Именно так однажды случилось с CMS моего знакомого: CMS решал, человек залоглен или нет, опираясь на онду переменную $admin_id. Стоило сделать запрос admin.php?admin_id=1 и коробочка раскрылась и даже не смотря на то, что этот $admin_id должен был придти из сессии – н там не был установлен (я взял новую сессию) и скрипт пощитал, что всё впорядке и можно пользоваться.

Короткое резюме: пишите свои проекты с учётом register_globals = Off; если вы уверены, что вами написанный проект отлично работает с register_globals = Off, а на сервере register_globals = On – отключите register_globals, так как в редких случаях это может вызвать неадекватное поведения вашего проекта; если вам приходиться работать со скриптами, которые требуют register_globals = On (только в том случае, если это необходимо), будьте предельно бдительны, не сделайте глупых ошибок, связанных со свойством register_globals = On, а также проведите аудит скрипта на возможные ошибки – вы последний, кто его редактировал и все бочки посыпятся на вас.

Заметки о загрузке файлов с 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; проверяйте и перепроверяйте параметры.

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