Protect sensitive data
As with any third-party service, it’s important for you to understand and have the ability to manage what data is sent to Shake servers. Shake SDK allows you to filter out sensitive data on the mobile device itself, so it never reaches the Shake servers.
Automatically redacted sensitive data
Shake automatically redacts these sensitive data from your notifications, touch events and network requests:
- email addresses
- IP addresses
- credit card numbers
- bearer tokens
Shake also redacts network header values if the header key is:
- password
- secret
- passwd
- api_key
- apikey
- access_token
- auth_token
- credentials
- mysql_pwd
- stripetoken
- Authorization
- Proxy-Authorization
- card[number]
- token
To disable this privacy feature, use the method below:
- Objective-C
- Swift
SHKShake.configuration.isSensitiveDataRedactionEnabled = false;
Shake.configuration.isSensitiveDataRedactionEnabled = false
Views
This feature is disabled for iOS applications built with SwiftUI.
You can mark any UIView or its subclasses as private. You can not mark UIBarItems (UIBarButtonItem, UIBarButtonItemGroup and UITabBarItem) as private since those are not UIVew subclasses.
You can mark any view as private, and it'll automatically be deleted from the auto screenshot. Private views are stored as a weak reference. They get cleared from the memory when not used anymore.
These methods won't delete sensitive views from auto screen recording — only from the auto screenshot.
Let's suppose you're building a shopping app and you want to delete the name and the credit card number views from the auto screenshot:
- Objective-C
- Swift
@import Shake;@import Stripe;- (void)maskSensitiveData {[SHKShake addPrivateView:textUserName];[SHKShake addPrivateView:textCardNumber];}
import Shakeimport Stripefunc maskSensitiveData() {Shake.addPrivateView(textUserName)Shake.addPrivateView(textCardNumber)}
To remove a view from private views use the following method:
- Objective-C
- Swift
[SHKShake removePrivateView:view];
Shake.removePrivateView(view)
If you want to delete an entire screen from the auto screenshot, simply mark the whole view controller as private:
- Objective-C
- Swift
@import UIKit;@import Shake;@import Stripe;@interface PaymentViewController: STPPaymentOptionsViewController@end@implementation PaymentViewController- (void)viewWillAppear:(BOOL)animated {[super viewWillAppear:animated];[SHKShake addPrivateViewController:self];}@end
import UIKitimport Shakeimport Stripeclass PaymentViewController: STPPaymentOptionsViewController {override func viewWillAppear(_ animated: Bool) {super.viewWillAppear(animated)Shake.addPrivateViewController(self)}}
To remove a view controller from the list of private views, use the following method:
- Objective-C
- Swift
[SHKShake removePrivateViewController:self];
Shake.removePrivateViewController(self)
To clear all the private views, use the following method:
- Objective-C
- Swift
[SHKShake clearPrivateViews];
Shake.clearPrivateViews()
You can disable Screen Recording feature if you want to make sure that sensitive data is not recorded.
- Objective-C
- Swift
SHKShake.configuration.isAutoVideoRecordingEnabled = false;
Shake.configuration.isAutoVideoRecordingEnabled = false
Touch events
Marking a view as private will automatically delete its touch events' text properties too.
Consequently, you'll see them as data_redacted
strings in ticket's
Activity history.
The view's ID, accessibility labels and tags remain visible.
Network requests
Network requests may contain sensitive data which you may not want to send to Shake servers.
Use the Shake.setNetworkRequestsFilter()
method to obfuscate sensitive parts of those requests,
or to entirely prevent certain network requests from being logged.
As an example, if you'd like to obfuscate the Authorization header in all network requests sent from your app, do this:
- Objective-C
- Swift
@import Shake;- (void)setupNetworkFilter {SHKShake.networkRequestsFilter = ^SHKNetworkRequestEditor * (SHKNetworkRequestEditor * networkRequest){NSMutableDictionary<NSString *, NSString *>* headers = networkRequest.requestHeaders;if (headers[@"Authorization"] != nil) {headers[@"Authorization"] = @"***";}return networkRequest;};}
import Shakefunc setupNetworkFilter() {Shake.networkRequestsFilter = { (networkRequest) inif networkRequest.requestHeaders["Authorization"] != nil {networkRequest.requestHeaders["Authorization"] = "***"}return networkRequest}}
If you don't want to log specific network requests, return nil
from the NetworkRequestsFilter
as shown below:
- Objective-C
- Swift
@import Shake;- (void)setupNetworkFilter {SHKShake.networkRequestsFilter = ^SHKNetworkRequestEditor *(SHKNetworkRequestEditor * networkRequest){if ([networkRequest.url.absoluteString hasPrefix:@"https://api.myapp.com/cards"]) {return nil;}return networkRequest;};}
import Shakefunc setupNetworkFilter() {Shake.networkRequestsFilter = { (networkRequest) inif networkRequest.url.absoluteString.hasPrefix("https://api.myapp.com/cards") {return nil}return networkRequest}}
To clear the network requests filter, use Shake.networkRequestsFilter = nil
.
Notification events
If your app notifications contain sensitive data, use the Shake.setNotificationEventsFilter()
method to fully or partially obfuscate those notifications.
For example, if you'd like to obfuscate the description of the notification event that contains an email, do this:
- Objective-C
- Swift
@import Shake;- (void)setupNotificationEventsFilter {SHKShake.notificationEventsFilter = ^SHKNotificationEventEditor *(SHKNotificationEventEditor * notificationEvent){if ([notificationEvent.title hasPrefix:@"E-mail changed"]) {notificationEvent.description = @"***@gmail.com";}return notificationEvent;};}
import Shakefunc setupNotificationEventsFilter() {Shake.notificationEventsFilter = { (notificationEvent) inif notificationEvent.title.contains("E-mail changed") {notificationEvent.description = "***@gmail.com"}return notificationEvent}}
If you do not want to track a specific notification event, return nil
from the notificationEventsFilter
like below:
- Objective-C
- Swift
@import Shake;- (void)setupNotificationEventsFilter {SHKShake.notificationEventsFilter = ^SHKNotificationEventEditor *(SHKNotificationEventEditor * notificationEvent){if ([notificationEvent.title hasPrefix:@"E-mail changed"]) {return nil;}return notificationEvent;};}
import Shakefunc setupNotificationEventFilter() {Shake.notificationEventsFilter = { (notificationEvent) inif notificationEvent.title.contains("E-mail changed") {return nil}return notificationEvent}}
To clear the notification events filter, use Shake.notificationEventsFilter = nil
.