e2 v1063: Обновление системы безопасности

Большое спасибо Шурику Бабаеву (он же A!e%), Дмитрию Кирсанову (он же ixed), Евгению Степанищеву (он же Болк) и Алексею Куликову (он же Clops) за разные ценные советы в области безопасности.

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

Очевидно, что чтобы заменить имеющийся в реестре MD5-хэш пароля на требующийся теперь SHA-1-хэш, e2 придётся узнать сам хэшируемый пароль, а сделать он это сможет только тогда, когда вы в следующий раз его введёте. Поэтому переход с MD5 на SHA-1 реально состоится только тогда, когда вы в следующий раз зайдёте в свой блог.

Среди других фиксов:

  • бэкап теперь должен делаться намного быстрее и без выкрутасов с памятью, т. к. использует напрямую функции mySQL
  • исправлен баг с процентами (кто знает, тот поймёт)
  • на странице избранных комментариев в заголовке браузера не отображалась строка «Избранные комментарии»
  • решена проблема c RewriteBase, из-за которой на некоторых хостингах e2 не ставился; теперь при установке в .htaccess прописывается эта строка
  • вроде бы получше работают Wiki-таблицы, если их встречается несколько штук в одном документе (раньше они как-то странно склеивались)
  • улучшена совместимость с PHP 4.1 (по крайней мере, e2 теперь под ним устанавливается), хотя в системных требования по-прежнему прописан 4.3 — вдруг ещё какие проблемы вылезут
  • поиск настроек стал ещё умнее

После перехода на новую версию зайдите в файл form_login.php и уберите из него обработку onsubmit на форме. Обработчик этого события теперь навешивается автоматически. Посмотрите, как теперь выглядит form_login в классической своей версии. Если вы не меняли его дизайн, то просто замените свой form_login.php этим.

Однако, пока я заморачивался с переходом с MD5 на SHA-1, выяснилось, что SHA-1 уже тоже взломали. См. также сюда. Но это всё ерунда, конечно.

Дистрибутив v1063 пока не делаю: вдруг окажется, что не все объявленные фиксы действительно у всех сработали.

В следующем milestone надеюсь починить глюки транслита при поиске и решить ещё кое-какие проблемы Wiki-форматтера.

Дальше
2 комментария
misnik 2005

Мвсль по поводу защиты от взлома хешей.

Можно записывать в куки не сам хеш, а хеш + N произвольных байт и перед проверкой в движке это учитывать.
Если злоумышленник будет брутфорсить такой хеш, то исходную последовательность не получит точно (а время потратит, и, возможно, будет сбит с толку).

Развивая идею использования ключа. Так как злоумышленник потенциально способен получить куки авторизованного пользователя, нужно сделать так, чтобы даже использование этих кук не помогло ему получить доступ к ресурсу. Решение проблемы: вместо логина+зашифрованного пароля, хранить в куках один хеш, содержащий пароль+логин+некоторые данные+информацию о машине пользователя (с помощью JavaScript можно вытащить разные вещи типа версии браузера, ОС, разрешения экрана и т. д.).

Для повышения надежности — данную исходную строку или хеш (или все вместе) изменять своим алгоритмом. Например, перед получением хеша строку преобразовать в последовательность ASCII кодов, каждый код увеличить на N. N может быть переменной, определяющимся положением символа в исходной строке. Ну и так далее.

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

Кто что скажет? (я не шар в криптографии, просто люблю поразмышлять на досуге — поэтому интересно мнение тех, кто этим действительно занимается)

Илья Бирман

В куки записывается просто N произвольных байт, зачем там вообще хэш чего либо?

Всякие эксперименты с хэшированием при помощи JS я проводил в версиях v1035-v1063, больше не хочу, как-то.

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

(Форум посмотреть всё руки не доходят, но я посмотрю)

misnik 2005

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

Это сработает, если ресурс поддерживает «запоминание пароля» (то есть хеш будет действителен не в течение одной сессии, а до тех пор пока пользователь не выполнит авторизацию или пройдет заданное время и хеш устареет).

Я сейчас рассматриваю общую задачу, а не обеспечение безопасности в блогах и e2 в частности (просто твой пост подталкнул поразмыслить над этим).

Так вот, если мы имеем многопользовательскую систему и хотим сделать «запоминание пароля» (и при этом боимся XSS атак), то один из вариантов заключается в том, чтобы идентифицировать пользователя не только при помощи логина/пароля, но и софта/железа, которое он использует. То есть, когда пользователь авторизовывается, мы смотрим какой софт/железо он использует (здесь нам может помочь JS, поэтому я его упомянул). Эти данные в зашифрованном виде пишутся в куки. Когда пользователь работает, мы проверяем, совпадают ли данные записанные в куки с теми данными, которые имеют место быть на самом деле. Если нет — просим пройти авторизацию. Если пользователь просто зашел на ресурс с другого компьютера или поменял браузар — никаких проблем, ведь он знает пароль. Если кто-то пытается воспользоваться украденым хешем — скорее всего, ничего не получится. Разве что, чисто случайно, он будет использовать такую же конфигурацию, как и жерства.

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

—-

Я как раз вчера узнал, что наиболее распространенные уязвимости в открытых системах (в закрытых их просто сложнее обнаружить «наощупь») — это возможность SQL-инъекций (из-за отсутствия фильтрации входных данных в движке — одна-две дырки есть в практически любой системе) и, на втором месте, возможность проведения XSS атак, позволяющих воровать хеши пользователей в автоматическом режиме. Чтобы от них защититься, также нужно фильтровать входные данные, но процесс уже гемморойнее, чем в случае с SQL, когда достаточно прописать x=addslashes(x); в php. Так что хотелось смириться с возможностью кражи хеша и найти кардинальное решение проблемы.

Илья Бирман

Всё-таки это как-то непредметно. Если «С помощью XSS акати злоумышленник может заполучить хеш», то это уже проблема не хэша — нужно от самой атаки защищаться. Вы видите какую-нибудь XSS-атаку, чтобы достать мой хэш, вот я сейчас залогинен? И потом, есть привязка к IP-адресу, чем она хуже привязки к железу? И ещё я пока не понимаю, почему злоумышленник, имея сколь угодно другое железо, не сможет сделать вид, что у него всё то же самое, что и у жертвы.

Мои книги