Developer Guide: SDK v2.2.x

Overview

The Reblaze platform includes a proprietary Mobile SDK: a unique client certification mechanism for mobile applications. Organizations can publish their iOS and Android apps with the SDK embedded.

In use, the SDK signs the application, authenticates the device, and verifies user identity. It validates all requests coming from legitimate apps, adding a cryptographic HMAC signature to each one. The signatures are non-reproducible, non-guessable, and non-repeating.

The SDK provides a reliable and secure mechanism to confirm that the traffic is originating from a legitimate app user and not a bot or emulator. Incoming traffic that was not verified by the SDK can safely be rejected, or have other custom responses configured.

The Reblaze Mobile SDK is available to Reblaze customers. To get access to the latest version, send a message to:

mobile-sdk-dev@reblaze.com

Scope

The SDK currently supports:

Android:

  • Java

  • Kotlin

iOS:

  • Swift-5 (Xcode 11)

  • Objective-C (Xcode 11)

The SDK package ReblazeSDK.zip contains example applications and libraries, as well as a Flutter plugin that works on both Android and iOS. We also include a React-Native example, which demonstrates the use of native bridges for iOS and Android.

The SDK comes with internal protections that make it harder to abuse it to attack your backend services, or backend services of other Reblaze customers. Still, the Reblaze SDK alone does not protect your application. We strongly recommend to all our customers to apply obfuscation and runtime protection techniques for their apps.

Getting Started

First, read the platform-independent information on this page. Then go to the page for your specific platform (links are at the bottom of this page) and follow the setup instructions.

How the SDK works

In the discussion below, customer will refer to the organization who uses the Reblaze SDK, client application will refer to the application in which the SDK is used, and user will refer to the end user of the client application.

After configuration is completed and the SDK is in use, it performs several activities:

  • Signs the requests that the client application sends over the network, to authenticate that they originated from a legitimate user of the client application.

  • Sends summaries of certain user actions (their interactions with the client application) to Reblaze for UEBA (User and Entity Behavioral Analytics).

  • Sends (optional) custom events to Reblaze for enhanced UEBA and reporting.

Each activity is described in detail in the SDK Operations section below.

Setup

The minimal requirements for using the SDK are:

There are additional properties that can be configured, but in many cases, the default values will be adequate.

We recommend configuring the SDK by adding the ReblazeURL string to iOS app Info.plist or on Android, to values resource (with Flutter or React Native, you should set this string for both platforms). This guarantees that the SDK will become activated as early as possible, and will take full advantage of the Remote Configuration.

Additional SDK properties can be set in two ways:

  • Local configuration: the properties are set programmatically in the client application.

  • Remote configuration: the properties are set by the Reblaze backend web proxy.

These options are not exclusive. At a particular time, an SDK might have all its properties configured locally, while later at a different time, some of its properties might be overridden remotely.

Local Configuration

To configure the SDK programmatically, we recommend overriding the Application.onCreate() method on Android. For iOS, the best choice would be to configure the SDK in application:didFinishLaunchingWithOptions: method.

The SDK's properties (except the read-only ones) can be queried or changed at any time, with a dedicated API. For example:

reblaze.reportCounters = ReblazeSDK_ReportCountersALL; // Objective-C
reblaze.setTokenHeaderName("session-id"); // Java
reblaze.setToken('Bearer cn389ncoiwuencr'); // Flutter
let interval = reblaze.interval // Swift
val configName = reblaze.configurationName // Kotlin

In Java and Flutter, we use getter and setter APIs, e.g. setToken() or getInterval(). If the language allows, it's preferable to use assignment operators.

The getter will always give you the effective value, but the setter might be affected by remote configuration, as discussed next.

Remote Configuration

You can setup the Reblaze backend web proxy to override local configuration settings. This is done via the Mobile SDK Profiles on the backend.

Reblaze always has one, and only one, active Mobile SDK Profile. Each Profile contains a list of zero or more property settings. Each property setting in the active Profile will be used to configure the SDK in the client application.

Properties which are not defined in the active Profile will be determined locally. The default Profile is empty. Therefore, when the default Profile is active, all SDK configuration is determined locally.

When a local property setting does not match the corresponding property setting in the active Profile, the Profile's setting is used. However, the local setting is not discarded. If the active Profile changes, and the new Profile no longer has a setting for that property, then the local setting will take effect.

The following diagram demonstrates this flow. It uses the interval parameter as an example, but the same logic works for all other parameters.

This demonstrates why you should not cache the values you get from the SDK for extended periods, because the parameters may be changed at any time due to the remote configuration.

SDK Properties

Here are all the properties available to your app:

Property
Description

configurationName

Name of server-side configuration (it will be an empty string if the configuration is fully client-side). It is read-only.

backendUrl

URL for the customer's application server. The remote configuration cannot override this value.

tokenHeaderName

The name of the HTTP header that contains a unique token for this user or session. (Default: authorization).

token

The value for the header specified above (for example, the user's login token)

interval

Determines how often UEBA events are sent to the WAF, in seconds. Minimum: 12 sec. Default value: 5 min = 300 sec.

timeslice

Time interval for grouping the UEBA data, milliseconds (rounded to 100ms). Default value: 1 sec = 1000 ms. Zero timeslice means that no grouping is performed.

userAgent

The header that will appear in Console logs for the sync messages that the SDK sends to the Reblaze service. It depends on the platform. The remote configuration cannot override this value.

reportCounters

Which counters will be reported, either ALL (default) or NONE.

autoSign

Which requests will be signed automatically, either NONE (default) or ALL. Applies to iOS only.

hashVariant

Which variant of hash function the client will use in this session. In this version, this property is read-only, and fixed at "v2".

The list above is general information. The platform-specific documentation pages contain more information about setting properties.

Backend Configuration

Your backendUrl points to your application server, protected by the Reblaze web proxy. You must configure this web proxy to recognize the signature of your app.

The Reblaze console contains a page (Settings / Web Proxy) that includes this section:

App Signatures is a list of SHA-256 digests of recognized certificates for your client application(s).

To find the signature for an iOS app, you can open the Apple Development Certificate in the Keychain app, and copy the SHA-256 fingerprint. Alternatively, you can extract this fingerprint from the ipa bundle.

For an Android app, you can get the SHA-256 fingerprint from the keystore or extract it from a signed APK with the apksigner tool (part of the Android SDK). See detailed instructions here.

When uploading the fingerprint to the Reblaze Console, make sure that it contains hexadecimal characters only, in lowercase, without spaces. Any number of signatures may be 'Active' at given time.

To avoid the issue of an app getting a new signature when uploaded to the App Store or Google Play, there is a protocol between the SDK and the backend that negotiates the signature remotely and updates the system with a new one, if such was generated.

The communication between the components takes place under the /74d8-ffc3-0f63-4b3c-c5c9-5699-6d5b-3a1f endpoint, and when a new signature is introduced, it will be provided as a value for the header named "sig" (see screenshot below).

This new signature shall then be added to the app signatures list under the Mobile SDK settings in Reblaze Console.

To find it easily in the View Log, use this filter: url:/74d8-ffc3-0f63-4b3c-c5c9-5699-6d5b-3a1f .

Profiles is a list of remote configurations, each of which contains settings that can override the parameters of the SDK on all mobile clients. The Default profile is always empty, and when it is active, the SDK parameters are fully determined by the app local configuration. Only one remote profile may be active at given time. For more on this, see the discussion above on remote configuration.

Grace period defines the allowable time between the timestamp of a request and the time that Reblaze receives the request from the application. Requests with a longer delay will be rejected. (The grace period can be set to 24 hours to allow maximum use of the generated hash.)

Token Header Name determines the name of the header that contains session or user authentication token. With the new versions of Mobile SDK, it can be empty. This name should match the tokenHeaderName configuration parameter.

During testing, you may allow running the app on Simulator (iOS) or Android Emulator. These generate a special signature: "abadbabe". Make sure that this is disabled on Production. Note that you can also use Offline Testing both on Simulator and on a physical device.

Profile Format and Restrictions

As shown above, the backend can override the parameters of the SDK. The active remote profile applies to all mobile clients, both Android and iOS. The profile is stored as a JSON string. Correct JSON syntax is enforced, all strings must be "quoted". But in the current version, the there is no verification that this JSON follows the scheme expected by the SDK on the app (client) side. Unexpected parameters (including wrong capitalization) will be silently ignored. The valid parameters are listed in the table below:

Parameter
Type and Restrictions

name

String, required. Don't specify it in the JSON, it will be taken from the left column. The SDK will see this as configurationName.

interval

Integer, in seconds. If it is below the minimum of 12 sec, the app will use 12 sec.

timeslice

Integer, in milliseconds. The app will round this value to hundreds of milliseconds. Zero timeslice means that no grouping is performed.

reportCounters

String, either "ALL" or "NONE".

autoSign

String, either "NONE" or "ALL".

The following parameters are supported, but you should have a very strong reason to change them remotely.

tokenHeaderName

String. It should be synchronized with the UID Header Name setting of the Web Proxy, and also the app must comply with this change.

hashVariant

String, should be "v2". Otherwise, the SDK will not be able to communicate with the backend anymore, and all future app requests will not be recognized as Human.

As long as a parameter is specified in the active profile, its value will override whatever is specified in the application code, but a different active profile may be chosen at any moment, or the same active profile may be edited.

When the changed profile does not specify some parameter anymore, the local value actualizes. Note that the remote configuration does not persist when the application shuts down.

SDK Operations

Signing the Network Requests

The SDK provides a way to sign the Web requests that the app sends to the customer's microservice/API endpoint. The signatures are non-reproducible, non-guessable, and non-repeating. They provide a reliable, secure mechanism to verify that the packets are originating from the legitimate app that is operated by a user, and not from an emulator or other bot.

The SDK introduces an additional HTTP header (reblaze.reblazeHeader) that should be present in all HTTPS requests that go through the Reblaze WAF. Depending on your network configuration, this may involve different URL domains and paths.

The name of the header, rbzsdk, is reserved. The SDK may also inject predefined rbzsdkandrbzsdk_tokencookies.

This header and cookies are not forwarded by Reblaze to the customer's backend.

The signature is returned by the generateHash()method, and can be valid for up to 24 hours:

httpsURLConnection.setRequestProperty(reblaze.reblazeHeader, reblaze.generateHash())

This method relies on the system clock, on the app identity, device identity and, optionally, on a user session token (see below). To verify the app identity, the app signature (the SHA-256 digest of the developer's certificate) will be registered with the Reblaze WAF, as discussed above. The device identity does not compromise the user's privacy. Obtaining this id requires no permissions on either iOS or on Android. It cannot be used to recognize that different apps are running on the same device. Also, it will be reset if an end-user reinstalls the app (but it survives the normal app upgrade).

Protected User HTTP Session

If your API features an HTTP session that is specified by a header that holds some kind of user login token, or persistent user id, you can use the Reblaze SDK to keep track of this session and provide protection from user id spoofing and token hijacking. The SDK secure hash will involve this token or id, so that the WAF rules can safely track the session, and make sure that the token is not manipulated by a man-in-the-middle or similar attack.

Perhaps you don't have such an id when the app starts up (before the user completes a signup or login process). Reblaze will enforce login-time security rulesets while this value is not available. Make sure that you set this property as soon as you know it, for the better protection.

Reblaze can use this token to enforce per-user security rulesets such as dynamic rate limits. This token can also help you to observe the activities of individual users within the traffic logs on the Reblaze console.

This support is optional, and may be turned off at any time. Simply set reblaze.token to an empty string.

Auto-signing and WebView

WebViews embedded in your mobile app are powerful browsers on their own, and their communications are fully protected by the Reblaze WAAP, which monitors end-user activity and filters bot traffic. However, this protection relies on Javascript, which should be disabled on WebView as the best practice recommended by OWASP. Without Javascript, the traffic must be protected by this Mobile SDK.

You can pass the rbzsdk header with a request that returns HTML that you load into a WebView, but this approach does not support the links and resources (including AJAX) that are parts of that HTML. To handle these use cases, the Mobile SDK introduces auto-signing. The details of this approach will be described separately on Android and iOS, but the basic idea is the same: the SDK automatically signs all relevant requests as long as the application needs this. While debugging the application, all auto-signed requests will be reported to the listener (see Monitoring the SDK).

Sending Biometric Summaries

The SDK will periodically send summaries of user events to Reblaze. These are generated automatically based on the user's interaction with the client application. The SDK accumulates the information and sends it to Reblaze at an interval set in the SDK configuration. Each summary is signed by the SDK, to prevent rogue interceptors from editing the reports.

This information is used to build behavioral profiles, which are used to recognize legitimate usage patterns for the client application. These profiles provide an additional layer of security, based on private analytics and cumulative user-event data to which threat actors have no access. Thus, they provides an additional form of client authentication that is extremely difficult for threat actors to defeat.

The summary may include counts of the following user behavior events:

tap, click, gesture, keyDown, keyPress, keyUp, touchDown, touchMove, touchUp, timeInBackground, deviceOrientation

The latter refers to device orientation changes; some of these happen when the app starts, without really rotating the device. On the other hand, if the user chooses fixed device orientation, some device rotations will not be counted.

In the current version of the SDK, you can use ALL to choose all standard counters (this is the default), or NONE. The standard counters include also the count of signedRequests (this counter may help to check that the SDK is not being abused) and a timestamp (of the first event that is counted in the batch).

The summary also includes the current battery level, charging mode, application mode (foreground or background), and device mode (e.g. emulator).

Reblaze includes these reports in its console. They can be observed by using this filter: url:/8d47.

As mentioned above, Reblaze uses the event counters to build behavioral profiles for users of the client application. After an initial learning period, Reblaze will understand how legitimate users interact with the application. Subsequent users who do not conform to these behavioral patterns can be flagged as suspicious and/or blocked from access to the API endpoint.

Transmission Interval

The summary will be sent in a form of signed JSON to the Reblaze server at the specified pace. The summary is not sent if there is nothing to report, e.g. if the application is in background, and does not communicate with the background. The interval cannot be shorter than MINIMUM_INTERVAL (12 sec). The default interval DEFAULT_INTERVAL is 5 minutes. Tune your interval according to the application usage patterns; for best performance, there should be a few reports sent during a user session. The event counts may be grouped in time slices, according to the timeslice parameter.

Reporting Custom Events

In addition to standard events, the SDK can also accumulate custom events, as reported by the client application. Each custom event is identified with a string chosen by the customer. Customers can define as many types of events as they wish, like this:

reblaze.sendEvent("buttonPressed")

Sending more types of events has the following benefits:

  • Reblaze can construct more sophisticated behavioral profiles, and thus can enforce more robust security policies. Example: a mobile API endpoint is receiving numerous requests for data from a specific IP address. Those requests for data are usually generated by a user interacting with the customer's application in a certain way. If the customer has coded the application so that all these interactive events are sent to Reblaze, then Reblaze will have learned that these types of data requests should be accompanied by these specific custom events. A high number of data requests that are not accompanied by these event notifications would indicate that this is not a legitimate user; instead, it is probably an attacker using an emulator.

  • Reblaze includes all the custom events in its traffic logs. Thus, customers can view fuller records of all the events being generated in each session.

Monitoring the SDK

The SDK does all its work in the background, and does not require application awareness of its state. It will not throw exceptions, display error logs, or crash your app.

However, we provide a way for the app to be aware of SDK status. For all SDK properties that are set by the app, or overridden by remote configuration, an SDK Event Listener can be used to keep track of networking errors that happen while the SDK is running:

reblaze.setEventListener { kind, message ->
  val text: String
  if (kind == Kind.ERROR) {
    Toast.makeText(context, message, Toast.LENGTH_LONG).show()
  }
  Log.println(kind.value, "reblaze", message)
}

Setting the SDK event listener does not depend on initialization. Actually, you may prefer to have monitoring ready when the SDK sends its first handshake HTTPS request to the backend. Therefore, we recommend to define the listener in the Application class. Note that on Android, the SDK does not retain the listener (it uses a weak reference), so it's your responsibility to protect it from being destroyed by the garbage collector.

For convenience of working with the Log.println(), the values of Kind enum match those of the Android framework Log class.

EventListener cannot be set in Flutter or ReactNative, due to performance limitations of these frameworks. You can add custom event listeners in the platform-dependent code of your app.

Offline Testing (Mock)

The SDK will not work when the device is not connected to the internet and the Reblaze server is not set up. But you can test how your app will work with the SDK without any server, even offline. To perform offline tests, use enableMock(). The SDK will not try to use the network, but will pretend to be sending events to Reblaze and receiving acknowledgements from the server. In your test, you can define mock remote configuration and/or mock connection failure (with delay):

reblaze.setMockResponse(200, "{'name':'mockConfig', 'interval':30}")

or

reblaze.setMockResponse(503, "", 600)

Once you enable mocking, you cannot turn it off. Therefore, this feature should never be used in production.

How to Set up the SDK on Your Platform

Follow these instructions for your specific platform:

Last updated