Подтвердить что ты не робот

Защищенный RESTful API, который может использоваться веб-приложением (angular), iOS и Android

Я должен разработать план разработки RESTful API (Python/Flask), который может использоваться нашим будущим веб-приложением (Angularjs) и мобильными приложениями (iOS/Android).

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

  • Использование Basic-Http-Auth и отправка имени пользователя/пароля в обычном (но https) канале для каждого запроса API.
  • Использование Digest-Auth, который является хешем пароля, и отслеживание будет автоматическим. Это будет работать для веб-приложения, однако я не смог подтвердить, поддерживает ли iPhone и Android это. Если они это сделают, это может быть простым решением!
  • Использование пользовательского HTTP-заголовка, в котором я бы отправил пользовательскую строку Auth в заголовке http при успешной аутентификации. Но тогда я должен убедиться, что я отправляю этот код auth для каждого запроса, который пользователь делает. Это делает его точно так же, как 1) с той разницей, что простые пароли не используются, и код auth может истекать без какого-либо риска. Также проблематично отслеживание кода auth, который больше не автоматизирован, как в 2)
  • Использование OAuth - это вариант. Но его довольно сложно настроить. Если нет лучшего способа, возможно, это единственный способ?
  • Защита API как Amazon S3, как описано в этой отличной статье. Короче говоря, он говорит, что и сервер, и клиент будут знать секретный ключ, который они будут использовать для хэширования связи. Это будет похоже на рукопожатие гангстеров, что вы только доверяете мальчике доставки, если он знает рукопожатие гангста. Далее по комментариям кто-то спрашивает:

Как сохранить секретный ключ в безопасном приложении HTML5?

Вы совершенно правы; в чистом HTML5 (JS/CSS/HTML) приложении, нет защиты ключа. Вы будете общаться HTTPS, в этом случае вам не понадобится ключ, так как вы можете безопасно идентифицировать клиента с использованием стандартного API_KEY или другого дружественного идентификатор без необходимости или сложности HMAC.

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

Чем больше я исследую, тем более нерешительным я получаю.

Я надеялся спросить некоторых профессионалов, которые сделали это раньше и могли поделиться своим опытом. Большое спасибо

4b9b3361

Ответ 1

Кажется, вы смешиваете/объединяете два разных понятия вместе. Мы начинаем говорить об шифровании трафика (HTTPS), а затем начинаем говорить о разных способах управления аутентифицированными сеансами. В защищенном приложении это не взаимоисключающие задачи. Вероятно, также возникает недоразумение, как управление сеансом может повлиять на проверку подлинности. Основываясь на этом, я предоставил праймер для управления сеансом веб-приложений/веб-api, проверки подлинности и шифрования.

Введение

Управление сеансами

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

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

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

Каждый HTTP-запрос от клиента должен включать идентификатор сеанса; это можно сделать разными способами. Популярные примеры:

  • Он может храниться в файле cookie - файлы cookie для текущего домена автоматически отправляются по каждому запросу.
  • Он может быть отправлен по URL-адресу: каждый запрос может отправить идентификатор сеанса в URL-адрес, а не предлагать, поскольку идентификаторы сеансов будут оставаться в истории клиентов
  • Он может быть отправлен через HTTP-заголовок - каждый запрос должен будет указать заголовок

В большинстве рамок веб-приложений используются файлы cookie. Однако приложение, основанное на JavaScript и одностраничных проектах, может использовать HTTP-заголовок/хранить его в другом месте, которое можно наблюдать сервером.

Очень важно помнить, что HTTP-ответ, который уведомляет клиента о своем идентификаторе сеанса и клиентских запросах, содержащих идентификатор сеанса, является полностью открытым текстом и на 100% небезопасным. Чтобы бороться с этим, весь HTTP-трафик должен быть зашифрован; где находится HTTPS.

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

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

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

Пользователь в свою очередь связан с привилегиями для мелкозернистого контроля доступа через списки управления доступом и записи контроля доступа (ACL и ACE). Обычно это называется "Авторизация". В большинстве систем всегда есть как аутентификация, так и авторизация. В некоторых простых системах все аутентифицированные пользователи равны, и в этом случае у вас не будет авторизации после простой аутентификации. Дополнительная информация об этом не подходит для этого вопроса, но подумайте о ACE/ACL.

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

  • Данные их хранимой серверной информации могут хранить свой идентификатор пользователя/другой флаг, который означает, что использование аутентифицируется как конкретный пользователь
  • Другой токен пользователя может быть отправлен клиенту точно так же, как идентификатор сеанса (который по незашифрованному HTTP так же небезопасен, как отправка идентификатора сеанса, незашифрованного).

Любая опция в порядке. Обычно это сводится к технологии, над которой вы работаете, и к тем, что они предлагают по умолчанию.

Клиент обычно инициирует процесс аутентификации. Это можно сделать, отправив учетные данные на определенный URL-адрес (например, yoursite.com/api/login). Однако, если мы хотим быть "RESTful", мы обычно ссылаемся на ресурс некоторым существительным и делаем действие "create". Это можно сделать, потребовав POST учетных данных для вашего сайта /api/authenticatedSession/. Там, где идея заключалась бы в создании аутентифицированного сеанса. Большинство сайтов просто добавляют POST учетные данные в /api/login или тому подобное. Это отход от "истинных" или "чистых" идеалов RESTful, но большинство людей считают это более простой концепцией, а не думать о ней как о "создании аутентифицированной сессии".

Шифрование

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

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

Один из способов борьбы с этим - связать запросы удаленного IP-адреса с аутентифицированным сеансом. Это неэффективно, так как любой хакер сможет обманывать свои запросы удаленным IP-адресом в своих поддельных запросах, а затем наблюдать за ответами, которые ваш сервер отправляет обратно. Большинство утверждают, что это даже не стоит реализовывать, если вы не отслеживаете исторические данные и не используете их для идентификации конкретных шаблонов входа пользователя (например, Google).

Если вам нужно разделить ваш сайт между разделами HTTP и HTTPS, обязательно, чтобы HTTP-трафик не отправлял или не получал идентификатор сеанса или любой токен, используемый для управления статусом аутентификации пользователя. Также важно, чтобы вы не отправляли конфиденциальные данные приложения в запросы и ответы без HTTP.

Единственный способ защитить данные в веб-приложениях/API-интерфейсах - это зашифровать ваш трафик.

Темы по одному

Basic-Http-Auth

  • Аутентификация: ДА
  • Управление сеансом: НЕТ
  • Шифрование: НЕТ

Это метод аутентификации только через веб-ресурс. Базовая аутентификация проверяет использование ресурсов по URL-адресу. Это было наиболее широко реализовано Apache HTTP Web Server с использованием .htaccess на основе аутентификации на основе каталога/местоположения. Учетные данные должны отправляться с каждым запросом; клиенты обычно обрабатывали это прозрачно для пользователей.

Базовая аутентификация может использоваться другими системами в качестве режима аутентификации. Однако системы, использующие Basic-Http-Auth, обеспечивают аутентификацию и управление сеансом, а не сам Basic-Http-Auth.

  • Это не управление сеансом.
  • Это не шифрование; содержание и учетные данные составляют почти 100% обычного текста.
  • Это не защищает содержимое HTTP-запроса/ответов приложения.

Дайджест-Авт

  • Аутентификация: ДА
  • Управление сеансом: НЕТ
  • Шифрование: НЕТ

Это точно так же, как Basic-Http-Auth с добавлением некоторого простого переваривания MD5. На это переваривание не следует полагаться, вместо того, чтобы использовать шифрование.

  • Это не управление сеансом.
  • Это не шифрование; дайджест легко сломается
  • Это не защищает содержимое HTTP-запроса/ответов приложения.

OAuth

  • Аутентификация: ДА
  • Управление сеансом: НЕТ
  • Шифрование: НЕТ

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

  • Это не управление сеансом.
  • Это не шифрование; ваш трафик сайтов по-прежнему остается простым текстом. Процесс аутентификации будет защищен из-за ограничений HTTPS, но ваше приложение по-прежнему уязвимо.
  • Это не защищает содержимое HTTP-запроса/ответов приложения.

Рукопожатие Gangster/ Пользовательский заголовок HTTP

  • Аутентификация: ДА, потенциально
  • Управление сеансом: ДА, потенциально
  • Шифрование: НЕТ

"Пользовательский HTTP-заголовок" - это тип "Рукопожатия гангстеров"; поэтому я буду использовать тот же раздел, чтобы обсудить их. Единственное различие заключается в том, что "Пользовательский HTTP-заголовок" указывает, где будет храниться hanshake (идентификатор сеанса, токен, аутентификация пользователя toke и т.д.) (Т. Е. В заголовке HTTP).

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

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

  • Это не шифрование; ваш трафик сайтов по-прежнему остается простым текстом. Процесс аутентификации будет защищен из-за ограничений HTTPS, если вы используете OAuth, но ваше приложение по-прежнему уязвимо.
  • Это не защищает содержимое HTTP-запроса/ответов приложения.

Что вам нужно сделать

... Я настоятельно рекомендую вам убедиться, что вы понимаете, что надежное безопасное веб-приложение нуждается в следующем:

  • Шифрование (HTTPS - это ваш единственный выбор)
  • Управление сеансами
  • Аутентификация/авторизация

Авторизация основана на проверке подлинности. Аутентификация зависит от управления сеансом и шифрования, поэтому сеанс не захвачен и что учетные данные не перехватываются.

Колба-Войти

Я думаю, вы должны изучить flask-login как способ избежать повторного внедрения колеса. Я лично никогда не использовал его (я использую пирамиду для веб-приложений в python). Тем не менее, я уже упоминал об этом ранее в советах веб-приложений/python. Он обрабатывает как проверку подлинности, так и управление сеансом. Бросьте свой веб-api/приложение через HTTPS, и у вас есть все три (шифрование, сеансовое управление и аутентификация пользователей).

Если вы не используете/не можете использовать флажок-логин, будьте готовы написать свой собственный, но сначала сделайте исследование о том, как создавать механизмы безопасной аутентификации.

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

Пожалуйста, зашифруйте свой трафик

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

Ответ 2

https медленнее, но не является. Только квитирование уже медленнее. Для нас самой большой проблемой является поддержка пары ключей на стороне сервера и мобильных телефонов. Мы также внедрили дайджест сообщений. Проблема заключается в том, что сложно правильно настроить версию php-android-ios. После этого (параметр должен изменить то, что предлагает Google с первых результатов только на стороне android) проблема будет связана с устройствами младшего класса: с большим использованием процессора, медленным процессом расшифровки шифрования, намного медленнее, чем https, особенно когда вам нужно преобразовать строку 10kb (может занять несколько минут).

Если я не передам данные НАСА в ХАМАС, я бы пошел с очень простым шифрованием по простому HTTP: вроде бы инвертировал бит или так...

Ответ 3

Перейдите с помощью HTTPS. Это (незначительно) медленнее, но безопасность, которую вы получаете от него за относительно короткое время инвестиций (покупка сертификата SSL и просто изменение URL-адресов с http на https), стоит того. Без HTTPS вы рискуете получить доступ к вашим сеансам пользователей в незащищенных общедоступных сетях, что очень удобно для для кого-то.