diff options
| author | Chad Brubaker <cbrubaker@google.com> | 2017-10-18 10:35:04 -0700 |
|---|---|---|
| committer | Chad Brubaker <cbrubaker@google.com> | 2017-10-18 12:30:30 -0700 |
| commit | 5ac2ea1b4d6dbaca045acd4ae9f82bb27089d5f2 (patch) | |
| tree | cf5c58e54c768498257b6263b9c22501a3167f3a /core/java | |
| parent | 02cca1e0714ca607d794e0482fab0e8d3e922477 (diff) | |
Make priv apps not trust user added CAs by default
Privileged applications provide core system functionality and as such a
MiTM in one can put the entire system at risk. These applications should
not be trusting user added CAs by default.
Bug: 65406503
Test: runtest --path framework/base/tests/NetworkSecurityConfigTest
Change-Id: I033258fe1c66ad245d172899df52e9cd02e9ca75
Diffstat (limited to 'core/java')
3 files changed, 33 insertions, 57 deletions
diff --git a/core/java/android/security/net/config/ManifestConfigSource.java b/core/java/android/security/net/config/ManifestConfigSource.java index 8fcd5ab55e6a..79115a5ad3c2 100644 --- a/core/java/android/security/net/config/ManifestConfigSource.java +++ b/core/java/android/security/net/config/ManifestConfigSource.java @@ -20,6 +20,7 @@ import android.content.Context; import android.content.pm.ApplicationInfo; import android.util.Log; import android.util.Pair; + import java.util.Set; /** @hide */ @@ -29,21 +30,14 @@ public class ManifestConfigSource implements ConfigSource { private final Object mLock = new Object(); private final Context mContext; - private final int mApplicationInfoFlags; - private final int mTargetSdkVersion; - private final int mConfigResourceId; - private final int mTargetSandboxVesrsion; + private final ApplicationInfo mApplicationInfo; private ConfigSource mConfigSource; public ManifestConfigSource(Context context) { mContext = context; - // Cache values because ApplicationInfo is mutable and apps do modify it :( - ApplicationInfo info = context.getApplicationInfo(); - mApplicationInfoFlags = info.flags; - mTargetSdkVersion = info.targetSdkVersion; - mConfigResourceId = info.networkSecurityConfigRes; - mTargetSandboxVesrsion = info.targetSandboxVersion; + // Cache the info because ApplicationInfo is mutable and apps do modify it :( + mApplicationInfo = new ApplicationInfo(context.getApplicationInfo()); } @Override @@ -61,17 +55,18 @@ public class ManifestConfigSource implements ConfigSource { if (mConfigSource != null) { return mConfigSource; } - + int configResource = mApplicationInfo.networkSecurityConfigRes; ConfigSource source; - if (mConfigResourceId != 0) { - boolean debugBuild = (mApplicationInfoFlags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; + if (configResource != 0) { + boolean debugBuild = + (mApplicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; if (DBG) { Log.d(LOG_TAG, "Using Network Security Config from resource " - + mContext.getResources().getResourceEntryName(mConfigResourceId) + + mContext.getResources() + .getResourceEntryName(configResource) + " debugBuild: " + debugBuild); } - source = new XmlConfigSource(mContext, mConfigResourceId, debugBuild, - mTargetSdkVersion, mTargetSandboxVesrsion); + source = new XmlConfigSource(mContext, configResource, mApplicationInfo); } else { if (DBG) { Log.d(LOG_TAG, "No Network Security Config specified, using platform default"); @@ -79,10 +74,9 @@ public class ManifestConfigSource implements ConfigSource { // the legacy FLAG_USES_CLEARTEXT_TRAFFIC is not supported for Ephemeral apps, they // should use the network security config. boolean usesCleartextTraffic = - (mApplicationInfoFlags & ApplicationInfo.FLAG_USES_CLEARTEXT_TRAFFIC) != 0 - && mTargetSandboxVesrsion < 2; - source = new DefaultConfigSource(usesCleartextTraffic, mTargetSdkVersion, - mTargetSandboxVesrsion); + (mApplicationInfo.flags & ApplicationInfo.FLAG_USES_CLEARTEXT_TRAFFIC) != 0 + && mApplicationInfo.targetSandboxVersion < 2; + source = new DefaultConfigSource(usesCleartextTraffic, mApplicationInfo); } mConfigSource = source; return mConfigSource; @@ -93,10 +87,8 @@ public class ManifestConfigSource implements ConfigSource { private final NetworkSecurityConfig mDefaultConfig; - public DefaultConfigSource(boolean usesCleartextTraffic, int targetSdkVersion, - int targetSandboxVesrsion) { - mDefaultConfig = NetworkSecurityConfig.getDefaultBuilder(targetSdkVersion, - targetSandboxVesrsion) + DefaultConfigSource(boolean usesCleartextTraffic, ApplicationInfo info) { + mDefaultConfig = NetworkSecurityConfig.getDefaultBuilder(info) .setCleartextTrafficPermitted(usesCleartextTraffic) .build(); } diff --git a/core/java/android/security/net/config/NetworkSecurityConfig.java b/core/java/android/security/net/config/NetworkSecurityConfig.java index 789fc273b965..b9e550540217 100644 --- a/core/java/android/security/net/config/NetworkSecurityConfig.java +++ b/core/java/android/security/net/config/NetworkSecurityConfig.java @@ -16,9 +16,11 @@ package android.security.net.config; +import android.content.pm.ApplicationInfo; import android.os.Build; import android.util.ArrayMap; import android.util.ArraySet; + import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; @@ -28,8 +30,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -import javax.net.ssl.X509TrustManager; - /** * @hide */ @@ -170,22 +170,24 @@ public final class NetworkSecurityConfig { * <li>No certificate pinning is used.</li> * <li>The system certificate store is trusted for connections.</li> * <li>If the application targets API level 23 (Android M) or lower then the user certificate - * store is trusted by default as well.</li> + * store is trusted by default as well for non-privileged applications.</li> + * <li>Privileged applications do not trust the user certificate store on Android P and higher. + * </li> * </ol> * * @hide */ - public static final Builder getDefaultBuilder(int targetSdkVersion, int targetSandboxVesrsion) { + public static Builder getDefaultBuilder(ApplicationInfo info) { Builder builder = new Builder() .setHstsEnforced(DEFAULT_HSTS_ENFORCED) // System certificate store, does not bypass static pins. .addCertificatesEntryRef( new CertificatesEntryRef(SystemCertificateSource.getInstance(), false)); - final boolean cleartextTrafficPermitted = targetSandboxVesrsion < 2; + final boolean cleartextTrafficPermitted = info.targetSandboxVersion < 2; builder.setCleartextTrafficPermitted(cleartextTrafficPermitted); // Applications targeting N and above must opt in into trusting the user added certificate // store. - if (targetSdkVersion <= Build.VERSION_CODES.M) { + if (info.targetSdkVersion <= Build.VERSION_CODES.M && !info.isPrivilegedApp()) { // User certificate store, does not bypass static pins. builder.addCertificatesEntryRef( new CertificatesEntryRef(UserCertificateSource.getInstance(), false)); diff --git a/core/java/android/security/net/config/XmlConfigSource.java b/core/java/android/security/net/config/XmlConfigSource.java index a111fbce183c..02be403ae150 100644 --- a/core/java/android/security/net/config/XmlConfigSource.java +++ b/core/java/android/security/net/config/XmlConfigSource.java @@ -1,13 +1,13 @@ package android.security.net.config; import android.content.Context; +import android.content.pm.ApplicationInfo; import android.content.res.Resources; import android.content.res.XmlResourceParser; -import android.os.Build; import android.util.ArraySet; import android.util.Base64; import android.util.Pair; -import com.android.internal.annotations.VisibleForTesting; + import com.android.internal.util.XmlUtils; import org.xmlpull.v1.XmlPullParser; @@ -36,37 +36,19 @@ public class XmlConfigSource implements ConfigSource { private final Object mLock = new Object(); private final int mResourceId; private final boolean mDebugBuild; - private final int mTargetSdkVersion; - private final int mTargetSandboxVesrsion; + private final ApplicationInfo mApplicationInfo; private boolean mInitialized; private NetworkSecurityConfig mDefaultConfig; private Set<Pair<Domain, NetworkSecurityConfig>> mDomainMap; private Context mContext; - @VisibleForTesting - public XmlConfigSource(Context context, int resourceId) { - this(context, resourceId, false); - } - - @VisibleForTesting - public XmlConfigSource(Context context, int resourceId, boolean debugBuild) { - this(context, resourceId, debugBuild, Build.VERSION_CODES.CUR_DEVELOPMENT); - } - - @VisibleForTesting - public XmlConfigSource(Context context, int resourceId, boolean debugBuild, - int targetSdkVersion) { - this(context, resourceId, debugBuild, targetSdkVersion, 1 /*targetSandboxVersion*/); - } - - public XmlConfigSource(Context context, int resourceId, boolean debugBuild, - int targetSdkVersion, int targetSandboxVesrsion) { - mResourceId = resourceId; + public XmlConfigSource(Context context, int resourceId, ApplicationInfo info) { mContext = context; - mDebugBuild = debugBuild; - mTargetSdkVersion = targetSdkVersion; - mTargetSandboxVesrsion = targetSandboxVesrsion; + mResourceId = resourceId; + mApplicationInfo = new ApplicationInfo(info); + + mDebugBuild = (mApplicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; } public Set<Pair<Domain, NetworkSecurityConfig>> getPerDomainConfigs() { @@ -365,7 +347,7 @@ public class XmlConfigSource implements ConfigSource { // Use the platform default as the parent of the base config for any values not provided // there. If there is no base config use the platform default. NetworkSecurityConfig.Builder platformDefaultBuilder = - NetworkSecurityConfig.getDefaultBuilder(mTargetSdkVersion, mTargetSandboxVesrsion); + NetworkSecurityConfig.getDefaultBuilder(mApplicationInfo); addDebugAnchorsIfNeeded(debugConfigBuilder, platformDefaultBuilder); if (baseConfigBuilder != null) { baseConfigBuilder.setParent(platformDefaultBuilder); |
