eslint-plugin-rn-security
v0.1.0
Published
ESLint rules for React Native security defects that generic JavaScript security plugins do not catch
Maintainers
Readme
eslint-plugin-rn-security
ESLint rules for React Native security defects that generic JavaScript security plugins do not catch.
Why this exists
There are good general purpose security linters for JavaScript. eslint-plugin-security covers dangerous sinks like eval and unsafe regular expressions. eslint-plugin-no-secrets finds hardcoded credentials. Use both.
Neither knows anything about React Native. They will not tell you that a WebView with originWhitelist={['*']} will load any origin including file://, that a token in AsyncStorage sits unencrypted on disk, or that a deep link handler is passing an attacker supplied URL straight into navigation.
This plugin covers only that gap. Six rules, all React Native specific, all statically detectable.
Install
npm install --save-dev eslint-plugin-rn-securityRequires ESLint 8.40 or later and Node 18 or later.
Usage
Flat config (ESLint 9)
// eslint.config.js
import rnSecurity from 'eslint-plugin-rn-security'
export default [
rnSecurity.configs.recommended,
]Or wire the rules yourself:
import rnSecurity from 'eslint-plugin-rn-security'
export default [
{
plugins: { 'rn-security': rnSecurity },
rules: {
'rn-security/no-unsafe-webview': 'error',
'rn-security/no-insecure-storage': 'error',
},
},
]Legacy config (.eslintrc)
{
"plugins": ["rn-security"],
"extends": ["plugin:rn-security/legacy-recommended"]
}Rules
| Rule | What it catches |
| --- | --- |
| no-unsafe-webview | WebView configured to allow any origin, filesystem access, or mixed content |
| no-insecure-storage | Credentials written to AsyncStorage or web storage rather than Keychain or Keystore |
| no-cleartext-http | http:// endpoints in network calls |
| no-dynamic-link-open | Linking.openURL with an unvalidated value, or a dangerous scheme |
| no-unvalidated-deep-link | Deep link URLs reaching navigation or fetch without a check |
| no-sensitive-console | Credentials written to the device log |
What this plugin does not do
It does not find secrets in native or config files. ESLint only sees the files it lints, which is JavaScript and TypeScript. React Native secrets often live in .env, app.json, google-services.json, Info.plist and gradle.properties, and no ESLint plugin can reach those. Use a dedicated scanner such as gitleaks or trufflehog for that.
It is not a substitute for a real assessment. These are lint rules. They catch a specific set of mistakes cheaply and early. They do not analyse data flow across modules, they do not inspect your native code, and a clean run does not mean an app is secure.
It will not catch everything, and it will occasionally be wrong. Rules that reason about names, such as no-insecure-storage and no-sensitive-console, use heuristics. Both accept an additionalPatterns option so you can extend them, and both are ordinary ESLint rules you can disable per line where they are wrong.
Contributing
Issues and pull requests are welcome, particularly reports of false positives with a reproduction. Run the tests with:
npm testEach rule lives in lib/rules/ with its cases in tests/rules.test.js.
License
MIT
