Skip to content

Most visited

Recently visited


Updating Your Security Provider to Protect Against SSL Exploits

Android relies on a security Provider to provide secure network communications. However, from time to time, vulnerabilities are found in the default security provider. To protect against these vulnerabilities, Google Play services provides a way to automatically update a device's security provider to protect against known exploits. By calling Google Play services methods, your app can ensure that it's running on a device that has the latest updates to protect against known exploits.

For example, a vulnerability was discovered in OpenSSL (CVE-2014-0224) that can leave apps open to a "man-in-the-middle" attack that decrypts secure traffic without either side knowing. With Google Play services version 5.0, a fix is available, but apps must ensure that this fix is installed. By using the Google Play services methods, your app can ensure that it's running on a device that's secured against that attack.

Caution: Updating a device's security Provider does not update Rather than using this class, we encourage app developers to use high-level methods for interacting with cryptography. Most apps can use APIs like HttpsURLConnection without needing to set a custom TrustManager or create an SSLCertificateSocketFactory.

Patching the Security Provider with ProviderInstaller

To update a device's security provider, use the ProviderInstaller class. You can verify that the security provider is up-to-date (and update it, if necessary) by calling that class's installIfNeeded() (or installIfNeededAsync()) method.

When you call installIfNeeded(), the ProviderInstaller does the following:

The installIfNeededAsync() method behaves similarly, except that instead of throwing exceptions, it calls the appropriate callback method to indicate success or failure.

If installIfNeeded() needs to install a new Provider, this can take anywhere from 30-50 milliseconds (on more recent devices) to 350 ms (on older devices). If the security provider is already up-to-date, the method takes a negligible amount of time. To avoid affecting user experience:

Warning: If the ProviderInstaller is unable to install an updated Provider, your device's security provider might be vulnerable to known exploits. Your app should behave as if all HTTP communication is unencrypted.

Once the Provider is updated, all calls to security APIs (including SSL APIs) are routed through it. (However, this does not apply to, which remains vulnerable to such exploits as CVE-2014-0224.)

Patching Synchronously

The simplest way to patch the security provider is to call the synchronous method installIfNeeded(). This is appropriate if user experience won't be affected by the thread blocking while it waits for the operation to finish.

For example, here's an implementation of a sync adapter that updates the security provider. Since a sync adapter runs in the background, it's okay if the thread blocks while waiting for the security provider to be updated. The sync adapter calls installIfNeeded() to update the security provider. If the method returns normally, the sync adapter knows the security provider is up-to-date. If the method throws an exception, the sync adapter can take appropriate action (such as prompting the user to update Google Play services).

 * Sample sync adapter using {@link ProviderInstaller}.
public class SyncAdapter extends AbstractThreadedSyncAdapter {


  // This is called each time a sync is attempted; this is okay, since the
  // overhead is negligible if the security provider is up-to-date.
  public void onPerformSync(Account account, Bundle extras, String authority,
      ContentProviderClient provider, SyncResult syncResult) {
    try {
    } catch (GooglePlayServicesRepairableException e) {

      // Indicates that Google Play services is out of date, disabled, etc.

      // Prompt the user to install/update/enable Google Play services.
          e.getConnectionStatusCode(), getContext());

      // Notify the SyncManager that a soft error occurred.

    } catch (GooglePlayServicesNotAvailableException e) {
      // Indicates a non-recoverable error; the ProviderInstaller is not able
      // to install an up-to-date Provider.

      // Notify the SyncManager that a hard error occurred.

    // If this is reached, you know that the provider was already up-to-date,
    // or was successfully updated.

Patching Asynchronously

Updating the security provider can take as much as 350 milliseconds (on older devices). If you're doing the update on a thread that directly affects user experience, such as the UI thread, you don't want to make a synchronous call to update the provider, since that can result in the app or device freezing until the operation finishes. Instead, you should use the asynchronous method installIfNeededAsync(). That method indicates its success or failure by calling callbacks.

For example, here's some code that updates the security provider in an activity in the UI thread. The activity calls installIfNeededAsync() to update the provider, and designates itself as the listener to receive success or failure notifications. If the security provider is up-to-date or is successfully updated, the activity's onProviderInstalled() method is called, and the activity knows communication is secure. If the provider cannot be updated, the activity's onProviderInstallFailed() method is called, and the activity can take appropriate action (such as prompting the user to update Google Play services).

 * Sample activity using {@link ProviderInstaller}.
public class MainActivity extends Activity
    implements ProviderInstaller.ProviderInstallListener {

  private static final int ERROR_DIALOG_REQUEST_CODE = 1;

  private boolean mRetryProviderInstall;

  //Update the security provider when the activity is created.
  protected void onCreate(Bundle savedInstanceState) {
    ProviderInstaller.installIfNeededAsync(this, this);

   * This method is only called if the provider is successfully updated
   * (or is already up-to-date).
  protected void onProviderInstalled() {
    // Provider is up-to-date, app can make secure network calls.

   * This method is called if updating fails; the error code indicates
   * whether the error is recoverable.
  protected void onProviderInstallFailed(int errorCode, Intent recoveryIntent) {
    if (GooglePlayServicesUtil.isUserRecoverableError(errorCode)) {
      // Recoverable error. Show a dialog prompting the user to
      // install/update/enable Google Play services.
          new DialogInterface.OnCancelListener() {
            public void onCancel(DialogInterface dialog) {
              // The user chose not to take the recovery action
    } else {
      // Google Play services is not available.

  protected void onActivityResult(int requestCode, int resultCode,
      Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == ERROR_DIALOG_REQUEST_CODE) {
      // Adding a fragment via GooglePlayServicesUtil.showErrorDialogFragment
      // before the instance state is restored throws an error. So instead,
      // set a flag here, which will cause the fragment to delay until
      // onPostResume.
      mRetryProviderInstall = true;

   * On resume, check to see if we flagged that we need to reinstall the
   * provider.
  protected void onPostResume() {
    if (mRetryProviderInstall) {
      // We can now safely retry installation.
      ProviderInstall.installIfNeededAsync(this, this);
    mRetryProviderInstall = false;

  private void onProviderInstallerNotAvailable() {
    // This is reached if the provider cannot be updated for some reason.
    // App should consider all HTTP communication to be vulnerable, and take
    // appropriate action.
This site uses cookies to store your preferences for site-specific language and display options.

Get the latest Android developer news and tips that will help you find success on Google Play.

* Required Fields


Follow Google Developers on WeChat

Browse this site in ?

You requested a page in , but your language preference for this site is .

Would you like to change your language preference and browse this site in ? If you want to change your language preference later, use the language menu at the bottom of each page.

This class requires API level or higher

This doc is hidden because your selected API level for the documentation is . You can change the documentation API level with the selector above the left navigation.

For more information about specifying the API level your app requires, read Supporting Different Platform Versions.

Take a short survey?
Help us improve the Android developer experience. (April 2018 — Developer Survey)