Securing React Native Application

Discover a ways to develop secure react native application.

KPITENG

Key Points -

  • Screenshot Prevention
  • Rooted/ Jailbroken Device Detection
  • SSL Pinning
  • Storage of Sensitive Data — API EndPoint / FB / Google / Firebase Keys
  • Local Storage
  • Deep Linking
  • Android Specific Security
  • iOS Specific Security
  • Authentication Methods
  • Data Encryption

1. Screenshot Prevention

iOS Integration -

Screenshot Restriction is not possible on Straight Forward Way, But you can do something like, When application InActive — add Blur Layer/ View on window and when Active — remove BlurLayer/View.

Add Following Lines of Code in AppDelegate.m

Android Integration -

In Android it’s quite simple to restrict user to prevent taking screenshot — Go to MainActivity.java

Another way to prevent for screenshot — Go to MainActivity.java, In onCreate method add lines marked as +.

2. Rooted/ Jailbroken Device Detection

iOS Integration -

To detect iOS devices is Jailbroken, use following code. You need to create React Native Native Module and integrated iOS Code in iOS Project.

We will check following to detect Jailbroken devices -

  • Check if Cydia is installed
  • Check if the app can edit system files
  • Check if the system contains suspicious files
  • Check if other suspicious apps (FakeCarrier, Icy, etc.) is installed
  • Check if Cydia is installed with alternative names (using URIScheme)

Also, don’t forget to add “Cydia” in LSApplicationQueriesSchemes key of info.plist. Otherwise canOpenURL will always return false.

Android Integration -

Rootbear library helps in detection of rooted devices. Simply follow steps of installation and using React Native Native Module you can access Rootbear functions to detection of rooted devices.

Library will check following to detection of Rooted Devices

  • checkRootManagementApps
  • checkPotentiallyDangerousApps
  • checkRootCloakingApps
  • checkTestKeys
  • checkForDangerousProps
  • checkForBusyBoxBinary
  • checkForSuBinary
  • checkSuExists
  • checkForRWSystem

It’s simple to integrate in Code -

SafetyNet Android-only API that helps in the detection of rooted devices and bootloader unlocks. It also provides security against security threats, device tampering, malicious apps, and fake users.

The react-native-google-safetynet, which is a wrapper plugin for SafetyNet’s API, can also be used to verify the device of the user. The react-native-device-info plugin can be used to see if the app is being run on an emulator.

3. SSL Pinning

SLL Pinning can be done using 3 different ways

  • Public Key Pinning
  • Certificate Pinning
  • Subject Public Key Info (SPKI) Pinning

iOS Integration — Place your .cer files in your iOS Project. Don’t forget to add them in your Build Phases — Copy Bundle Resources, in Xcode

Android Integration — Place your .cer files under src/main/assets/

iOS — drag .cer to Xcode project, mark your target and “Copy items if needed”

iOS — drag .cer to Xcode project, mark your target and “Copy items if needed”. No Extra steps needed for public key pinning. AFNetworking will extract public key directly from certificate.

Android — public key should be extracted by following command, simply replace google with your domain.

4. Storage of Sensitive Data — API EndPoint / FB / Google / Firebase Keys

Never store your API EndPoint, AccessKey, Firebase, Google/FB Social Key directly into Code. Your bundle can be decoded into plaintext and all information can be extracted.

It’s recommended to use react-native-config and react-native-dot-env to place your secure key, endpoint.

Note: react-native-config module doesn’t encrypt secrets for packaging, so do not store sensitive keys in .env file.

5. Local Storage

Developer often needs to store data locally, sometime developer prefer asyncstorage to store accesskey/ access-token/ user token. But AsyncStorage is un-encrypted storage, so information can be extract from AsyncStorage.

React Native does not provide solution for secure data storage. There are pre-existing solution in iOS & Android we all know about iOS Keychain and Android Keystore.

iOS Keychain -

In iOS we use Keychain Services which allows developers to securely store sensitive information like certificates, tokens, securekeys, passwords, and any other sensitive information like secrets of open platform services which we are using in our application.

Android Keystore -

The Android Keystore allows developers to store cryptographic keys in a container to make it more difficult to extract from the device. Once keys are in the keystore, they can be used for cryptographic operations with the key material remaining non-exportable.

To use iOS Keychain & Android Secure Shared Preferences from React Native, you can use following NPM.

Note: redux-persist-sensitive-storage uses react-native-sensitive-info with redux-persist. react-native-sensitive-info manages all data stored in Android Shared Preferences and iOS Keychain. Android Shared Preferences are not secure, but there is a branch of react-native-sensitive-info that uses the Android key-store instead of shared preferences. You can use that branch with redux-persist-sensitive-storage if you prefer.

6. Deep Linking

Deep linking is a way to open application from other sources. Deep Link contains textual data along with Link. Like yourappname://

Let’s say you have E-Commerce application and your deep link is yourappname://products/1 means it will open your app with detail of product 1.

Deep links are not secure and you should not append any sensitive information in deep link.

There is no centralised method of registering URL schemes. As developer, you can use any URL scheme you choose by configuring it in Xcode for iOS or adding an intent on Android.

Malicious app can hijack your data by also using the same scheme and then obtaining access to the data your link contains. Sending something like yourappname://products/1 is not harmful, but sending tokens is a security concern.

iOS allows one single URL Scheme to be claimed by multiple apps. For instance, sample:// can be used by two completely separate apps in their implementation of URL Schemes. This is how some malicious apps can take advantage of the URL Scheme and compromise users.

Apple introduced Universal Links in iOS 9 as a solution to the lack of graceful fallback functionality in custom URI scheme deep links. Universal Links are standard web links that point to both a web page and a piece of content inside an app.

When a Universal Link is opened, iOS checks to see if any installed app is registered for that domain. If so, the app is launched immediately without ever loading the web page. If not, the web URL (which can be a simple redirect to the App Store) is loaded in Safari.

Setting up a universal link (HTTP or HTTPS) login interface, and musing a random identifier to authenticate the received login token locally, prevents hijacking and malicious login token replaying.

7. Android Specific Security

Let’s see how to protect our APK or app bundle from reverse engineering attacks.

Hackers can easily access our Codebase by doing reverse engineering with APK or app bundle file. To avoid it we can add Pro Guard rules. Pro Guard obfuscates your code. So if someone reverse engineer it, it’s not readable and saves you from engineering attacks. Pro Guard also used to reduces APK size by removing unused code and resources. If your project contain any third party library then you can add the Pro Guard rules of that library in your rules file.

To enable Pro Guard rule we have to enable the minifyEnabled property in app/build.gradle file.

8. iOS Specific Security

Let’s see how we can restrict the insecure domains usage in iOS. It will save us from transport layer attacks. You can restrict insecure domains by configuring some properties within your Info.plist file.

Now, let’s see what you should add in your Info.plist file for that.

From iOS 9.0 Apple has introduced NSAppTransportSecurity which you can find inside info.plist file. Inside NSAppTransportSecurity there is one key NSAllowArbitraryLoads which is set to NO by default that means you are agreed with security benefits. In some cases while you are working with localhost or with HTTP domain if required then you have to make it YES otherwise you can’t make network request with those insecure domains.

There are chances that your app might get rejected while uploading it to apple store because you set NSAllowArbitraryLoads value as YES. To overcome that you can use NSExceptionDomains by providing a list of domains inside that. Application will consider like you have agreed to all over security benefits excepts the domain those domains which you have mentioned in NSExceptionDomains (although you have set NSAllowArbitraryLoads value as YES).

9. Authentication Methods

Nowadays OAuth has become more popular for Authentication between one application interacting with another application. Consider a case where your application communicates with an API to send/retrieve data from the server. How do servers know the coming request is authenticated? OAuth 2.0 makes the authentication process simple for you. Instead of sharing passwords OAuth allows authentication using Token. It’s an approach to use JWT Token for API Authentication.

10. Data Encryption

Crypto JS is popular Javascript library for crypto standards. To store, send data to server it’s approched to Encrypt data using CrytpJS. So, it’s is not redable by enable directly.

What Next?

Top 10 React Hooks Library

How to improve the performance of React Native App?

Thanks for reading full article!

Read More Technical Articles

KPITENG || hello@kpiteng.com ||DIGITAL TRANSFORMATION

Connect Us — Linkedin | Facebook | Instagram

Founder & CEO at KPITENG