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

Вот задача:

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

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

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

Идеи:

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

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

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

Редактировать:

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

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

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

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

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

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

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

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

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

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

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

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