Improve Security in React Native

Improve Security in React Native

In the fast-paced world of mobile development, React Native has emerged as a powerful tool for crafting cross-platform applications with native-like performance. However, with this power comes a significant responsibility: ensuring the security of user data and application logic. While React Native itself boasts a solid foundation, vulnerabilities can creep in throughout the development process if not addressed proactively. This guide delves into the essential concepts and best practices for hardening your React Native application, transforming it into a secure haven for user information and application integrity.

In this blog, you will learn about best practices for storing sensitive information, authentication, network security, and tools that will help you secure your app.

And remember, although an ordinary padlock is pickable, it is still much harder to get past than a cabinet hook!

Source: https://reactnative.dev/docs/security#oauth2-and-redirects

Storing Sensitive Information

Because anything included in your code could be accessed in plain text by anyone inspecting the app bundle. So never store sensitive API keys in your app code. Here are a few cases where you need to define sensitive information in your code as mentioned below:

  • While building any application, it’s common that you have to make some server requests to get data and for that, you will need to define endpoints of APIs in your application.
  • You often require some third-party authentication integration, In that case, you need to define an application secret that is created on a third-party platform like Facebook or Google in your application to access their services.
  • Often you are required to use some services of open platforms like Firebase and Google to implement features like notifications, messaging, and analytics in your application. Here you also need to define the secret of an application created on an open platform in your application to access their services.

In my eyes, here are some security solutions to overcome sensitive information security issues:

Async Storage

In React Native we use Async Storage to save these data types in the device but Async Storage is an asynchronous unencrypted key-value store. React Native does not provide any solution for sensitive data storage. There are pre-existing solutions in Android and iOS platforms that we can use with React Native by setup it up on native side as iOS Keychain and Android Keystore.

Secure Storage

  • Use some libraries below instead of Async Storage to secure sensitive information in your app

- react-native-encrypted-storage
- react-native-keychain
- redux-persist-sensitive-storage

Authentication and Deep Linking

Mobile apps have a unique vulnerability that is non-existent on the web: deep linking. Deep linking is a way of sending data directly to a native application from an outside source. A deep link looks like app:// where app is your app scheme and anything following the // could be used internally to handle the request.

For example, if you were building an E-commerce app, you could use app://products/1 to deep link to your app and open the product detail page for a product with id 1.

Deep links are not secure and you should never send any sensitive information to them.

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.

OAuth2 and Redirects

The OAuth-2 authentication protocol is incredibly popular nowadays and prided as the most complete and secure protocol around. The OpenID Connect protocol is also based on this. In OAuth-2, the user is asked to authenticate via a third party. On successful completion, this third party redirects back to the requesting application with a verification code which can be exchanged for a JWT — a JSON Web Token.

An abstraction of the OAuth-2 Workflow

On the web, this redirect step is secure, because URLs on the web are guaranteed to be unique. This is not true for apps because, as mentioned earlier, there is no centralized method of registering URL schemes! In order to address this security concern, an additional check must be added.

To be more secure with OAuth-2 approach as an extension we can use SHA 256 cryptographic algorithm which ensures that the authentication and token exchange requests come from the same client. SHA 256 creates a unique “signature” for a text or file. The signature is always the same length and for the same inputs, the signature will always be the same. This whole process is known as Proof of Key Code Exchange (PKCE).

Now, let’s understand how it works.
For that first here we have to discuss two terminologies:

  • code verifier: A large random string generated by the client
  • code challenge: The SHA 256 of the code verifier
Proof of Key Code Exchange (PKCE)

Network Security

SSL encryption protects against the requested data being read in plain text between when it leaves the server and before it reaches the client. Using https endpoints could still leave your data vulnerable to interception.

SSL Pinning

SSL pinning is a technique that can be used on the client side to avoid this attack. It works by embedding (or pinning) a list of trusted certificates to the client during development, so that only the requests signed with one of the trusted certificates will be accepted, and any self-signed certificates will not be accepted.

To implement SSL Pinning in React Native you can refer to react-native-ssl-pinning.

Conclusion

Mobile apps written with React Native can be well-protected. It has its own cost and additional risks. To make your app secure, you need to follow the best practices of a secure software development lifecycle, define and address possible risks, plan your security controls, and prepare a remediation strategy. Invest your time in building a threat model for your application as it helps to bring together the security and usability of the app.