- JS Bundles
- https://github.com/vesselsoft/metro-minify-obfuscator
- https://github.com/jscrambler/jscrambler/tree/master/packages/jscrambler-metro-plugin
- https://github.com/MichaelXF/js-confuser - Adding this here as a note, because it could end up better than the
javascript-obfuscator, but it might require aRN / Metroimplementation with a working sourcemap1/2support.
- Android
Proguard/R8
- iOS
- Before deprecation,
BITCODEwas used. However there is a commercial one callediXGuard. - https://github.com/securevale/swift-confidential
- Before deprecation,
- JS are still easier to
decompile/deobfuscatethannative, so ideally, if you can, the more you implement in thenativeside, the better. That's why one of the recommendations below is to use a single point of implementation, withRustorC++.
- https://github.com/GantMan/jail-monkey
- https://github.com/react-native-device-info/react-native-device-info#isemulator
- https://github.com/atul7017128880/react-native-security-checker
- wumke/react-native-exit-app#85
- https://github.com/talsec/Free-RASP-ReactNative - https://docs.talsec.app/freerasp/features-and-pricing-plans#plans-comparison
- https://github.com/wultra/react-native-malwarelytics - https://developers.wultra.com/components/react-native-malwarelytics
- As to not support older versions. Having backend checks in place.
- https://github.com/kimxogus/react-native-version-check
- https://github.com/SudoPlz/sp-react-native-in-app-updates
- It may have
quotasfor verifications. I suppose it could becached, once per install. - https://github.com/pagopa/io-react-native-integrity
- https://rnfirebase.io/app-check/usage
- https://github.com/niteshbalusu11/react-native-secure-enclave-operations
- https://www.sigstore.dev
- https://github.com/anchore/syft
- https://github.com/CycloneDX/cyclonedx-gradle-plugin
- https://github.com/CycloneDX/cyclonedx-cocoapods
- https://github.com/CycloneDX/cdxgen
- https://github.com/sigstore/cosign
- AFAIK there is no
react-nativespecific package / setup for this, so, you would need to figure it out.
- https://babeljs.io/docs/babel-plugin-transform-remove-debugger
- These babel plugins should be installed, as it can also be removed from if also found in the libraries.
- For
auth tokensand any other data that may come from thebackendor that need to be temporarily storaged. - https://github.com/oblador/react-native-keychain
- If some things are not possible with
keychain, there is https://github.com/mrousavy/react-native-mmkv as alternative if used withencryption.
Do all things in the backend. The App / Web should be only for displaying data and taking action on it for the most part.
- You can make use of
Paseto(auth token) in the backend. - By using
Paseto, you can have two things, a less vulnerable alternative toJWTfor authentication, and verification of the payload with it'sprivate/publickey, similarly asHMAC Signatureintent, helps ensure the integrity of the data being transported. - Make use of
refresh tokenandaccess tokenpattern, whererefresh tokenonly serves to refresh theaccess tokenwhich should have duration of minutes, andaccess tokento request content only. - Use
argon2for password hashing. - Never return
databaseerror messages ordatathat may be sensitive, in errors fromAPIresponses, that should belogged/reportedto the developer, to befixed. Thefrontendshould only know that an error happened and the admin or developer are aware, butvalidationerror messages can be returned. - You can opt to use multiple login types (
MFA - Multi Factor Auth), nopasswordmight be safer, so there isOTPauth as option, be throughemail,SMSor some othermessaging toolto receive the code.2FAcan be an additional security option.HOTPorTOTP.
- Be sure to have
rate limitset for all endpoints / queries. - Never return all data per
endpoint / query, make sure to return / make availableonlythe data needed for a specificcontext. Be through permissions or not. Data is tofill the requirementsof the app / web, not to return because it's there or part of it.
- You could send specific information from the smartphone like a combined string
uniqueDeviceId+deviceManufacturer+modeland tie theauth tokento it. That way, it cannot be used in another device. - You can session limit with device binding. Like one device at the time or more.
Public Key Pinningare known to be a better option.- https://github.com/frw/react-native-ssl-public-key-pinning
- https://github.com/huytdps13400/react-native-ssl-manager
- There are things that point to being easy to
bypass pinning, though with checks and actions in place forjailbreak, rooted, emulators and hooks(but not only), can help reduce or even completely prevent the possibility of this.
- It could help make it more safer and provide better usage experience
- https://github.com/smallcase/react-native-simple-biometrics
- https://github.com/sbaiahmed1/react-native-biometrics
- https://github.com/chubo274/react-native-biometrics
- But this would be something optional like
2FAis in some cases. - https://github.com/f-23/react-native-passkey
- For
encryptionwork, I would say to do in thebackend, but if not possible. - https://github.com/margelo/react-native-quick-crypto
- https://github.com/serenity-kit/react-native-libsodium
- Why in the backend? Same reason why all that is possible should be done in the backend. Because it encapsulates / hides the implementation and intent.
- https://babeljs.io/docs/babel-plugin-transform-remove-console
- This means no
consolebased nor any other logginglibusage. - However if doing specific types of logging based on user interactivity, make sure that no sensitive data are included.
- https://github.com/mowispace/react-native-logs - Use a non-console option instead.
- This should be prioritized in the backend, but it's fine on app too.
- https://github.com/colinhacks/zod
- https://github.com/cure53/DOMPurify for
HTMLin case you use Webview. But preferably, opt-out. - https://github.com/validatorjs/validator.js
- Use only the best options (most used) available and keep to a minimum.
- Have something in place to auto-upgrade the packages and do code upgrades if major changes are needed.
- Use tools like
pnpmoryarnlatest versions for further install protections.
- SAST involves analyzing the source code to identify potential security vulnerabilities without actually executing the code.
- https://www.sonarqube.org
- https://sonarcloud.io
- DAST involves interacting with a running instance of the application to identify security issues.
- https://github.com/MobSF/Mobile-Security-Framework-MobSF
- https://github.com/paulveillard/cybersecurity-dast
- https://github.com/wn-na/react-native-capture-protection
- https://github.com/gbumps/react-native-screenguard
- Even
OAuth2/OpenIDcan be a secure alternative form of authentication. Recommended to be mostly implemented in thebackend. - https://github.com/sbaiahmed1/react-native-google-auth
- https://github.com/FormidableLabs/react-native-app-auth
- While the integrity options above are a way to check, it's not the same.
- Currently, this might require some manual work on the native side. As well as managing generated certs. Since currently, there is no good library for this.
- Always combine with backend checks where possible, not only on the client-side, since that can be bypassed.
- You can generate checksum or certs based manually through the CI for both
nativeandjsbundles. But it takes more work. And probably would require some other implementationnativelyand injs. - There is this library
but it is very outdated has too many dependencies, seems like a bad package, not recommended.react-native-app-integrity-checksum
https://github.com/bamlab/react-native-app-security - Mix of checks, left it here, but other standalone options are likely better.
- Never use
deep linksfor sensitive data - Make sure to restrict schemes
- Whilelist domains / hosts
- Validate / Sanitize query params
- No sensitive
env varsin the frontend/app. - But there is a safer option than
react-native-configandreact-native-dotenv, that can helpenv varsthat are not possible to have the setup in thebackend- https://github.com/numandev1/react-native-keys- Currently
react-native-keysstill has ways to go to be free of vulnerabilities. But at this point it's the safer option. - Who knows, at some point, someone might make a better option dmno-dev/varlock#226
- Currently
- Setup the
CIto have dependencyvulnerabilitieschecks withsnykor some other tool. - https://github.com/aquasecurity/trivy
- https://github.com/RetireJS/retire.js
- https://github.com/NodeSecure/cli
- https://github.com/semgrep/semgrep
pnpm / yarn / npm audit- https://github.com/lirantal/npq - It may help identify vulnerabilities in packages before you install.
- Develop
nativefunctionality in a single point rather than inJava/KotlinandObjC/Swift, this way it can help prevent bugs and even security issues. - I would recommend in
Rust - But, if you prefer
C++, there is https://github.com/mrousavy/nitro as alternative.
- It could help provide faster
hotfixesin case some security issue are discovered or bad impl are done. It's on theJSside only. - https://github.com/gronxb/hot-updater - This tool seem to be working to be more than that.
Lintare recommended due to it's checks which can help prevent security issues.Typesare recommended withTypescript, with proper configuration, you can enforce additional good practices, therefore having less bugs, so leading to less security issues.- All should be enforced in both
devenvironment andCI.
- Recommended at least in crucial parts of the app, and backend.
- Good tests will check for things that should not be possible, so, it can help prevent security issues.
- https://jestjs.io -
Jestare still the recommended choice inReact Nativedue to better support with other libraries. Other equivalent libraries are not that well supported or not at all. - https://callstack.github.io/react-native-testing-library -
ComponentandIntegrationtests. - https://wix.github.io/Detox for
E2Etests.
For the backend, if starting something new, I would recommend Rust or DenoJS which are rust-based, both are likely to have less vulnerabilities. Just my opinion though.
- Your data is a
secureas you made yourbackendto be. In all ends of it.- OS always keep to a minimum in
packages, always updated. - There are
hardenedkernels and many other things that can be done to increase security in the OS part. e.g., https://madaidans-insecurities.github.io/guides/linux-hardening.html - API preferably
containerized. - Everything
isolatedandharderto access, withstrictconfigurations, and so on. And not just what you or someone else know, but researched and updatedconfigto latest and safest approaches. - Ideally ALL should be
automated, to have predictable actions done to theserver, as to prevent things done by someone, where someone else would not know about it. Everythingstored in a repo/commited, of course.
- OS always keep to a minimum in
- If not starting new, and there is a legacy system that requires scaling and need a rewrite,
Rustcan be a great alternative too.
There are other things, that can also help, but those are more specific things like configurations, those you should search by yourself.
- One example being related to android
apk signing, onlyv4being free of known vulnerabilities. - Fstack Protector
- In ios (xcode), select the target in the
Targetssection, then click theBuild Settingstab, make sure that the-fstack-protector-alloption is selected in theOther C Flagssection and thatPosition Independent Executables (PIE)support is enabled. - In android,
android/build.gradlein one of the build configurations, make sure thatcmake > cppFlagshas-fstack-protector-allas one of it's setting.
- In ios (xcode), select the target in the
Like everything else, it's your responsibility to confirm whether your implementation are working by adding checks / doing security analysis.
Be sure to check each package before using.
Some additionals suggestion by Gemini 2.5 - https://pastebin.com/raw/uyaeKjsr