Взлом аккаунта и юникодные символы

от автора

В техническом блоге «Спотифая» было опубликовано интересное исследование на тему взлома аккаунтов сервиса путём использования особенностей канонизации вводимых пользователем данных. Это стало возможным благодаря тому, чем спотифаевцы гордятся, — полностью юникодному логину. К примеру, пользователь легко может иметь ☃ в качестве имени аккаунта, если он того пожелает. Реализация подобного, впрочем, с самого начала доставляла некоторые неудобства.

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

Хакер действовал следующим образом: при желании взломать аккаунт с именем, скажем, bigbird, он регистрировал аккаунт с именем ᴮᴵᴳᴮᴵᴿᴰ (в Пайтоне эта строчка выглядит как u’\u1d2e\u1d35\u1d33\u1d2e\u1d35\u1d3f\u1d30′). После запроса ссылки на сброс пароля задавался новый пароль, который подходил к аккаунту bigbird.

Проблема состояла в канонизации имени пользователя, некорректно обрабатывающей запрещенные и эквивалентные символы. Очевидно, что пробелы в имени пользователя недопустимы, а BigBird и bigbird — это одно и то же имя пользователя. Первый случай — это обработка запрещенных символов, второй — обработка некоторых символов как эквивалентных друг другу. Подобное достигается канонизацией имени пользователя.

Если допускаются только символы латинского алфавита (a—z, A—Z), то будет достаточно

canonical_username = username.lower()

Таким образом BigBird, Bigbird, bigbird и любые производные будут одним и тем же логином. BigBird в таком случае называют точным именем пользователя, а bigbird — каноническим. При создании аккаунта необходимо, чтобы канонический логин был свободен в системе.

Обращение в нижний регистр обладает свойством идемпотентности, то есть приложение его к одной и той же строке один и более раз даёт один и тот же результат:

x.lower() == x.lower().lower()

С разрешением юникодных символов начинаются разнообразные проблемы. К примеру, внешне трудно отличить Ω от Ω, хотя первое — буква омега, а второе — символ единицы измерения, и в Юникоде это — различные символы. Очевидно, что просто обращения в нижний регистр было бы недостаточно. К счастью для разработчиков, собственной системы канонизации разрабатывать не пришлось, в фреймворке Twisted были необходимые методы, разработанные ещё для XMPP.

from twisted.words.protocols.jabber.xmpp_stringprep import nodeprep def canonical_username(name):     return nodeprep.prepare(name)

Идемпотентность обещается в спецификациях. Так в чём же дело? Посмотрим, что случается при вводе ᴮᴵᴳᴮᴵᴿᴰ.

>>> canonical_username(u'\u1d2e\u1d35\u1d33\u1d2e\u1d35\u1d3f\u1d30') u'BIGBIRD' >>> canonical_username(canonical_username(u'\u1d2e\u1d35\u1d33\u1d2e\u1d35\u1d3f\u1d30')) u'bigbird'

Как видно, свойство идемпотентности не выполняется для этих символов. Дело в том, что согласно официальной документации учитывались символы Юникода 3.2, в который не входит ни один из символов ᴮᴵᴳᴮᴵᴿᴰ.

Уязвимость сначала была исправлена посредством обязательности выполнения условия X==canonical_username(X). Позже была добавлена функция, которая, по сути, лишь выполняла функцию канонизации и отказывала в регистрации, если old_prepare(old_prepare(name)) != old_prepare(name). Проблема же в Twisted была исправлена в версии 11.0.0, и, как оказалось, баг проявлялся лишь при обновлении версии Пайтона с 2.4 к 2.5, что было вызвано изменениями в стандартной библиотеке.

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

ссылка на оригинал статьи http://habrahabr.ru/post/183878/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *