Learn React Native - Network Security & TLS
Episode 14 of 23

Learn React Native - Network Security & TLS

This episode covers network security: TLS/SSL with the network security config on Android and App Transport Security on iOS, certificate pinning to prevent man-in-the-middle attacks, plus hardening to face bundle reverse engineering.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Introduction

Your app sends sensitive data over networks you can't trust: public Wi-Fi, carrier networks, or a proxy in the middle. Without proper protection, the data can be read or altered in transit.

Episode 14 covers network security: TLS with the network security config on Android and App Transport Security on iOS, certificate pinning to block man-in-the-middle attacks, plus hardening to face bundle reverse engineering.

HTTPS and TLS

Why HTTPS Is Mandatory

HTTPS runs data over TLS, which encrypts communication and verifies the server's identity via certificates. Without TLS, all data is sent as plain text and can be intercepted. The first rule: no request may use plain HTTP in a production app.

Certificate Verification

TLS is only secure if the server's certificate is verified. Man-in-the-middle attacks work by injecting a fake certificate; if the app accepts any certificate, the encryption becomes useless. Platforms have built-in verification, and the configurations below tighten it.

Android Network Security Config

Restricting Traffic to HTTPS

Android uses network_security_config.xml to manage network policy. Restrict the app so it only communicates over HTTPS:

network_security_config.xml
<network-security-config>
  <base-config cleartextTrafficPermitted="false">
    <trust-anchors>
      <certificates src="system" />
    </trust-anchors>
  </base-config>
  <domain-config cleartextTrafficPermitted="false">
    <domain includeSubdomains="true">api.example.com</domain>
  </domain-config>
</network-security-config>

cleartextTrafficPermitted="false" blocks ordinary HTTP traffic. This rule is enforced globally, then tightened per domain. Never allow cleartext for production — it opens the door to interception.

Pointing the Config in the Manifest

The config file is activated via an attribute in AndroidManifest.xml on the application element:

Enable in AndroidManifest
android:networkSecurityConfig="@xml/network_security_config"

iOS App Transport Security

ATS Defaults on iOS

iOS enforces App Transport Security (ATS) by default: ordinary HTTP connections are blocked unless explicitly exempted. ATS has been on since iOS 9, so an app that doesn't change the configuration is already protected.

Exempting Domains with Strict Rules

If a domain needs a non-HTTPS connection for development, register a limited exemption in Info.plist:

ATS exemption in Info.plist
NSAppTransportSecurity
  NSAllowsArbitraryLoads: false
  NSExceptionDomains
    localhost
      NSExceptionAllowsInsecureHTTPLoads: true

NSAllowsArbitraryLoads stays false for the whole app, and the exemption only covers localhost during development. Never bring such exemptions into a production build.

Certificate Pinning

Blocking Fake Certificates

Ordinary verification only checks that the certificate is signed by a trusted CA. Certificate pinning tightens this: the app only accepts a predetermined certificate or public key. That way, fake certificates from man-in-the-middle attacks are rejected.

Install react-native-ssl-pinning
npm install react-native-ssl-pinning
JSRequest with pinning
import { fetch } from "react-native-ssl-pinning";
 
fetch("https://api.example.com/data", {
  method: "GET",
  sslPinning: {
    certs: ["api-example"],
  },
  timeoutInterval: 15000,
});

The library compares the server's certificate with the api-example certificate bundled in the app. If they don't match, the request fails. certs: ["api-example"] refers to the certificate file name in the resources folder.

The Cost of Pinning

Pinning has a price: when the server certificate rotates, older apps that haven't updated can't connect. Install two pins (a backup pin) and plan rotation carefully. For many teams, pinning is enough on the most sensitive endpoints.

Hardening and Reverse Engineering

Shrinking the Attack Surface

The JavaScript bundle can be unpacked and read. A few basic mitigations:

  • Obfuscation: make code reading harder with a JavaScript obfuscator.
  • ProGuard and R8: for Android, enable minification and resource shrinking in the release build.
  • Tamper detection: check the app signature at runtime to detect modified versions.
  • Root and jailbreak detection: block sensitive features on rooted devices.

ProGuard for Android

Minification in build.gradle
buildTypes {
  release {
    minifyEnabled true
    shrinkResources true
    proguardFiles getDefaultProguardFile("proguard-android-optimize.txt")
  }
}

Keep in mind: no hardening makes an app 100 percent impossible to unpack. The goal is to raise the attack cost high enough that attackers pick another target.

Warning

Never store server secrets in a client app, no matter what hardening you install. Pinning, obfuscation, and ProGuard slow down reverse engineering — they don't stop it.

Closing

Episode 14 secured the data path: TLS with the Android network security config and iOS ATS, certificate pinning against man-in-the-middle attacks, and hardening like ProGuard and obfuscation to slow down reverse engineering.

Key takeaways:

  • HTTPS with certificate verification is the foundation of network security.
  • Block cleartext traffic on Android and keep ATS active on iOS.
  • Certificate pinning rejects fake certificates, but has a rotation cost.
  • Install a backup pin and plan certificate rotation.
  • Bundles can be unpacked; hardening only slows things down.
  • Server secrets must never be in a client app.

In the next episode, episode 15, we'll discuss authentication and authorization: JWT and OAuth 2.1, the refresh token flow, biometric authentication with Face ID and fingerprints, SSO, and the principle of never trusting client input.

Learn React Native - Network Security & TLS | Learn React Native