Pull to refresh

Уязвимость Account Manager в Android, о которой необходимо знать

Reading time 3 min
Views 20K
Приветствую тебя, дорогой читатель! Многие разработчики используют возможности Account Manager(AM) в своих приложениях. И правильно делают, ведь этот инструмент позволяет упростить некоторые вещи. Он позволяет хранить пароль, токен, да и в принципе любые строковые данные юзера. Так же позволяет автоматически обновлять токен, если тот протухает, и много других полезных штук. Но у этого удобства есть и другая сторона — безопасность. Из-за этого собственно я и написал данный текст.

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

Вообще для работы с AM в приложении нужно сделать несколько телодвижений и создать два компонента — наследника AbstractAccountAuthenticator и Service (подробней тут). Последний придется зарегистрировать в манифесте приложения таким образом:

        <service
            android:name=".account.AuthenticatorService"
            android:exported="false">
            <intent-filter>
                <action android:name="android.accounts.AccountAuthenticator" />
            </intent-filter>

            <meta-data
                android:name="android.accounts.AccountAuthenticator"
                android:resource="@xml/authenticator" />
        </service>

А еще, если вы заметили, то нам надо создать в ресурсах некий xml-файл с именем authenticator.xml. Хотя название тут не важно, а важно содержимое. Оно то и играет ключевую роль рассказа. Выглядит файл внутри вот так:

<account-authenticator 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:accountType="@string/account_type"
    android:label="@string/app_name" />

Параметр label — отвечает за название в списке аккаунтов в настройках девайса, а самое интересно несет в себе accountType. Без него приложение не сможет добавлять и получать аккаунты. А еще с помощью этого параметра можно перехватить аккаунты другого приложения даже на девайсах без рута. Давайте посмотрим, как это может произойти.

На устройстве существует приложение А с accountType = «someType», это приложение создает акаунт, добавляет в него токен, пароль и прочую информацию. В один прекрасный момент на устройство устанавливается приложение B с таким же accountType = «someType». И вот если удалить приложение A, то все созданные аккаунты перейдут во власть приложения B с полным доступом. Обратное тоже верно, аккаунты приложения B передадутся приложению A, если удалить B.

Пример на видео:


Опережая вопросы про подписи apk, это не зависит от того, каким ключом было подписано приложение, релизным или дебажным, передача произойдет в любом случае. Ужасно, правда?

Все это можно проделать в плоть до API версии 23. Исправлено только с выходом андроид 7.0(API 24). Печалит в этой ситуации ничтожно малый процент устройств с этой версией андроида. Кстати, узнал я об этой проблеме из доклада по безопасности в андроид. К сожалению в тексте, пересказе презентации, об этом ничего нет вообще, а вот в видео об этом упомянули вскользь, не придав особого значения.

Так же что же ты предлагаешь? — можете спросить вы. А я предлагаю вам два варианта решения проблемы. Первый — продолжать пользоваться AM, но хранить в нем все важные данные в зашифрованном виде. Если вы перестали доверять AM, можно продолжать им пользоваться, но не хранить в нем важные данные и воспользоваться AM в связке со вторым вариантом. Второй — вообще отказаться от AM и пользоваться хранилищем, которое можно шифровать. Например SQLite в связке с sqlcipher или Realm, который поддерживает шифрование из коробки. Я выбрал последний. Тут пример для realm, где показано, как генерировать и хранить ключ шифрования.

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

Спасибо за внимание!
Tags:
Hubs:
+24
Comments 5
Comments Comments 5

Articles