Security controls

Debug detection

Android SDK has an ability to detect if the app works in a debug mode or in a debuggable environment (for example if it's running on an emulator or on a physical device with an operating system which allows debugging all applications - like the LineageOS). If debug mode detection is enabled and debug is detected, then the SDK will not allow executing any security related flow. Also, a special event will be logged on the Token Server instance indicating that connection attempt from the potentially unreliable device was made.

Root detection

The SDK is capable to detect whenever device running the application is rooted. If detection is enabled and device is rooted, then the SDK will not allow to execute any security related flow. Also special event will be logged on the Token Server instance indicating that connection from potentially unreliable device was sent.

Tampering detection

To validate the app has not been tampered with the client secret can be sent encrypted (depending on the client configuration in the Token Server) to any request using the client secret to the Token Server. The client secret encryption is done using the application signature which naturally changes across different app versions so once the application gets updated/changed server will not be able to validate it anymore. For that reason the client secret is tied to a specific application version and will also be changed once application is updated. It is done by a process called Dynamic Client Update (DCU). For more info on this topic please refer to Dynamic Client Update.

SecurityController

In some cases you may want to disable root or debug detection, or display additional debug logs. We advice you to not do this for production apps, because it can introduce security vulnerabilities to your product. However, you might want to enable it during development or when you try to debug an error. For such cases the SDK uses the Context.getPackageName() method to search for a class called {your.application.package}.SecurityController. The class can contain public static boolan fields that can change the default security options of the SDK:

  • debugDetection (default TRUE) - when set to FALSE the SDK will disable the debug detection feature
  • rootDetection (default TRUE) - when set to FALSE the SDK will disable the root detection feature
  • debugLogs (default FALSE) - when set to TRUE the SDK will print network logs to the Android Logcat

When any of the fields is not defined in the SecurityController, the SDK keeps the most secure configuration using default values. You can use any combination of above fields (set a field to TRUE/FALSE or skip it to have default value).

Please note, that the SecurityController can be also created by the Onegini SDK Configurator. The configurator will set desired root and debug detection flags when needed, but it will not add the "debugLogs" flag.

Remember, that the SecurityController can't be obfuscated. Otherwise the SDK won't be able to find it. If you want to use SecurityController in an obfuscated app, you should add a proper "keep" rule, for example:

-keep class com.onegini.mobile.android.demo.SecurityController { *; }

Examples

A setup with disabled: root detection and network logs while having debug detection enabled could look like this:

package com.onegini.mobile.android.demo;

public final class SecurityController {
  public static final boolean debugDetection = true; // default value, so this line can be removed
  public static final boolean rootDetection = false;
  public static final boolean debugLogs = false; // default value, so this line can be removed
}

or (when we remove not required lines):

package com.onegini.mobile.android.demo;

public final class SecurityController {
  public static final boolean rootDetection = false;
}

A setup with network logs enabled while both root and debug detection features are disabled:

public final class SecurityController {
  public static final boolean debugDetection = false;
  public static final boolean rootDetection = false;
  public static final boolean debugLogs = true;
}

A setup which have both: root and debug detection enabled and logs disabled: simply remove the SecurityController from your app so the SDK will use default values to protect your app.

Product flavours

In case you use product flavours and dynamically change the applicationId using applicationIdSuffix it might be that the SecurityController class cannot be found by the SDK. In that case you need to manually specify the location of the SecurityController class. You can do that by using the OneginiClientBuilder#setSecurityController() method. Below you can find a code example.

  private static OneginiClient buildSDK(final Context context) {
    final Context applicationContext = context.getApplicationContext();
    final CreatePinRequestHandler createPinRequestHandler = new CreatePinRequestHandler(applicationContext);
    final PinAuthenticationRequestHandler pinAuthenticationRequestHandler = new PinAuthenticationRequestHandler(applicationContext);

    // will throw OneginiConfigNotFoundException if OneginiConfigModel class can't be found
    return new OneginiClientBuilder(applicationContext, createPinRequestHandler, pinAuthenticationRequestHandler)
        .setSecurityController(SecurityController.class)
        .build();
  }