Categories
Support Corner

Support Corner: Protecting React Native Apps

Reading Time: 3 minutes

We’ve recently worked with a handful of customers in the process of creating React Native apps. As with other mobile development frameworks, it is relatively easy to reverse engineer and tamper with React Native apps. For this reason, it’s essential to secure your organization’s IP and data before publishing. In the following article, we’ll discuss how to do so using PreEmptive.

React Native apps are primarily written in JavaScript, then packaged as an APK, AAB, or IPA file for deployment. Once the app is installed on a device, the end user can extract an APK and see the bundled JavaScript file within the “assets” directory. The bundle will be minified during the build, but this can easily be unminified and formatted by a text editor such as Nodepad++ with JSTool. Doing so would reveal API calls, keys, and sensitive strings:

JavaScript can also interface with Native Java modules. Java is compiled and embedded in the APK as one or more classes.dex file(s). A tool such as ByteCode viewer can decompile the classes.dex to reveal sensitive IP within Java source:

Leaving code exposed in such a way is quite dangerous. A hacker could clone the app, infiltrate back-end systems, initiate a data breach, and more. Luckily, PreEmptive can protect the code embedded in the APK. JSDefender for JavaScript can protect the JavaScript bundle. DashO Java obfuscator can protect the Java code.

JSDefender’s Metro plugin and DashO’s Gradle plugin integrate protection directly into our build.

metro.config:

build.gradle:

When building the React Native project

>npx react-native run-android 

or 

>gradlew clean assembleRelease or bundleRelease


PreEmptive can be seen running in the build output:

After this build, binary is hardened against decompilation, reverse engineering, and tampering:

The full source code sample can be downloaded here.

In order to run the sample:

  • Download the JSDefender (trial or commercial) Core and Metro npm packages. 
  • Configure the JSDefender license key in jsdefender.config.json. 
  • Install and register PreEmptive DashO (trial or commercial) on your machine.
  • Run npm install within the directory. 

If you have feedback on this topic or any other topics you would like us to discuss in the Support Corner, please contact us.

 

 

 

 

Categories
Support Corner

Protecting C# Applications That Use Friend Assemblies

Reading Time: 2 minutes

The internal keyword in C# restricts access of types and members to callers in the same assembly. The InternalsVisibleTo attribute is a special way to grant internals access to a “Friend” assembly. Friend assemblies are used when unit testing, as internal members must be directly invoked by a test DLL. So it is quite common to have several friend assemblies in our project.

 

Dotfuscator takes friend assemblies into consideration when applying protection settings. It follows a specific process to preserve runtime behavior while performing as much obfuscation as possible. It also notifies us of any potential issues with friend assemblies during the build.

 

Please consider the following example, a DLL has InternalsVisibleTo an EXE file:

 

 

The EXE file directly references an internal class, made possible only by adding the InternalsVisibleTo attribute in the DLL: 

When obfuscating only the DLL, one of the following warnings would be shown, depending on the Dotfuscator configuration:

 

WARNING: MyAssembly has non-input Friend Assemblies and is in Library Mode; internal members will not be renamed or pruned. Consider adding Friend Assemblies as input for increased obfuscation.

OR 

WARNING: MyAssembly has non-input Friend Assemblies and is not in Library Mode; internal members may be renamed or pruned. References from non-input Friend Assemblies to the internal members of MyAssembly may no longer be valid.

 

The first message occurs when Dotfuscator is run in Library Mode. In Library Mode, Dotfuscator will not rename public and protected members for reusability of obfuscated components (as with APIs). Because of the InternalsVisibleTo attribute, Dotfuscator will also skip the renaming of internals. This will result in less Rename obfuscation than we may have anticipated, but it also will not break any runtime behavior. 

 

The second message warns that Dotfuscator may rename internals in a way that could break calls from the friend assembly.  If the friend assembly is deployed with this obfuscated DLL, this could cause a runtime error. If the friend assembly is not deployed (as with a unit testing DLL) then this warning will have no runtime impact and can be disregarded.

 

In general, obfuscation works best when more parts of the application are obfuscated together. The above warnings will completely disappear if the friend assembly is included as Dotfuscator input. If this is not feasible, we can still process the assemblies in Library mode but with less obfuscation.

 

The full example can be downloaded here.


Be on the look out for our next Support Corner blog!

 

Categories
Support Corner

How to Leverage Incremental Obfuscation when Protecting Large Applications

Reading Time: 2 minutes

In the previous Support Corner article, we discussed the significance of Cross-Assembly Obfuscation when configuring Dotfuscator.  Cross-Assembly Obfuscation ensures that classes, methods, properties and their references are automatically renamed uniformly across all Dotfuscator inputs.

Separated Assemblies Obfuscated

When related assemblies are obfuscated separately, they’re processed in Library Mode by default.  Library Mode does not rename public and protected types and members so that they can still be called by assemblies not included in that Dotfuscator project.  (Obfuscation transforms like Control Flow, String Encryption, and Tamper detection will be performed regardless of access modifier).

What if the different components of our app must be obfuscated as separate projects, but we still want to fully rename public types and members? This can be achieved by using Incremental obfuscation.

Incremental obfuscation

Incremental obfuscation uses Dotfuscator’s Rename Map file to maintain consistent identifier renaming across Dotfuscator builds.  It was created to enable patching a subset of assemblies for an obfuscated app already in production.  It can also be used to rename serializable types, so that full Renaming can still be performed on apps that persist serializable types to file. 

Along these same lines, Incremental Obfuscation can be used to maximize renaming when separating components of an app into multiple Dotfuscator projects.  

Example:

Consider the following example: a company maintains a set of common assemblies used by several different projects.  Each project has completely different sprints and release cycles.  In this scenario, the team maintaining the common assemblies uses Dotfuscator to fully obfuscate and rename publics.  They store the Rename Map file with their build artifacts.  Any team creating a front-end app will use that map file to rename references to the shared assemblies in their Dotfuscator project.  Only the map file is needed – they do not need to re-obfuscate the common assemblies.  When it’s time to deploy to production, all public and protected types and members for the full application will be renamed.

A simple example illustrating this concept can be downloaded here.


If you have feedback on this topic or other topics you would like us to discuss in the Support Corner, please feel free to contact our Support Department.