Integrate BehavioSec account fraud detection
BehavioSec provides a New Account Fraud (NAF) scenario to generate profiling statistics of all the users to distinguish between a genuine new user and a fraudster.
A population profiling feature monitors a session when a user attempts to create a new account. The user’s behavioral data is collected invisibly and sent to the BehavioSense server for analysis.
Typically, new users do not have an existing user profile to compare against. The population profiling feature provides the data where new users are analyzed against the statistics of the global population of previous users and are checked for obvious suspicious activity, such as bots and remote access tools.
The NAF feature supports both single-page and multiple-page use cases:
-
Single-page: This is a registration flow where all the user's inputs are on one screen. It is a single
ViewControlleron iOS. It is a single fragment or activity on Android. -
Multiple-page: This is registration flow where the user's inputs are on multiple screens. It requires multiple
ViewControllerson iOS. It requires multiple fragments or activities on Android.
Single-page integration
TouchSDK collects user’s touch interaction with the app on a page (ViewController, Activity, Fragment), such as swipe, tap, and press, to provide more accurate information for population profiling.
Besides TouchSDK, the integration steps are similar to the existing BehavioSec integration, that is, setting the page name and ID for each UI component, and so on.
Enabling TouchSDK increases the BehavioSec payload size. It is recommended to stop the detection as soon as the registration has completed or the screen is dismissed. Alternatively you can optimize this operation in the background by calling GAHCore.clearTransactionResources. GAHCore.clearTransactionResources clears all collected BehavioSec data and all registrations, and stops motion detections.
Enabling TouchSDK also increases signal collection time. The default timeout is set to 2000 ms. When BehavioSec signal collection exceeds this timeout, the signal contains error code 524 (Signal Timeout). On older Android devices, if the page is expected to contain a lot of touches, the timeout should be increased by calling GAHCoreConfig.setSignalCollectionGlobalTimeout(). The following table provides the signal collection time for some devices.
| Device | 10 touches | 20 touches | 30 touches | 60 touches | 120 touches |
|---|---|---|---|---|---|
| Android | |||||
| Nexus 7 (2012) | 715 ms | 1277 ms | 1621 ms | 3206 ms | 5919 ms |
| Xperia Z5 | 512 ms | 826 ms | 1255 ms | 2107 ms | 4492 ms |
| Blackberry Priv | 328 ms | 541 ms | 693 ms | 1745 ms | 3594 ms |
| OnePlus 5T | 73 ms | 99 ms | 138 ms | 274 ms | 516 ms |
| iOS | |||||
| iPhone 5s | 25 ms | 35 ms | 45 ms | 77 ms | 142 ms |
| iPhone 7 Plus | 12 ms | 15 ms | 19 ms | 33 ms | 58 ms |
| iPad 6th gen (2018) | 8 ms | 12 ms | 14 ms | 25 ms | 43 ms |
iOS
It is recommended to place the setup code in viewWillAppear and clear the data code in viewWillDisappear.
After the user has finished entering the input fields and is ready to submit the data:
-
Obtain the
visitIDby calling therequestVisitIDAPI. All the data collection is passed in therequestVisitIDAPI. -
If an error occurs, it might require the user to re-enter all the inputs, then you have to call the 'clear data' function and 'set up' function again. Otherwise, the data from the old session is appended along with the new session.
The following sample code snippet shows how to integrate the NAF feature on iOS:
Objective C
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self setupBehavioSec];
[GAHCore startPrefetchSignals];
}
-(void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self clearBehavioSecData];
}
-(void)setupBehavioSec {
//initialize BehavioSec object
self.bSDK = [BehavioSecIOSSDK sharedIOSSDK];
//Register UI elements
self.bSDK addInformation:@"<page_definition_identifier>" withName:@"viewIdentifier"];
[self.bSDK registerKbdTargetWithID: self.inputTextField andName:@"<id_defined_in_page_definition>" isAnonymous:YES];
[GAHCore setBehavioSecObject:self.bSDK];
//enable TouchSDK and start motion detects
[self.bSDK enableTouchSDKWithViewController:self];
[self.bSDK startMotionDetect];
}
-(void)clearBehavioSecData{
[self clearTextFieldData];
//Below function will clear all BehavioSec data collected, clear all registrations and stop the motion detects
[GAHCore clearTransactionResources];
}
-(IBAction)registerButtonPressed:(id)sender {
if ([self isValidTextFieldInput]) {
//The user's interaction and risks data are sent via requestVisitID
[GAHCore requestVisitID:^(NSString *visitID) {
//call backend to register new account and get decisions
[self registerNewAccountWithVisitId:visitID];
} failure:^(NSInteger errorCode, NSString *errorMessage) {
//handle error
//clear current data and do set up again if needed
}];
}
}
Swift
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
setupBehavioSec()
GAHCore.startPrefetchSignals()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillAppear(animated)
clearBehavioSecData()
}
func setupBehavioSec() {
//initialize BehavioSec object
self.bSDK = BehavioSecIOSSDK.shared()
//Register UI elements
self.bSDK.addInformation("<page_definition_identifier>", withName: "viewIdentifier")
self.bSDK.registerBtnTarget(withID: self.inputTextField, andName: "<id_defined_in_page_definition>", isAnonymous: true)
//Set BehavioSec Object to GAH SDK
GAHCore.setBehavioSecObject(self.bSDK)
//enable TouchSDK and start motion detects
self.bSDK.enableTouch(with: self)
self.bSDK.startMotionDetect()
}
func clearBehavioSecData() {
clearTextFieldData()
//Below function will clear all BehavioSec data collected, clear all registrations and stop the motion detects
GAHCore.clearTransactionResources()
}
@IBAction func registerButtonPressed(_ sender: UIButton) {
if (isValidTextFieldInput()) {
GAHCore.requestVisitID({ (visitID) in
//call backend to register new account and get decisions
self.registerNewAccount(withVisitId: visitID!)
}) { (errorCode, errorMessage) in
//handle error
//clear current data and do set up again if needed
}
}
}
Android
Besides enabling TouchSDK, it is also recommended to enable DeviceSDK. DeviceSDK collects the device data. Refer to the BehavioSec documentation for more details.
Perform the following steps to integrate the NAF feature:
-
Extend the BehavioSec
BehavioAbstractActivity.BehavioSec also provides
BehavioAppCompactActivityandBehavioAbstractFragmentfor theAppCompatActivityandFragmentuse cases. Refer to the BehavioSec documentation for more details. -
Follow these steps to override the
initActivitymethod:-
Set the page name by calling
BehavioTimings.setPageName(). -
Use
BehavioEditText,BehavioMaskedEditTextorBehavioAnonymousEditTextprovided by BehavioSec and set the ID by callingsetFieldName.
-
-
Override
dispatchTouchEventbecauseTouchSDKhas to get information about every interaction with the application. -
In
onResume, create theTouchSDKandDeviceSDKobjects.-
Pass both
TouchSDKandDeviceSDKobjects toGAHCore.setBehavioSecTouchDeviceObject. -
Start data collection by calling
TouchSDK.startDataCollection.
You can only do data collection when the application is active by stopping the data collection in
onPause. -
-
After the user has finished entering the input fields and is ready to submit the data, obtain visitID by calling the
requestVisitIDAPI. -
Clear the text fields and BehavioSec data by calling
GAHCore.clearTransactionResources().
The following sample code snippet shows how to set up a single-page integration on Android:
// 1. extend activity
public class RegistrationActivity extends BehavioAppCompatActivity {
private BehavioEditText mUsernameEditText;
private TouchSDK mTouchSDK;
private DeviceSDK mDeviceSDK;
// 2. override initActivity
@Override
public void initActivity() {
setContentView(R.layout.activity_registration);
// i. set page name
BehavioTimings.setPageName("<page_definition_identifier>");
// ii. set id for textfields
mUsernameEditText = (BehavioEditText)findViewById(R.id.text_username);
mUsernameEditText.setFieldName("<id_defined_in_page_definition>");
}
// 3. override dispatchTouchEvents
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (mTouchSDK != null) {
mTouchSDK.addTouchEvent(ev);
}
return super.dispatchTouchEvent(ev);
}
// 4. create TouchSDK and DeviceSDK
@Override
protected void onResume() {
super.onResume();
if (mTouchSDK == null){
ViewGroup viewGroup = findViewById(R.id.activity_viewgroup);
mTouchSDK = new TouchSDK(getApplicationContext(), viewGroup);
mDeviceSDK = new DeviceSDK(getApplicationContext());
// i. set TouchSDK and DeviceSDK to GAHCore
GAHCore.setBehavioSecTouchDeviceObject(mTouchSDK, mDeviceSDK);
}
// ii. start data collecetion
mTouchSDK.startDataCollection();
}
// 5. stop data collection in onPause and start data collection in onResume
@Override
protected void onPause() {
super.onPause();
if (mTouchSDK != null){
mTouchSDK.stopDataCollection();
}
}
@Override
protected void onResume() {
super.onResume();
if (mTouchSDK != null){
mTouchSDK.startDataCollection();
}
}
// 6. after user has entered data
public void nextButtonTouched(View view) {
// i. obtain visitID
GAHCore.requestVisitID(new GAHResponseCallback() {
@Override
public void success(String visitId) {
// ii. clear the textfields and timing data
GAHCore.clearTransactionResources();
mTouchSDK = null;
mDeviceSDK = null;
}
@Override
public void error(int errCode, final String errorMsg) {}
});
}
}
Multiple-page integration
To use the NAF feature on multiple pages, GAHCore.startProfileTransaction is called to obtain the visitID the first time it is set up on the first page. This visitID is used throughout the multiple page sequences that are visited.
Call the GAHCore.profileTransaction API only after the visitID is obtained from GAHCore.startProfileTransaction.
At the end of every page, GAHCore.profileTransaction is called to collect the user's behavioral data on each page.
On the last page, it is recommended to wait for profileTransaction to finish before calling the back-end API that calls getDecision. Otherwise, there is a chance that the user's data collected on the last page is not received by the back end when getDecision is called.
After the registration is completed, call GAHCore.finishProfileTransaction to clear the associated visitID in the SDK.
iOS setup
The setup in the multiple-page integration is very similar to the single-page integration, with the following exceptions:
-
In the single-page integration, after the user enters the inputs, the data collected is appended and sent in the
requestVisitIDAPI. -
For multiple-page integration, the user enters the inputs on multiple screens, so the
profileTransactionAPI is used to append and send the user’s behavioral data for the current session. -
GAHCore.startProfileTransactionis used instead ofGAHCore.requestVisitIdduring the setup of the first page to obtain thevisitID.
For every registration page, it is recommended to place the setup code in viewWillAppear and clear the user’s behavioral data code in viewWillDisappear.
iOS samples
The following sample code snippet shows how to set up and clear data code on iOS.
Objective C
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self setupBehavioSec];
[GAHCore startPrefetchSignals];
}
-(void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self clearBehavioSecData];
}
-(void)setupBehavioSec {
//initialize BehavioSec object
self.bSDK = [BehavioSecIOSSDK sharedIOSSDK];
//Register UI elements
self.bSDK addInformation:@"<page_definition_identifier>" withName:@"viewIdentifier"];
[self.bSDK registerKbdTargetWithID: self.inputTextField andName:@"<id_defined_in_page_definition>" isAnonymous:YES];
//Set BehavioSec Object to GAH SDK
[GAHCore setBehavioSecObject:self.bSDK];
//enable TouchSDK and start motion detects
[self.bSDK enableTouchSDKWithViewController:self];
[self.bSDK startMotionDetect];
}
-(void)clearBehavioSecData{
[self clearTextFieldData];
//Below function will clear all BehavioSec data collected, clear all registrations and stop the motion detects
[GAHCore clearTransactionResources];
}
Swift
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
setupBehavioSec()
GAHCore.startPrefetchSignals()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillAppear(animated)
clearBehavioSecData()
}
func setupBehavioSec() {
//initialize BehavioSec object
self.bSDK = BehavioSecIOSSDK.shared()
//Register UI elements
self.bSDK.addInformation("<page_definition_identifier>", withName: "viewIdentifier")
self.bSDK.registerBtnTarget(withID: self.inputTextField, andName: "<id_defined_in_page_definition>", isAnonymous: true)
//Set BehavioSec Object to GAH SDK
GAHCore.setBehavioSecObject(self.bSDK)
//enable TouchSDK and start motion detects
self.bSDK.enableTouch(with: self)
self.bSDK.startMotionDetect()
}
func clearBehavioSecData() {
clearTextFieldData()
//Below function will clear all BehavioSec data collected, clear all registrations and stop the motion detects
GAHCore.clearTransactionResources()
}
Set your first page
-
On the first entry screen of the registration flow, call
GAHCore.startProfileTransactionto obtain thevisitIDbefore allowing user interaction. You can also obtain thevisitIDbefore this step. -
Call
profileTransactionto send the user's behavioral data when the user has finished entering the input fields and is about to move to the next screen.
In the following sample code snippet, you can:
-
Call the
startProfileTransactionAPI inviewDidLoadto start the session. -
Call
profileTransactionwhen the user clicks next to proceed to the next screen.
Only use the startProfileTransaction API to obtain the visitID when you are integrating the NAF feature on multiple pages. Do not use the GAHCore.requestVisitID method because it might send redundant data to the server, which can lead to errors in dashboard entries.
The following sample code snippet shows how to set up the first page on an iOS device:
Objective C
- (void)viewDidLoad {
[super viewDidLoad];
[GAHCore startPrefetchSignals];
[GAHCore startProfileTransaction:^(NSString *visitID) {
//store visitID to get the fraud decisions when calling registration API;
} failure:^(NSInteger errorCode, NSString *errorMessage) {
}];
}
-(IBAction)nextButtonPressed:(id)sender {
if ([self isValidTextFieldInput]) {
//Do profiling and move to the next screen
[GAHCore profileTransaction:^(NSInteger statusCode, NSString *statusMessage) {
}];
[self moveToTheNextScreen];
}
}
Swift
override func viewDidLoad() {
super.viewDidLoad()
//should stop user interaction before getting the visitID
GAHCore.startPrefetchSignals()
GAHCore.startProfileTransaction({ (visitID) in
//store visitID to get the fraud decisions when calling registration API
}) { (errorCode, errorMessage) in
//handle error and retry
}
// Do any additional setup after loading the view.
}
@IBAction func registerButtonPressed(_ sender: UIButton) {
if (isValidTextFieldInput()) {
//Do profiling and move to the next screen
GAHCore.profileTransaction { (statusCode, statusMessage) in
//handle error or just ignore the return
}
}
}
Set subsequent pages
-
Call the
profileTransactionAPI. -
Proceed to the next page.
The following sample code snippet shows how to set up subsequent pages on iOS:
Objective C
-(IBAction)nextButtonPressed:(id)sender {
if ([self isValidTextFieldInput]) {
//Do profiling and move to the next screen
[GAHCore profileTransaction:^(NSInteger statusCode, NSString *statusMessage) {
}];
[self moveToTheNextScreen];
}
}
Swift
@IBAction func registerButtonPressed(_ sender: UIButton) {
if (isValidTextFieldInput()) {
//Do profiling and move to the next screen
GAHCore.profileTransaction { (statusCode, statusMessage) in
//handle error or just ignore the return
}
}
}
Set your last page
-
Call the
profileTransactionAPI. -
Wait for the
profileTransactionAPI to complete. -
Clear the
visitIDthat is associated with this operation by callingfinishProfileTransaction. -
Continue with the application registration process.
The following sample code snippet shows how to set up your last page on an iOS device:
Objective C
-(IBAction)registerButtonPressed:(id)sender {
if ([self isValidTextFieldInput]) {
[GAHCore profileTransaction:^(NSInteger statusCode, NSString *statusMessage) {
if (statusCode == RESULT_STATUS_CODE_OK) {
//Clear visitID associated with this operation
[GAHCore finishProfileTransaction];
//Call app's API to register for new account.
//The visit Id obtained in the first page will be sent to get fraud decisions
[self registerNewAccountWithVisitId:self.currentVisitID];
} else {
//Handle error
}
}];
}
}
Swift
@IBAction func registerButtonPressed(_ sender: UIButton) {
if isValidTextFieldInput() {
//Do profiling and move to the next screen
GAHCore.profileTransaction { (statusCode, statusMessage) in
if statusCode == RESULT_STATUS_CODE_OK {
//Clear visitID associated with this operation
GAHCore.finishProfileTransaction()
//Call app's API to register for new account.
//The visit Id obtained in the first page will be sent to get fraud decisions
self.registerNewAccount(withVisitId: self.currentVisitId)
}
}
}
}
Known issue
On iOS, when TouchSDK is enabled for NAF, there are intermittent false negative problems for BOT detection (BotDesc15) when integrating for multiple pages. iPhones sometimes record touches with errors in the key timings. This causes BehavioSense to flag sessions with BotDesc15 (https://developer.behaviosec.com/docapi/5.2/#bot-description-codes).
The workaround for this issue is to disable BotDesc15 in the page definitions for gesture data (type fg - TouchSDK) on all affected pages.
Android setup
The setup for multiple-page integration is similar to single-page integration (step 1 - 4), with the following exceptions:
-
GAHCore.startProfileTransactionis used instead ofGAHCore.requestVisitIdduring the setup of the first page to obtain thevisitID. -
TouchSDKandDeviceSDKobjects are not passed toGAHCore.setBehavioSecTouchDeviceObject. Instead, these objects are used at the end of page later during the call toGAHCore.profileTransaction.
Set up all pages
The following setup process applies to all pages:
-
Extend BehavioSec
BehavioAbstractActivity.BehavioSec also provides
BehavioAppCompactActivityandBehavioAbstractFragmentforAppCompatActivityandFragmentuse cases. Refer to be BehavioSec documentation for details. -
Override the
initActivitymethod:-
Set the page name by calling
BehavioTimings.setPageName(). -
Use
BehavioEditText,BehavioMaskedEditText, orBehavioAnonymousEditTextprovided by BehavioSec and set the ID by callingsetFieldName.
-
-
Override
dispatchTouchEventbecauseTouchSDKhas to get information about every interaction with the application. -
In
onResume, create theTouchSDKandDeviceSDKobjects to start the data collection.
You can only do data collection when the application is active by stopping the data collection in onPause.
The following sample code snippet shows how to set up the first page on an Android device:
// 1. extend activity
public class RegistrationFirstPageActivity extends BehavioAppCompatActivity {
private BehavioEditText mUsernameEditText;
private TouchSDK mTouchSDK;
private DeviceSDK mDeviceSDK;
// 2. override initActivity
@Override
public void initActivity() {
setContentView(R.layout.activity_registration);
// i. set page name
BehavioTimings.setPageName("<page_definition_identifier>");
// ii. set id for textfields
mUsernameEditText = (BehavioEditText)findViewById(R.id.text_username);
mUsernameEditText.setFieldName("<id_defined_in_page_definition>");
}
// 3. override dispatchTouchEvents
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (mTouchSDK != null) {
mTouchSDK.addTouchEvent(ev);
}
return super.dispatchTouchEvent(ev);
}
// 4. create TouchSDK and DeviceSDK
@Override
protected void onResume() {
super.onResume();
if (mTouchSDK == null){
ViewGroup viewGroup = findViewById(R.id.activity_viewgroup);
mTouchSDK = new TouchSDK(getApplicationContext(), viewGroup);
mDeviceSDK = new DeviceSDK(getApplicationContext());
// mTouchSDK and mDeviceSDK will be used later as input to profileTransaction
}
// i. start data collection
mTouchSDK.startDataCollection();
}
// 5. stop data collection in onPause
@Override
protected void onPause() {
super.onPause();
if (mTouchSDK != null){
mTouchSDK.stopDataCollection();
}
}
}
Set your first page
-
On
onStart, callGAHCore.startProfileTransactionto obtain thevisitIDbefore allowing user interaction.You can also obtain visitID earlier prior to this step:
-
Call the
GAHCore.startProfileTransactionAPI. -
Wait for the callback.
Only use the
GAHCore.startProfileTransactionAPI to obtain thevisitIDwhen you are integrating the NAF feature on multiple pages. Do not use theGAHCore.requestVisitIDmethod because it might send redundant data to the server, which might lead to errors in dashboard entries. -
-
After the user has finished entering the input fields, call the
GAHCore.profileTransactionAPI. -
Clear the input fields and BehavioSec data by calling the
GAHCore.clearTransactionResourcesmethod. -
Proceed to the next page.
The following sample code snippet shows how to set up the first page on an Android device:
// 1. obtain visitID
@Override
protected void onStart() {
// i. call startProfileTransaction
GAHCore.startProfileTransaction(new GAHResponseCallback() {
@Override
public void success(String visitId) {
// ii. wait for callback
// proceed with the page setup
}
@Override
public void error(int errCode, final String errorMsg) {
// handle error, do not proceed with next page. Because profileTransaction requires visitID obtained.
}
});
}
public void nextButtonTouched(View view) {
// 2. call profileTransaction
GAHCore.profileTransaction(mTouchSDK, mDeviceSDK, null,
(statusCode, statusString) -> {}
);
// 3. clear the textfields and touchSDK
GAHCore.clearTransactionResources();
mTouchSDK = null;
mDeviceSDK = null;
// 4. go to next page
Intent intent = new Intent(this, RegistrationSecondPageActivity);
startActivity(intent);
}
Set subsequent pages
-
After the user has finished entering the input fields, call the
GAHCore.profileTransactionAPI. -
Clear the input fields and BehavioSec data by calling the
GAHCore.clearTransactionResourcesmethod. -
Proceed to the next page.
The following sample code snippet shows how to set up the subsequent pages on an Android device:
public void nextButtonTouched(View view) {
// 1. call profileTransaction
GAHCore.profileTransaction(mTouchSDK, mDeviceSDK, null,
(statusCode, statusString) -> {}
);
// 2. clear the textfields and touchSDK
GAHCore.clearTransactionResources();
mTouchSDK = null;
mDeviceSDK = null;
// 3. go to next page
Intent intent = new Intent(this, RegistrationThirdPageActivity);
startActivity(intent);
}
Set your last page
-
After the user has finished entering the input fields, call the
GAHCore.profileTransactionAPI. -
Clear the input fields and BehavioSec data by calling the
GAHCore.clearTransactionResourcesmethod. -
Wait for the
GAHCore.profileTransactionfunction to complete. -
Clear the visitID that is associated with this operation by calling
GAHCore.finishProfileTransaction. -
Continue with the application registration process.
The following sample code snippet shows how to set up the last page on an Android device:
public void nextButtonTouched(View view) {
// 1. call profileTransaction
GAHCore.profileTransaction(mTouchSDK, mDeviceSDK, null, (statusCode, statusString) -> {
// 3. wait for completion
// 4. clear visitID
GAHCore.finishProfileTransaction();
if (statusCode == GAHErrorCodes.RESULT_STATUS_CODE_OK) {
// 5. continue with registration process
} else {
// handles error
}
});
// 2. clear the textfields and touchSDK
GAHCore.clearTransactionResources();
mTouchSDK = null;
mDeviceSDK = null;
}