REST - Как ограничить доступ для неавторизованного клиентского программного обеспечения

вот задача:

Уровень сервиса/бизнес имеет интерфейс REST (JSON). Существует два типа клиентов, которые могут вызывать API: Webapp, который работает в браузере и мобильном приложении (Android). Оба они являются публичными. Каждый, кто пользуется авторизированным (!) Webapp или уполномоченным (!) Мобильным приложением, должен иметь доступ к ресурсам. Все неавторизованные клиенты (например, скрипты) должны быть запрещены.

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

По-моему, единственное решение - "по неизвестности".

Идеи:

  • Загрузите случайную JS-функцию (позвоните ей "вызов" ) с сервера, который выполняется в браузере (или приложении), отпечатки пальца браузера определенным образом (ошибки браузера?), вычисляет результат и отправьте результат с каждым вызовом REST-API.

Есть ли у вас какие-либо дальнейшие идеи или предложения?

Спасибо заранее и извините за мой плохой английский

Изменить:

Мой вопрос не имеет ничего общего с аутентификацией и/или авторизацией пользователя, но клиентское программное обеспечение аутентификация + авторизация.

Фон моего вопроса заключается в том, что для моих собственных приложений (android + web) есть RESTful-back-end, и я не хочу, чтобы кто-то создал собственное клиентское программное обеспечение поверх него. Причина этого заключается в том, что это коммерческий веб-сайт/приложение, которое предоставляет некоторые данные, которые были довольно дорогостоящими для сбора. Я хотел бы продвигать сайт и мобильное приложение, а не RESTapi (или какой-либо сторонний конкурент).

Ответ 1

К сожалению, мой ответ заключается в том, что вы просто не должны доверять клиентским приложениям.

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

Некоторые хорошие примеры таких проблем в отрасли легко видны из таких вещей, как игры, где даже с программами для проверки хакеров и других подходов, в конечном итоге даже службы с огромными бюджетами, такими как World of Warcraft, часто видят либо хаки их клиент или виртуальные клиентские эмуляторы, способные отправлять команды, которые обычный клиент не будет. Опираясь на ваше клиентское программное обеспечение, чтобы оставаться в безопасности, и только когда-либо отправлять надлежащие данные на ваш сервер, это рецепт катастрофы. Всегда проверяйте серверную сторону, если это важно для чего-то важного. Всегда правильно выходить/параметризовать данные. Используйте "белые списки" и предпочтительно используйте поиск таблиц символов на основе пользовательского ввода вместо самих пользовательских данных, где это необходимо. И т.д. Проверка на стороне клиента должна рассматриваться как помощь пользователю, а не как нечто безопасное.

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

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

Существует несколько способов борьбы с нападениями человека в середине (MITM), когда кто-то пытается перехватить данные, но ни один из них не может полностью учитывать уязвимую конечную точку.

Ответ 2

Веб-серверы обычно поддерживают концепцию "сеанса". Когда веб-браузер подключается, на сервере создается сеанс, который возвращает идентификатор сеанса (обычно как файл cookie HTTP). Затем веб-браузер отправляет этот cookie идентификатора сеанса ко всем последующим запросам на сервер.

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

В приложении Android (или iOS...) может быть немного по-другому, но идея схожа: один пользователь аутентифицируется один раз, предоставит клиенту "секретный токен", который отображается на сервере с помощью пользователь запись. Затем этот токен передается для всего запроса, отправленного клиентом.

Вы можете использовать домашнюю библиотеку для этого или более стандартную, например OAuth2.