Как стать автором
Обновить

Комментарии 49

Разработчики деактивирующие буфер обмена для полей с паролями должны гореть в аду.


Разработчики не делающие кнопочку "посмотреть пароль" в принципе не понимают пользователей. И должны быть отправлены в джуниоры.

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

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

Как запрет на вставку из буфера обмена помешает другому приложению его украсть? Уточняю: я уже скопировал пароль, потому что не думал, что кто-то за меня будет решать, как мне хранить мои пароли.

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

Это полностью бесполезное вредительство.

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

Это решается парольной политикой. Например можно исключить ТОП 100к популярных паролей. Плюс заиспользовать что-то вроде zxcvbn от Dropbox.

Вы живете в выдуманном мире.


В реальном будет так:


  1. Пользователи достанут техподдержку вопросами "Я ввожу пароль, в программа его не принимает"
  2. Все поставят пароль из топ10 + 1 в конце чтобы обойти эту самую политику. Причем сделают это по неофициальному совету техподдержки, которую все достало.
  3. При еще более суровой политике паролей у всех будет один пароль подходящий под самую политику. И техподдержка сама его будет советовать.

Жизнь такая. Пользователи такие.

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

Это не спорное, а однозначно вредное действие. Хотим повышенной безопасности используем 2fa, если и так сойдет делаем просто логин-пароль и не паримся. Всякие биометрические авторизации стоят особняком.


Это основы же. Самые. Технические ограничения в паролях только вредят. Запрет просмотра пароля и запрет буфера это одни из самых вредных ограничений. Пользователи их обойдут и пароли будут еще хуже.

Отправка в API пин-кода вместе с RefreshToken, для подтверждения аутентификации и получения новых токенов.

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

1) токен на девайсе без защиты
2) пин хранится где-то на сервере, что подразумевает риск массовой утечки
1) Токен не работает без ПИНа, так же как и зашифрованный.
2) Это можно решить хэшированием.
1) Передача пина сама по себе увеличивает поверхность для атаки. Например, теперь его можно перехватить по сети(см пункт 2)
2) А смысл? Вариантов всего 10к. Это получается, что завладев базой, я могу составить радужную таблицу на 10к вариантов и найти по ней все пины? Даже если будет у каждого своя соль, то это только немного замедлит перебор, тк прийдется для каждого пин-кода строить радужную таблицу.
1) Шифрование же никто не отменял.
2) Хэшировать пин вместе с токеном. Или, как ниже написал ARechitsky, хэшировать можно только токен.
Никто не отменял, ровно так же как и уязвимости в этом шифровании. Как я писал выше, проблема в увеличении поверхности атаки и если мы передаем, храним пин-код, то его можно перехватить, угнать и воспользоваться им при физическом доступе к устройству.
1) Или можно перехватить расшифрованный токен. Пин-код же не от аккаунта, а от конкретного токена. Логин с другого устройства — задайте пин-код.
Я не уверен, что понял мысль, но
Или можно перехватить расшифрованный токен.
если ты воспользуешься перехваченным RefreshToken, то пользователь сразу об этом узнает, тк его разлогинит.
Логин с другого устройства — задайте пин-код.

Если ты можешь перехватывать, то перехватишь и DeviceId и представишься все тем же девайсом.
А где хранится соль и вектор инициализации?

Если они хранятся в оперативной памяти, то это все не имеет смысла, т.к. после перезагрузки он пропадет вместе с AccessToken-ом и мы не сможем расшифровать RefreshToken.

RefreshToken лежит незащищенный в локальном хранилище

А если они хранятся также в «незащищенном хранилище», то получив доступ к девайсу (который вы подразумеваете. Хотя также есть вопрос, как из папки приложения малварь может извлечь данные не на рутовых девайсах), то останется перебрать лишь 4-6 значное числовое значения пина.
Рядом с зашифрованным RefreshToken. Они могут храниться где угодно в открытом виде, тк не являются секретами.

то останется перебрать лишь 4-6 значное числовое значения пина.
В этом и смысл статьи, что перебрать не получится. Нет никаких данных, по которым можнно определить верный это RefreshToken или нет. Можно узнать только отправив его в API, а там лимит на 3 попытки и инвалидация всех токенов.
А как происходит матчинг пользователя и его RefreshToken-a?

AccessToken + RefreshToken, RefreshToken + DeviceID?

Из статьи непонятно о каком протоколе речь — OAuth или какой-то кастомный протокол авторизации.
По спеке OAuth 2.0
К чему привязан лимит? В API приходит 3 разных refreshToken'а, как апи узнает, что это — 3 попытки расшифровки одного зашифрованного? Отдельный DeviceID/SessionID?
НЛО прилетело и опубликовало эту надпись здесь
Спасибо за замечания!..)
А откуда берется пин для расшифровки токена? При каждом старте пользователь вводит?
Да.
Такое
Все лучше, чем логин+пароль вводить каждый раз.
Объясните, пожалуйста:
1. Чем грозит утекший refreshToken? Когда Ева попытается обменять его с пин-кодом на accessToken, я его отзову после третьей неудачной попытки…
2. Как шифрование защитит вас от массовой утечки? Если у вас в БД лежат сырые токены — то при утечке Ева будет отправлять «расшифрованный» токен не зная пин-кода.

Если же вы в БД храните не токены, а хеши от них, то и пин-коды на сервере Еве ничего не дадут — она узнает пин-код и хеш-код токена, но не сам токен!

Если у Евы есть одновременно сохраненные данные с клиента и дамп БД, то этого клиента уже не защитить ни при каком сценарии. Ева просто переберет пин-коды и для каждого смоделирует: если использовать эти сохраненные данные (неважно, зашифрованный токен или сырой) с этим пин-кодом — ответит ли сервер положительно.
Отвечаю сразу на оба пункта. Сам по себе утекший токен ничем не грозит, просто этот вариант реализации предполагает, что пин будет передаваться и храниться. Это открывает еще 1 поверхность для атаки, которая предполагает стилл пин-кода и ввод его на физическом устройстве(без доступа к данным). В описанном варианте невозможно извлечь ни токен ни пинкод. По-этому я и посчитал, что он немного лучше.
Действительно, этот вектор я не предусмотрел, спасибо. Но криптография на сервере нас спасет: храним в БД хеш от токена и хеш от пары токен+пин-код. При утечке БД Ева не сможет определить пин-код — исходного токена у нее не будет, перебирать нечего.

Вариант с проверкой на сервере позволяет гораздо более обширный функционал; например, безопасное изменение пин-кода и разблокировку паролем от аккаунта (если забыл/не захотел задавать пин-код).

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

пин можно и в моем варианте изменить

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

А в моем варианте логин вводить не надо)

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

Называть отправку пин-кода в апи ошибкой — ошибка. Это приемлимо и даже дает преимущества.

Только сейчас понял, что refreshToken у вас одноразовый, надо подумать)

Да, наверное нужно было это явно обозначить, но это не у меня, это по гайдам так.
Где гайды можно почитать? Вы в комментариях ссылаетесь на OAuth2, но оно во-первых трехстороннее, а во-вторых refreshToken там многоразовый. А у вас уже не refreshToken получается, а nonce какой-то.
а во-вторых refreshToken там многоразовый
Не совсем, там в RFC написано, что метод обновления токенов опционально может возвращать RefreshToken, это предполагает, что он может быть одноразовым. А конкретные рекомендации можно найти по ссылкам — раз, два
Так у вас вообще расшифрованный токен по сети идет, бери и повторяй запрос.
Так не получится повторить, потому что токен уже не валиден. А в вашем варианте можно узнать пин по сети и вести его вручную.
А в моем варианте логин вводить не надо)
Это детали реализации, можно сделать сохранение логина и тоже не нужно будет вводить.
Нет таких векторов атаки, где ваш вариант устоит, а мой — нет.
Это не правда, если подумать шире. При передачи и хранении открывается большое количество векторов и возможностей где можно облажаться. Например, http клиент может закэшировать запрос в котором присутствует пин => при доступе к устройству будет и токен и пин. И таких возможностей открывается вагон. Главное понять, что в вашем варианте в бОльших системах фигуририует пин => его бОльших местах нужно защищать => больше вариантов налажать.
Нет таких векторов атаки, где ваш вариант устоит, а мой — нет

Я отталкивался от того что у вас refreshToken — многоразовый. Если одноразовый — пин-код в открытом виде действительно снижает безопасность.

Не отправлять токены гет, а отправлять пост. Не отправлять что-то там вместе с чем-то там. Автор ты серьезно? Если Ева слушает канал то не важно что и как отправляется. Если не слушает, то отправляй что как удобно.


Всю часть про сетевое взаимодействие надо заменить на большую красную надпись "ПРОВЕРЯЙТЕ СЕРТИФИКАТ СЕРВЕРА. ХОРОШО ПРОВЕРЯЙТЕ" ну и текст о том как его надо проверять. Этого многие не знают. Ну и заодно радом написать совет проверять подлинность сервера. Подменить днс элементарно. И аналогично текст о том как надо проверять.


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

Не отправлять токены гет, а отправлять пост. Не отправлять что-то там вместе с чем-то там. Автор ты серьезно? Если Ева слушает канал то не важно что и как отправляется. Если не слушает, то отправляй что как удобно.

Я не зря оставил ссылку в посте на CWE. С этой уязвимостью ты сколько угодно можешь проверять сертификаты, только это не поможет.
ПРОВЕРЯЙТЕ СЕРТИФИКАТ СЕРВЕРА. ХОРОШО ПРОВЕРЯЙТЕ

Основной посыл статьи не про сеть, а про хранение.
Итого статья безграмотна

Учитывая предложения выше, мне сложно сказать кто/что тут безграмотная.

И как вы оцениваете вероятность атаки на ваш сервис по этому вектору? Я бы оценил вероятность этого меньше чем вероятность компрометации приватного ключа сертификата. И соответсвенно пренебрег бы ей.


Безопасность это комплексное понятие. Нельзя заниматься одним и игнорировать второе. Это просто не имеет смысла. Если проигнорирован один важный фактор, то все остальное что вы сделали не имеет никакого смысла. Важный фактор — верификация сертификата вы проигнорировали. Остальная безопасность без валидации сертификата не имеет смысла. Вас сломают простейшим митм.

Да с чего вы взяли, что этим можно пренебречь? Вы же сами пишите
Нельзя заниматься одним и игнорировать второе.
И предлагаете пренебречь? Вы сами себе противоречите в рамках одного сообщения.
И никто не игнорировал фактор проверки сертификата, это обязательно делается, но скажу еще раз, статья не об этом.
Вы пишете про сетевое взаимодействие. Мол то-то использовать то-то не использовать. То-то с тем-то посылать с тем-то не посылать. При этом вы упускаете важнейшую часть организации сетевого взаимодействия. Без которой все остальное становится бесполезным, а скорее даже вредным. Потому что оно даст иллюзию безопасности.
Я не писал ничего про сетевое взаимодействие. Передача в Query относится к непреднамеренным утечкам данных, что напрямую связанно с хранением.
Некоторые рекомендации я нахожу излишними для массмаркета. Разве что для банк клиента. Ну какой пин при запуске? Все пользователей енгеджат всеми силами, а вы предлагаете им пин вводить при запуске.
Но в целом — хорошая обзорная статья которую хорошо иметь под рукой.
Спасибо
Конечно, не стоит это делать для каждого приложения. Сначала стоит определить уровень критичности приложения, например по MASVS, а потом уже заниматься такими вещами.

Спасибо за комментарий.
НЛО прилетело и опубликовало эту надпись здесь
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации