Pull to refresh

Comments 41

На самом деле вышеописанное — это баг апача. Потому что нельзя такую фичу "просто отключить", именно по описанной в статье причине. Для производительности можно сделать много другого — кешировать, проверять наличие .htaccess файлов при запуске и выдавать фатальную ошибку если они были найдены (т.е. вынудить админа либо явно включить поддержку .htaccess обратно, либо ручками удалить все такие файлы — и тогда уже он должен понимать, что делает), реализовать перечитывание этих файлов в фоне отдельным процессом или через inotify, etc. В общем, полно способов улучшить производительность не жертвуя безопасностью такого критичного элемента инфраструктуры как веб-сервер. Основная проблема как раз в том, что все озабочены в первую очередь фичами, во вторую скоростью, а о безопасности начинают думать только тогда, когда из-за её отсутствия начинают происходить инциденты. Поэтому эта идея пока относится к ненаучной фантастике:


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

В целом при построении безопасности нельзя полагаться на 3rd-party программное обеспечение со своими настройками, по крайней мере в ситуации, когда можно на это не полагаться особо не напрягаясь. У апача и раньше мог быть отключен хтаккесс, а может там нгникс был бы установлен, могла отвалиться обработка хтаккесс по разным причинам. При чем последнее на реальных проектах случалось уже и к утечкам приводило (тот же fl.ru если из советстких).

Файлы надо было загружать или выше корня или переименовывать их при загрузке или класть в базу или закидывать на отдельный домен где в принципе только статика есть или еще что-то… и проблемы бы не было, при чем это был бы уровень безопасности на уровне приложения, без отдачи ответственности за эту безопасность наружу.

Что касается фикса проблемы методом
'accept_file_types' => '/\.(gif|jpe?g|png)$/i'
Мы либу конечно не смотрели, но можем предположить что тут тупо проверяется окончание имени файла на .gif .jpe .jpeg .png при чем это анонсируется как проверка на «графическость» файла.
Но тогда это крайне кривой способ закрытия уязвимости, т.к.
Во-первых, тут не проверяется графический ли это файл, только расширение. Поэтому можно и пхп файл загрузить и сги скрипт под этим именем.
Во-вторых, файл можно загрузить под расширением вида picture.php.png, что при некоторых настройках апача может привести к его выполнению.
В-третьих, никто не отменяет xss при этом.
UFO just landed and posted this here
А зачем это проверять?
Потому что если такая проверка обещана
для правильной обработки этой ситуации и исправления уязвимости загрузки файлов CVE-2018-9206, разработчик изменил код так, чтобы он разрешал загружать только файлы изображений.

То будет неправильным ее не делать.

Надо иметь доступ к настройкам апача. чтобы это сделать.
Не, надо иметь доступ к настройкам в случае если Вам хочется изменить эту настройку — отключить или включить. Какое ее состояние в абстрактном апаче на абстрактном сайте разработчик не знает, поэтому обязан предполагать что мультирасширение включено.
UFO just landed and posted this here
Он и сделал, причем не менее надежным способом.
Нет, не сделал.
Проверка на расширение это одно, проверка того является ли файл картинкой это другое.

Если такая настройка сделана администратором, то она сделана специально, и исправление этого со стороны разработчика — это не ожидаемое поведение.
Разработчик не должен исправлять такую настройку, он должен учитывать возможность такой настройки.
UFO just landed and posted this here
Вот только в рамках обсуждаемой проблемы (инъекция PHP кода) первое безопаснее.
Было заявлено «пройдут только картинки», на деле картинки это или нет не проверяется. Вот и вся проблема.

Если так настроили, то значит так надо, нет?
Именно поэтому мы и говорим, что скрипт должен учитывать это.
на деле картинки это или нет не проверяется.

А как бы вы проверяли? Мне просто любопытно.

imagemagick или gd — в легкой форме получаем параметры картинки (identify / getimagesize), если получили — считаем картинкой. В тяжелой форме создаем изображение из файла картинки и записываем его.
О минусах этих подходов знаем, но для наших проектов с головой этого.

Если вы считаете, что "с головой" — это удалить РНР код из изображения, то у меня для вас плохие новости.

в легкой форме получаем параметры картинки

это легко обойти.


В тяжелой форме создаем изображение из файла картинки и записываем его.

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


Как по мне — проблему надо решать иначе.

FanatPHP

Если вы считаете, что «с головой» — это удалить РНР код из изображения, то у меня для вас плохие новости.

Мы об удалении PHP кода из изображения вообще ничего не говорили. Вопрос был способе проверки картинка это или нет.

Fesor,
это легко обойти.
Поэтому это и легкая форма:)

а как вы боритесь с шелами в метаданных EXIF? Да и потом, уверен что я смогу заиньектить код так что пройду и эту «тяжелую форму».
Ваш вопрос был о том как мы делаем проверку картинка это или нет.

Вопрос безопасности мы затрагивали в самом начале, позволим себе процитировать
Файлы надо было загружать или выше корня или переименовывать их при загрузке или класть в базу или закидывать на отдельный домен где в принципе только статика есть

Или если упростить — наше мнение в том, что надо бороться не с загрузкой г-на, а с исполнением залитого в принципе. Заодно это решает проблему «что делать» если вдруг Вам понадобится что бы к Вам заливали пхп скрипты по какой-то причине.
Вопрос был способе проверки картинка это или нет.

:)))
У вас в самом начале произошла подмена понятий:


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

Этой нехитрой логической конструкцией вы сначала убедили себя, что "проверка на картинку" имеет хоть какой-то смысл в контексте защиты от заливки РНР скриптов (что само по себе неверно), а потом и вовсе дистанцировались от вопроса защиты, что позволило вам встать в красивую позу и заявить, что


Мы об удалении PHP кода из изображения вообще ничего не говорили.

Хотя и статья, и обсуждение — именно про РНР код в картинках, а совсем не про то как определить, является ли файл валидной картинкой, или нет.

:)))
У вас в самом начале произошла подмена понятий:
Нет.
Процитируем диалог в который Вы встряли
edogs: картинки это или нет не проверяется.
Fesor: А как бы вы проверяли? Мне просто любопытно.
Тут нет ничего вообще про безопасность.

вы сначала убедили себя, что «проверка на картинку» имеет хоть какой-то смысл в контексте защиты от заливки РНР скриптов
Нет. Мы такого не утверждали и уж тем более не «убеждали» себя в этом.

потом и вовсе дистанцировались от вопроса защиты
Еще раз процитируем себя же из того поста на который Вы ссылаетесь
Файлы надо было загружать или выше корня или переименовывать их при загрузке или класть в базу или закидывать на отдельный домен где в принципе только статика есть или еще что-то… и проблемы бы не было, при чем это был бы уровень безопасности на уровне приложения

Какое дистанцирование? Вы там что курили?

Ой, во множественном о себе — это была не опечатка. Понятно, вопросов больше нет.

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

Вообще-то есть. Чтобы картинка стала валидным PHP нужно ей в конец дописать скрипт либо, возможно, вставить его в мета-теги — точно не помню. И хотя формально в этом ничего страшного нет, но на практике это сильно зависит от множества факторов, в т.ч. на сторонних вебсайтах куда эту картинку будут вставлять. Защита должна быть многоуровневой, поэтому я лично когда писал приём картинок юзеров на сервере не только реализовал проверку формата файла помимо расширения, но и добавил перекодирование картинок на лету (просто преобразование в массив точек, которые потом обратно кодируются в jpg/png/gif файл — без изменения размера/качества картинки, но сам процесс гарантирует что любые данные дописанные в конец оригинального файла либо в его мета-теги будут удалены). И при этом на нашем сервере никакого PHP нет в принципе, но, тем не менее.

точно не помню

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


но и добавил перекодирование картинок на лету

не помогает

Во-первых, причём тут браузер? Я про браузеры ничего не говорил, речь вообще-то шла о встраивании PHP-кода в картинки, и вот как раз PHP на сервере такие картинко-PHP файлы иногда выполняет как PHP-скрипт, а не просто отдаёт браузеру as is.
Во-вторых, вот вам немного (первых попавшихся) ссылок на тему встраивания в картинки всякой фигни, чтобы было меньше слухов и больше фактов:
https://www.helpnetsecurity.com/2015/06/02/future-attacks-hiding-exploit-code-in-images/
http://stegosploit.info/
https://www.howtogeek.com/119365/how-to-hide-zip-files-inside-a-picture-without-any-extra-software/

Понятно. Вы просто написали взаимосключающие параграфы, "Вообще-то [страшное в этом] есть… формально в этом ничего страшного нет", а я уже сам домыслил, что в вашем комментарии была отсылка к конкретному, пусть и устаревшему, эксплойту. Впредь буду внимательнее.


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

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

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

Не обязательно. Помимо чёрного и белого есть оттенки. Даже если нет возможности заблокировать все способы залить в картинке посторонние данные это ещё не значит что нет смысла блокировать те, которые возможно.


Что касается способа запуска этой нагрузки — защита должна быть многослойной, иначе она слишком хрупкая. Так что вне зависимости от наличия дыр в других слоях, которые приводят к запуску нагрузки, на обсуждаемом слое загрузки файлов лучше бы эту нагрузку удалять, насколько возможно.


Что касается конкретных примеров — бывают ситуации, когда картинка залитая на наш сайт используется как эксплоит для сторонних сайтов. Данный пример приводится исключительно в качестве граничной ситуации, когда мы в принципе не можем никак помешать выполнению этой нагрузки, но можем помешать залить её на наш сайт. Я лично не уверен, что с этим что-то можно сделать, и даже что с этим что-то нужно делать… но "не уверен" это ещё не синоним "не наша проблема". По факту наш сайт в этой ситуации можно формально обвинить в "распространении эксплойтов" — да, для этого нужно быть больным на всю голову, но мы что, мало таких больных наблюдали за последние годы, в т.ч. среди принимающих и исполняющих законы?

Знаете, я человек простой, в теориях мало что понимаю. Когда мне говорят "вот конкретный пример", то я ожидаю ссылку или описание конкретного случая взлома, обязательно с объяснением механизма. А не рассуждения вида "а вот был случай, кого-то где-то поломали со стороннего сайта, так вот мы в ответе за всех, кого приручили".


Если у вас есть конкретный сценарий взлома своего ли сайта, стороннего ли ресурса — я буду рад обсудить стратегию защиты от него. А рассуждения вида "защита должна быть многослойной, а то мало ли чего" я плохо понимаю. Извините.

Не знаю как сейчас, но 6 лет назад эта настройка была включена по умолчанию (Сейчас по ссылке отдается 404, а тогда был вывод РНР скрипта.).
Насколько я могу судить, пока это поведение не поменялось.


Так что я ещё рекомендую переименовывать файлы при загрузке, т.е. защита обеспечивается проверкой последнего расширения + переименованием.

Если это был бы баг, то его бы зарепортили и исправили в следующих релизах. Но этого не произошло, потому что все работало как задумано.

С другой стороны, соглашусь с вами, так быть не должно. Такие важные изменения должны происходить не в рядовом релизе с багфиксами, а в мажорном, и сопровождаться хорошо заметной записью в release notes, чтобы пользователи знали, на что они обновляются. В идеале – следовать semver, чтобы из номера версии было сразу понятно, ломающие там изменения или нет.
Это просто глобальная проблема высокого стека различных API и обычно неполной определённости логики состояний на некоторых уровнях — надо быть в курсе изменений на всю глубину и понимать что повлечет за собой изменение на каком-то из них. Большинство забивает на контроль — скорость разработки важнее.

По моему, проблема не в .htaccess, а в неправильном конфиге апача, поскольку все возможности локального .htaccess можно задать в общем конфиге. Поэтому и автор оригинальной статьи, и автор проекта борются со следствием, а не с причиной — надо объяснять админам риски и как их избегать.

UFO just landed and posted this here

Учитывая, что в 2018 всё ещё есть работа по Fortran, вряд ли апач и PHP когда-нибудь куда-нибудь пропадут.

Фортран фортрану рознь. И да, нет ничего стыдного в том что бы писать на фортране.


Но согласитесь, новых проектов на кобале вроде как не страртуют уже особо.

В 2018 году модуль MPM prefork/mod_php считаются устаревшими, а MPM worker + php-fpm прекрасно работают не хуже конкурентов и никаким "насилием" не являются.

Один вопрос. Каким боком тут привязан npm? До кучи, чтобы статья не была унылым приветом из 90х?
Или для увеличения куцого объёма ещё на абзац? (Там даже бессмысленное введение есть, но даже это не помогло).
Не ставлю минусов за переводы и в этот раз не буду, но это же просто мусор.
Автор полез искать дырки в популярных js-библиотеках. Где в 2018 году их еще искать, кроме как не в npm?
Предположим. Но к сути находки большую релевантность имеет его завтрак, чем npm. Так зачем упоминать?

И вся статья состоит из какой-то подобной шелухи, если убрать которую, то останется «я нашёл кривой аплоадер». Кстати, способ «исправления проблемы» — тоже та ещё жесть. Хотя чего можно было ожидать после «во всём виноват Apache» (чуваки вообще не в курсе, например, что бывают другие сервера)…

Лень смотреть, но верю, что в оригинале это может быть известная статья — но я до сих пор не понимаю, как можно заниматься таким хайпожорством.
Не могу понять что вы имеете в виду. То, что уязвимость не очень значительная, или что ее описание не очень?
Считаю что проблема высосана из пальца. Основная задача JS аплоадера — аплоадить файлы (отправлять данные на сервер) с чем библиотека прекрасно справляется.
В комплекте с библиотекой идут скрипты для бэкенда на РНР, python, go чтобы сохранять результаты аплоада. Их основная задача принять и сохранить файл, с чем они так же прекрасно справляются.
Так в чём же уязвимость библиотеки если она делает ровно то что задуманно?
Все настройки бэкенд скрипта доступны пользователю, где можно и раньше было задать white-list по расширениям файлов, где можно задать папку для аплоада выше корня веб сервера и тд.
А полагаться на .htaccess вообще смешно, а если у меня nginx или lighthttpd то получается я всегда был в зоне риска потому что не сумел минимально настроить бэкенд скрипт для аплоада, а использовал вариант «из коробки» который разрешал аплоад любых файлов в папку по умолчанию?
Вот если бы бэкенд скрипты которые идут с библиотекой позволяли бы сохранять файл в произвольное место, или например, пропускали файл *.php когда в настройках задано пропускать только *.jpg, или бы разрешали зааплоадить файл размером больше чем задано в настройках, можно было бы говорить об уязвимостях.
А так, я лично не вижу уязвимости в том что при настройках «разрешён аплоад любых файлов» — происходит аплоад любых файлов.
Согласен, проблема не очень большая. Большинство продвинутых разработчиков напишут бекенд-обработку самому, это не так сложно. Но хватает и начинающих разработчиков, которые скопируют код примера к себе, подвергая систему риску.

В ходе последующих за этим баг-репортом разборок нашелся даже один wordpress-плагин с этой уязвимостью: cxsecurity.com/issue/WLB-2018100153. Именно поэтому защита от дурака в примерах кода лишней не будет.
UFO just landed and posted this here
Sign up to leave a comment.

Articles