Top.Mail.Ru
Рекомендации по безопасной интеграции через API | VK ID - сервис авторизации
VK ID auth service logo

Рекомендации по безопасной интеграции через API

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

Web (User agent)

По градации защищенности варианты хранения токенов можно отсортировать следующим образом: (наименее безопасный) Local Storage, Indexed DBSession StorageVariablesWeb WorkerService Worker → (самый безопасный) Cookies
СпособОписание
Local Storage, Indexed DBНаименее безопасный способ. Уязвим к XSS (Cross-Site Scripting), реализовать атаку легко. Хранилище персистентное, значения токенов будут храниться пока JS не удалит записи из хранилища
Session storageНебезопасный способ. Реализовать CSRF/XSS-атаку сложнее из-за привязки к времени жизни открытой вкладки. Хранилище не персистентное, поэтому при следующем открытии приложения необходимо обращаться к OAuth заново
VariablesХранение в переменных кода более безопасно, однако узявимость сохраняется: обнаружение необходимой переменной злоумышленником возможно. Хранилище не персистентное
Web WorkerИспользует скрипты общего назначения, поэтому сохраняется уязвимость на уровне JS. Хранилище не персистентное
Service WorkerБезопаснее, чем Local Storage, Indexed DB, Session storage, так как нельзя скомпрометировать токены через XSS/CSRF-атаку. Токены хранятся на уровне переменных в коде Service Worker, значения подставляются в веб-хуках Request/Response. Хранилище не персистентное
CookiesС флагами HttpOnly, Secure, SameSite=Strict на уровне OAuth Proxy, реализующего логику взаимодействия с Resource и Authentication Server провайдера OAuth, хранение персистентно. Ещё более безопасным вариантом будет хранение значений токенов на стороне Proxy, а в User-Agent выдавать Cookies OAuth-сессии с теми же флагами
Для Web Single-Page Application возможен любой вариант хранения токенов. Для Web Multi-Page Application подходят все варианты, кроме Variables. В случае Service Worker возможность хранения определяется правами доступа (scope). Cookies необходимо устанавливать на Path, который реализует взаимодействие с OAuth Proxy. Если вы используете приложение без Backend, рекомендуем уменьшать срок жизни токенов, например уменшить срок жизни Refresh token до суток.

Android

Access token рекомендуется хранить в оперативной памяти. Для Refresh token возможны два варианта:
  • Encrypted Shared Preferences;
  • Shared Preferences с MODE_PRIVATE. Дополнительно рекомендуем создать в Keystore ключ симметричного шифрования. Рекомендуемый алгоритм шифрования — AES_256_GCM.
Если поддерживается ОС-аутентификация пользователя, например у пользователя установлен экран блокировки, который разблокируется через ПИН, биометрию, на этапе создания ключа рекомендуется дополнительно вызвать методы Builder:
  • setUserAuthenticationRequired(true);
  • setUserAuthenticationValidityDurationSeconds(-1);
  • setInvalidatedByBiometricEnrollment(true).
После пользовательской аутентификации значение Refresh token можно хранить в оперативной памяти приложения. Также можно предусмотреть дополнительный уровень защиты с сохранением ключа в Strongbox — метод Builder.isStongBoxBacked(true); Если нет строгой необходимости в фоновой активности с ключевой информацией, то вызвать метод Builder.isUnlockedDeviceRequired(true).

iOS

Access token рекомендуется хранить в оперативной памяти. Refresh token рекомендуется сохранять в Keychain с флагами. По умолчанию используется WhenUnlockedThisDeviceOnly. Если приложению необходима фоновая активность с OAuth-токенами, то лучше использовать AfterFirstUnlockThisDeviceOnly. Если приложение работает только на устройствах, где обязательно должен быть установлен экран блокировки, — WhenPasscodeSetThisDeviceOnly. Если для входа в приложение требуется аутентификация пользователя по FaceID или TouchID, то рекомендуется установить дополнительный флаг biometryCurrentSet и извлекать значение Refresh token в ОЗУ после пользовательской аутентификации.

Backend

Рекомендуется ассоциировать пару токенов с конкретной сессией пользователя. Сохранять токены лучше в зашифрованном виде в базе данных. После завершения сессии пользователя необходимо инвалидировать токены и очищать записи в базе данных.