security - это - jwt принцип работы




Лучшие практики SPA для аутентификации и управления сеансами (2)

Вы можете повысить безопасность в процессе аутентификации с помощью JWT (JSON Web Tokens) и SSL / HTTPS.

Идентификатор Basic Auth / Session можно украсть через:

  • Атака MITM (Man-In-The-Middle) - без SSL / HTTPS
  • Злоумышленник получает доступ к компьютеру пользователя
  • XSS

Используя JWT, вы шифруете данные аутентификации пользователя и сохраняете их на клиенте и отправляете вместе с каждым запросом API, где сервер / API проверяет токен. Он не может быть расшифрован / прочитан без закрытого ключа (который хранится в сервере / API). Прочитайте обновление .

Новый (более безопасный) поток будет:

Авторизоваться

  • Пользователь регистрируется и отправляет учетные данные для входа в API (через SSL / HTTPS)
  • API получает учетные данные
  • Если это действительно:
    • Зарегистрировать новый сеанс в базе данных
    • Шифровать идентификатор пользователя, идентификатор сеанса, IP-адрес, временную метку и т. Д. В JWT с закрытым ключом.
  • API отправляет маркер JWT обратно клиенту (через SSL / HTTPS)
  • Клиент получает токен JWT и хранит в localStorage / cookie

Каждый запрос API

  • Пользователь отправляет HTTP-запрос в API (через SSL / HTTPS) с сохраненным токеном JWT в HTTP-заголовке
  • API читает HTTP-заголовок и расшифровывает токен JWT с его закрытым ключом
  • API проверяет токен JWT, соответствует IP-адресу из HTTP-запроса с таковым в токере JWT и проверяет, закончился ли сеанс
  • Если это действительно:
    • Обратный ответ с запрошенным контентом
  • Если это недействительно:
    • Выбросить исключение (403/401)
    • Инфляция флага в системе
    • Отправьте электронное письмо пользователю.

Обновлено 30.07.15:

Полезная нагрузка / претензии JWT действительно может быть прочитана без секретного ключа (секретная), и ее небезопасно хранить в localStorage. Прошу прощения за эти ложные заявления. Однако они, похоже, работают над стандартом JWE (JSON Web Encryption) .

Я реализовал это, сохранив заявки (userID, exp) в JWT, подписал его с закрытым ключом (секретным), который API / Бэкэнд знает и хранит в качестве защищенного файла cookie HttpOnly на клиенте. Таким образом, он не может быть прочитан с помощью XSS и не может быть обработан, иначе JWT не сможет проверить подпись. Кроме того, используя безопасный файл cookie HttpOnly , вы убедитесь, что cookie отправляется только через HTTP-запросы (недоступные для скрипта) и отправляется только через безопасное соединение (HTTPS).

Обновлено 17.07.16:

JWT по своей природе являются лицами без гражданства. Это означает, что они недействительны / истекают. Добавляя SessionID в утверждениях токена, вы делаете его с сохранением состояния, поскольку его действительность теперь не зависит только от проверки подписи и даты истечения срока действия, это также зависит от состояния сеанса на сервере. Однако потенциал роста - это то, что вы можете легко лишить токенов / сеансов, чего вы не могли бы сделать с помощью JVT без гражданства.

При создании приложений стиля SPA с использованием таких рамок, как Angular, Ember, React и т. Д., Что люди считают лучшими методами аутентификации и управления сеансами? Я могу придумать пару способов рассмотрения проблемы.

  1. Относитесь к нему не иначе, как к аутентификации с помощью обычного веб-приложения, предполагая, что API и UI имеют один и тот же исходный домен.

    Вероятно, это связано с наличием сеансового файла cookie, хранилища сеансов на стороне сервера и, возможно, некоторой конечной точки сеанса API, с которой может пройти аутентифицированный веб-интерфейс, чтобы получить текущую пользовательскую информацию, чтобы помочь в персонализации или, возможно, даже определить роли / возможности на стороне клиента. Сервер по-прежнему будет применять правила защиты доступа к данным, конечно, пользовательский интерфейс будет использовать эту информацию только для настройки опыта.

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

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


Этот вопрос был рассмотрен в несколько иной форме, подробно:

Аутентификация RESTful

Но это относится к серверу. Давайте посмотрим на это с клиентской стороны. Прежде чем мы это сделаем, есть важная прелюдия:

Javascript Crypto - беззастенчивый

Статья Матасано об этом известна, но уроки, содержащиеся в ней, очень важны:

http://www.matasano.com/articles/javascript-cryptography/

Подвести итоги:

  • Атака «человек-в-середине» может тривиально заменить ваш <script> function hash_algorithm(password){ lol_nope_send_it_to_me_instead(password); }</script> <script> function hash_algorithm(password){ lol_nope_send_it_to_me_instead(password); }</script>
  • Атака «человек в середине» тривиально против страницы, которая обслуживает любой ресурс по не-SSL-соединению.
  • Как только у вас есть SSL, вы все равно используете реальный крипто.

И добавить свое собственное следствие:

  • Успешная атака XSS может привести к тому, что злоумышленник выполнит код в браузере вашего клиента, даже если вы используете SSL - так что, даже если у вас есть каждый люк, то ваш криптографический код браузера все равно может выйти из строя, если ваш злоумышленник найдет способ выполнить любой код javascript в чужом браузере.

Это делает невозможным или глупым многие схемы аутентификации RESTful, если вы собираетесь использовать клиент JavaScript. Давайте смотреть!

HTTP Basic Auth

Прежде всего, HTTP Basic Auth. Простейшая схема: просто передайте имя и пароль с каждым запросом.

Это, конечно, абсолютно требует SSL, потому что вы передаете Base64 (обратимо) кодированное имя и пароль с каждым запросом. Любой, кто прослушивает эту строку, может извлекать имя пользователя и пароль тривиально. Большинство аргументов «Basic Auth is insecure» исходят из места «Basic Auth over HTTP», что является ужасной идеей.

В браузере предусмотрена поддержка HTTP Basic Auth, но она уродлива, как грех, и вы, вероятно, не должны использовать ее для своего приложения. Альтернативой, однако, является спрятать имя пользователя и пароль в JavaScript.

Это самое RESTful решение. Сервер не требует каких-либо знаний о состоянии и аутентифицирует каждое индивидуальное взаимодействие с пользователем. Некоторые энтузиасты REST (в основном, соломенные) настаивают на том, что поддержание любого состояния является ересью и будет пениться во рту, если вы думаете о каком-либо другом методе проверки подлинности. Существуют теоретические преимущества для такого соответствия стандартам - он поддерживается Apache из коробки - вы можете хранить ваши объекты в виде файлов в папках, защищенных файлами .htaccess, если вам угодно!

Проблема ? Вы используете на стороне клиента имя пользователя и пароль. Это дает evil.ru лучший треск на нем - даже самые простые из уязвимостей XSS могут привести к тому, что клиент будет бить свое имя пользователя и пароль злому серверу. Вы можете попытаться смягчить этот риск, хешируя и засовывая пароль, но помните: JavaScript Crypto является беззаботным . Вы могли бы смягчить этот риск, оставив его до базовой поддержки браузера, но ... уродливым, как грех, как упоминалось ранее.

HTTP Digest Auth

Возможно ли аутентификация дайджеста с помощью jQuery?

Более «безопасный» auth, это запрос хеша запроса / ответа. За исключением JavaScript Crypto является Hopeless , поэтому он работает только через SSL, и вы все равно должны кэшировать имя пользователя и пароль на стороне клиента, что делает его более сложным, чем HTTP Basic Auth, но не более безопасным .

Аутентификация запроса с дополнительными параметрами подписи.

Еще один «безопасный» auth, где вы шифруете свои параметры с помощью данных nonce и time (для защиты от повторных и временных атак) и отправки. Одним из лучших примеров этого является протокол OAuth 1.0, который, насколько мне известно, является довольно сложным способом реализации проверки подлинности на сервере REST.

http://tools.ietf.org/html/rfc5849

О, но нет клиентов OAuth 1.0 для JavaScript. Зачем?

Помните, что JavaScript Crypto является Безнадежным . JavaScript не может участвовать в OAuth 1.0 без SSL, и вам все равно нужно локально хранить имя пользователя и пароль клиента, что ставит его в ту же категорию, что и Digest Auth, - это сложнее, чем HTTP Basic Auth, но он не более безопасен .

знак

Пользователь отправляет имя пользователя и пароль, а взамен получает токен, который может использоваться для аутентификации запросов.

Это немного более безопасно, чем HTTP Basic Auth, поскольку, как только транзакция имени пользователя / пароля будет завершена, вы можете отбросить конфиденциальные данные. Это также меньше RESTful, поскольку токены составляют «состояние» и усложняют реализацию сервера.

SSL еще

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

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

Срок действия токена

Обычно применяются политики маркеров, такие как «эй, когда этот токен слишком длинный, отбросьте его и повторите проверку подлинности пользователя». или «Я уверен, что единственным IP-адресом, разрешенным для использования этого токена, является XXX.XXX.XXX.XXX ». Многие из этих политик являются довольно хорошими идеями.

Firesheeping

Однако использование токена без SSL по-прежнему уязвим для атаки под названием «sidejacking»: http://codebutler.github.io/firesheep/

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

tl; dr: Отправка незашифрованных токенов по проводу означает, что злоумышленники могут легко набить эти жетоны и притворяться вашим пользователем. FireSheep - это программа, которая делает это очень просто.

Отдельная, более безопасная зона

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

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

Cookie (просто означает токен)

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

Сессия (еще только означает токен)

Session Auth - это только аутентификация Token, но с несколькими отличиями, которые делают это несколько иначе:

  • Пользователи начинают с неавторизованного токена.
  • Бэкэнд поддерживает объект состояния, привязанный к токену пользователя.
  • Токен предоставляется в файле cookie.
  • Среда приложения абстрагирует детали от вас.

Помимо этого, однако, это ничем не отличается от Token Auth.

Это еще больше удаляется от реализации RESTful - с объектами состояния, которые вы продвигаете дальше и дальше по пути простого RPC на сервере с сохранением состояния.

OAuth 2.0

В OAuth 2.0 рассматривается проблема «Как программное обеспечение A предоставляет ПО B доступ к данным пользователя X без программного обеспечения B, имеющего доступ к учетным данным пользователя X».

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

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

OAuth 2.0 может помочь вам двумя способами:

  • Предоставление аутентификации / информации другим пользователям
  • Получение аутентификации / информации от других пользователей

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

Вернуться к вашему вопросу

Таким образом, вопрос, который вы задаете, - «должен ли я хранить токен в файле cookie и настроить автоматическое управление сеансом моей среды на детали, или я должен хранить свой токен в Javascript и сам обрабатывать эти данные?»

И ответ: делайте то, что делает вас счастливыми .

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

Мне 21, поэтому SSL да

Другой ответ: используйте https для всего, или разбойники украдут пароли и токены ваших пользователей.





single-page-application