Shouldn't Android AccountManager Store OAuth Tokens on a Per-App/UID Basis?

前端 未结 4 782
既然无缘
既然无缘 2021-01-29 19:18

Android\'s AccountManager appears to fetch the same cached auth token for apps with different UIDs - is this secure? It does not seem compatible with OAuth2, since access tokens

4条回答
  •  自闭症患者
    2021-01-29 20:12

    Your observation is correct. Authenticator will run with same UID as the installing app. When another app connects to Account manager and get token for this authenticator, it will bind to your provided authenticator service. It will run as your UID, so new accounts will be related to this Authenticator. When app calls for getAuthToken, binding will happen and Authenticator will still run in same UId. Default built in permissions check for account's UID, so that different Authenticator could not access another account from different Authenticator.

    You can solve this issue with using "Calling UID" for addAccount and GetAuthToken since account manager service adds that to bundle. Your authenticator implementation can check that.

       @Override
        public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account,
                String authTokenType, Bundle loginOptions) throws NetworkErrorException {
            Log.v(
                    TAG,
                    "getAuthToken() for accountType:" + authTokenType + " package:"
                            + mContext.getPackageName() + "running pid:" + Binder.getCallingPid()
                            + " running uid:" + Binder.getCallingUid() + " caller uid:"
                            + loginOptions.getInt(AccountManager.KEY_CALLER_UID));
              ...
    }
    

    I suggest to follow authorization flow instead of storing client secret in your native app, because other developers can extract that secret. Your app is not a web app and should not have secrets.

    When you are adding an account, you can query the callingUId as well. You need to setUserData at your addAccount related activity which will be running as your app's UID, so it can call setUserData.

    getUserData and setUserData uses built in sqllite database, so you don't need to build cache by yourself. You can only store string type, but you can parse json and store extra info per account.

    When different third party app queries account and calls for getAuthtoken with your account, you can check UID in the account' userdata. If calling UID is not listed, you can do the prompt and/or other things to get permission. If it is permitted, you can add new UID to the account.

    Sharing tokens between apps: Each app is normally registered with different clientid and they should not share token. Token is for a client app.

    Storage: AccountManager is not encrypting your data. If you need more secure solution, you should encrypt the tokens and then store it.

提交回复
热议问题