Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d782f9c4 authored by Jason Chiu's avatar Jason Chiu
Browse files

Block the content scheme intent in AccountTypePreferenceLoader

Also prevent intent defined in AccountPreference from leaking access

Bug: 366401629
Flag: EXEMPT security fix
Test: atest AccountTypePreferenceLoaderTest, manual
Change-Id: Ica87087341cc983df04190919e33dc369fa18619
Merged-In: Ica87087341cc983df04190919e33dc369fa18619
(cherry picked from commit 841fb384)
parent 4296cc19
Loading
Loading
Loading
Loading
+18 −7
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@ package com.android.settings.accounts;

import android.accounts.Account;
import android.accounts.AuthenticatorDescription;
import android.content.ClipData;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
@@ -177,6 +179,9 @@ public class AccountTypePreferenceLoader {
                                 * exploiting the fact that settings has system privileges.
                                 */
                            if (isSafeIntent(pm, prefIntent, acccountType)) {
                                // Explicitly set an empty ClipData to ensure that we don't offer to
                                // promote any Uris contained inside for granting purposes
                                prefIntent.setClipData(ClipData.newPlainText(null, null));
                                mFragment.getActivity().startActivityAsUser(
                                    prefIntent, mUserHandle);
                            } else {
@@ -237,13 +242,19 @@ public class AccountTypePreferenceLoader {
    }

    /**
     * Determines if the supplied Intent is safe. A safe intent is one that is
     * will launch a exported=true activity or owned by the same uid as the
     * Determines if the supplied Intent is safe. A safe intent is one that
     * will launch an exported=true activity or owned by the same uid as the
     * authenticator supplying the intent.
     */
    private boolean isSafeIntent(PackageManager pm, Intent intent, String acccountType) {
    @VisibleForTesting
    boolean isSafeIntent(PackageManager pm, Intent intent, String accountType) {
        if (TextUtils.equals(intent.getScheme(), ContentResolver.SCHEME_CONTENT)) {
            Log.e(TAG, "Intent with a content scheme is unsafe.");
            return false;
        }

        AuthenticatorDescription authDesc =
            mAuthenticatorHelper.getAccountTypeDescription(acccountType);
                mAuthenticatorHelper.getAccountTypeDescription(accountType);
        ResolveInfo resolveInfo = pm.resolveActivityAsUser(intent, 0, mUserHandle.getIdentifier());
        if (resolveInfo == null) {
            return false;
+14 −0
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.settings.accounts;

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.Answers.RETURNS_DEEP_STUBS;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
@@ -26,8 +28,11 @@ import static org.mockito.Mockito.when;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AuthenticatorDescription;
import android.content.ClipData;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.UserHandle;

import androidx.preference.Preference;
@@ -129,4 +134,13 @@ public class AccountTypePreferenceLoaderTest {
        verify(mPrefLoader).updatePreferenceIntents(prefGroup4, acctType, mAccount);
        verify(mPrefLoader).updatePreferenceIntents(prefGroup41, acctType, mAccount);
    }

    @Test
    public void isSafeIntent_hasContextScheme_returnFalse() {
        Intent intent = new Intent();
        intent.setClipData(ClipData.newRawUri(null,
                Uri.parse("content://com.android.settings.files/my_cache/NOTICE.html")));

        assertThat(mPrefLoader.isSafeIntent(mPackageManager, intent, mAccount.type)).isFalse();
    }
}