Configuration

The minimum configuration for the AppProtection is setting up the username, password and public key for the service. However, we recommend configuring all features that are present in the SDK.

The Username, Password and Signature Public Key can be obtained in the Malwarelytics console. Note that these credentials are bound to your application Bundle ID. If you need to support multiple environments (Bundle IDs), you need different credentials for each environment.

Configuring the Service

To enable Malwarelytics in your app, you need to properly configure the singleton AppProtectionService class and set the AppProtectionRaspDelegate to obtain callbacks.

You should implement the following three configurations:

  • AppProtectionConfig - Configures generic parameters, such as service credentials or app user ID.
  • AppProtectionRaspConfig - Configures which RASP features are enabled and default actions for the detections.
  • AppProtectionEventConfig - Configures which RASP events are emitted and sent to the back-end services.

Based on the configuration, the AppProtectionRaspDelegate then receives updates about various RASP events.

Sample Integration

The AppSecurity swift class is a sample implementation over the AppProtectionService singleton.

import UIKit
import AppProtection

class AppSecurity: AppProtectionRaspDelegate {

    /// Creates AppSecurity instance
    /// - Parameter clientId: ID of the user
    init?(clientId: String?) {

        // Prepare a builder to connect to the service
        let builder = AppProtectionConfig.Builder()
            .username("$USERNAME")
            .password("$PASSWORD")
            .signaturePublicKey("$PUBKEY")

        // Set your internal client ID, if available
        if let clientId = clientId {
            builder.clientAppUserId(clientId)
        }

        // Prepare the RASP feature configuration
        let raspConfig = AppProtectionRaspConfig.Builder()
            .debugger(.block) // block debugger
            .httpProxy(.notify) // notify me via delegate when http proxy is enabled
            .jailbreak(.exit) // exit on jailbroken phone
            .repackage(.exit([AppProtectionTrustedCert(withBase64EncodedString: "$BASE_64_ENCODED_CERT")!])) // follow documentation how to obtain certificate string
            .reverseEngineeringTools(.notify) // let me know when user installed revers engineering tools
            .build()

        builder.raspConfig(raspConfig)

        // Prepare the configuration for events
        let eventsConfig = AppProtectionEventConfig.Builder()
            .enableAppLifecycleCollection(true) // track lifecycle events in the Malwarelytics console on the server
            .enableScreenshotTakenCollection(true) // track when user takes screenshot
            .build()

        builder.eventsConfig(eventsConfig)

        do {
            // Configure the Service
            try AppProtectionService.configureShared(builder.build())
        } catch {
            // AppProtectionService singleton was already configured!
            return nil
        }

        // Set the delegate to obtain RASP callbacks
        AppProtectionService.shared.rasp.addDelegate(self)
    }

    /// Report in-app incident
    /// - Parameter incident: Incident that happened inside the app
    func reportIncident(_ incident: RaspIncident) {
        AppProtectionService.shared.events.log(incident.appProtectionValue)
    }

    /// Call when client id changes (paired/unpaired the app).
    /// - Parameter clientId: Client id
    func setClientId(_ clientId: String?) {
        AppProtectionService.shared.clientAppUserId = clientId
    }

    /// AppProtection resets the device indicator and starts registering it as a new device.
    func resetServiceId() {
        AppProtectionService.shared.resetInstanceId()
    }

    // MARK: - AppProtectionRaspDelegate

    func debuggerDetected() {
        // react to debugger
    }

    func jailbreakDetected() {
        // react to jailbreak
    }

    func repackageDetected() {
        // react to repackage
    }

    func httpProxyEnabled() {
        // react to http proxy enabled
    }

    func userScreenshotDetected() {
        // react to user screenshot
    }

    func reverseEngineeringToolsDetected() {
        // react to reverse engineering tools
    }

    func systemPasscodeConfigurationChanged(enabled: Bool) {
        // react to system passcode change
    }

    func systemBiometryConfigurationChanged(enabled: Bool) {
        // react to biometry configuration changed
    }
}

enum RaspIncident {
    case sslInvalidCert
    case deviceUnpaired
    case devicePaired
    case deviceBlocked
    case userIgnoredWeakPassphrase
    case passphraseChanged
    case biometryEnabled
    case biometryDisabled
    case authenticationFailed
    case authenticationSuccess

    var appProtectionValue: AppProtectionEvent {
        switch self {
        case .sslInvalidCert: return AppProtectionEvent.Network.sslInvalidCertificate
        case .deviceUnpaired: return AppProtectionEvent.Authentication.deviceUnpaired
        case .devicePaired: return AppProtectionEvent.Authentication.devicePaired
        case .deviceBlocked: return AppProtectionEvent.Authentication.deviceBlocked
        case .userIgnoredWeakPassphrase: return AppProtectionEvent.Authentication.userIgnoredWeakPassphrase
        case .passphraseChanged: return AppProtectionEvent.Authentication.passphraseChanged
        case .biometryEnabled: return AppProtectionEvent.Authentication.biometryEnabled
        case .biometryDisabled: return AppProtectionEvent.Authentication.biometryDisabled
        case .authenticationFailed: return AppProtectionEvent.Authentication.authenticationFailed
        case .authenticationSuccess: return AppProtectionEvent.Authentication.authenticationSuccess
        }
    }
}
Last updated on Apr 18, 2021 (17:38) View product
Search

0.9.x

Malwarelytics for Apple