@reliabilityworks/ruleset-react-native 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/rules.json +752 -8
package/package.json CHANGED
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "name": "@reliabilityworks/ruleset-react-native",
3
- "version": "0.5.0"
3
+ "version": "0.7.0"
4
4
  }
package/rules.json CHANGED
@@ -11,28 +11,772 @@
11
11
  "message": "usesCleartextTraffic is enabled"
12
12
  }
13
13
  },
14
+ {
15
+ "id": "rn/android-debuggable",
16
+ "severity": "high",
17
+ "title": "Android app is debuggable",
18
+ "description": "Shipping with android:debuggable=\"true\" can enable runtime inspection and tampering.",
19
+ "matcher": {
20
+ "type": "regex",
21
+ "fileGlobs": ["**/AndroidManifest.xml"],
22
+ "pattern": "android:debuggable\\s*=\\s*\\\"true\\\"",
23
+ "message": "android:debuggable=\"true\" detected"
24
+ }
25
+ },
26
+ {
27
+ "id": "rn/android-allow-backup",
28
+ "severity": "medium",
29
+ "title": "Android backups allowed",
30
+ "description": "android:allowBackup can allow app data to be included in backups and restored to other devices.",
31
+ "matcher": {
32
+ "type": "regex",
33
+ "fileGlobs": ["**/AndroidManifest.xml"],
34
+ "pattern": "android:allowBackup\\s*=\\s*\\\"true\\\"",
35
+ "message": "android:allowBackup=\"true\" detected"
36
+ }
37
+ },
38
+ {
39
+ "id": "rn/android-network-security-config",
40
+ "severity": "low",
41
+ "title": "Android network security config referenced",
42
+ "description": "Review network security config for cleartext exceptions and trust anchors.",
43
+ "matcher": {
44
+ "type": "regex",
45
+ "fileGlobs": ["**/AndroidManifest.xml"],
46
+ "pattern": "android:networkSecurityConfig\\s*=\\s*\\\"@xml/",
47
+ "message": "android:networkSecurityConfig referenced"
48
+ }
49
+ },
50
+ {
51
+ "id": "rn/android-request-legacy-external-storage",
52
+ "severity": "medium",
53
+ "title": "Legacy external storage requested",
54
+ "description": "requestLegacyExternalStorage can broaden file access on Android 10 and may increase data exposure.",
55
+ "matcher": {
56
+ "type": "regex",
57
+ "fileGlobs": ["**/AndroidManifest.xml"],
58
+ "pattern": "android:requestLegacyExternalStorage\\s*=\\s*\\\"true\\\"",
59
+ "message": "android:requestLegacyExternalStorage=\"true\" detected"
60
+ }
61
+ },
62
+ {
63
+ "id": "rn/android-exported-activity",
64
+ "severity": "medium",
65
+ "title": "Exported Android activity",
66
+ "description": "Exported activities can be invoked by other apps. Validate intents and protect sensitive entrypoints.",
67
+ "matcher": {
68
+ "type": "regex",
69
+ "fileGlobs": ["**/AndroidManifest.xml"],
70
+ "pattern": "<activity[^>]*android:exported\\s*=\\s*\\\"true\\\"",
71
+ "message": "Exported activity detected"
72
+ }
73
+ },
74
+ {
75
+ "id": "rn/android-exported-receiver",
76
+ "severity": "high",
77
+ "title": "Exported Android broadcast receiver",
78
+ "description": "Exported receivers can be triggered by other apps. Ensure permissions/signature protections are correct.",
79
+ "matcher": {
80
+ "type": "regex",
81
+ "fileGlobs": ["**/AndroidManifest.xml"],
82
+ "pattern": "<receiver[^>]*android:exported\\s*=\\s*\\\"true\\\"",
83
+ "message": "Exported receiver detected"
84
+ }
85
+ },
86
+ {
87
+ "id": "rn/android-exported-service",
88
+ "severity": "high",
89
+ "title": "Exported Android service",
90
+ "description": "Exported services can be started/bound by other apps. Ensure services are protected appropriately.",
91
+ "matcher": {
92
+ "type": "regex",
93
+ "fileGlobs": ["**/AndroidManifest.xml"],
94
+ "pattern": "<service[^>]*android:exported\\s*=\\s*\\\"true\\\"",
95
+ "message": "Exported service detected"
96
+ }
97
+ },
98
+ {
99
+ "id": "rn/android-permission-camera",
100
+ "severity": "low",
101
+ "title": "Android CAMERA permission requested",
102
+ "description": "Requesting camera access increases privacy risk; ensure it is necessary and well scoped.",
103
+ "matcher": {
104
+ "type": "regex",
105
+ "fileGlobs": ["**/AndroidManifest.xml"],
106
+ "pattern": "android:name\\s*=\\s*\\\"android\\.permission\\.CAMERA\\\"",
107
+ "message": "CAMERA permission requested"
108
+ }
109
+ },
110
+ {
111
+ "id": "rn/android-permission-record-audio",
112
+ "severity": "low",
113
+ "title": "Android RECORD_AUDIO permission requested",
114
+ "description": "Requesting microphone access increases privacy risk; ensure it is necessary and well scoped.",
115
+ "matcher": {
116
+ "type": "regex",
117
+ "fileGlobs": ["**/AndroidManifest.xml"],
118
+ "pattern": "android:name\\s*=\\s*\\\"android\\.permission\\.RECORD_AUDIO\\\"",
119
+ "message": "RECORD_AUDIO permission requested"
120
+ }
121
+ },
122
+ {
123
+ "id": "rn/android-permission-read-sms",
124
+ "severity": "high",
125
+ "title": "Android READ_SMS permission requested",
126
+ "description": "SMS access is highly sensitive; avoid requesting READ_SMS unless strictly required.",
127
+ "matcher": {
128
+ "type": "regex",
129
+ "fileGlobs": ["**/AndroidManifest.xml"],
130
+ "pattern": "android:name\\s*=\\s*\\\"android\\.permission\\.READ_SMS\\\"",
131
+ "message": "READ_SMS permission requested"
132
+ }
133
+ },
134
+ {
135
+ "id": "rn/android-permission-send-sms",
136
+ "severity": "high",
137
+ "title": "Android SEND_SMS permission requested",
138
+ "description": "SMS sending can be abused for fraud; avoid requesting SEND_SMS unless strictly required.",
139
+ "matcher": {
140
+ "type": "regex",
141
+ "fileGlobs": ["**/AndroidManifest.xml"],
142
+ "pattern": "android:name\\s*=\\s*\\\"android\\.permission\\.SEND_SMS\\\"",
143
+ "message": "SEND_SMS permission requested"
144
+ }
145
+ },
146
+ {
147
+ "id": "rn/android-permission-read-contacts",
148
+ "severity": "medium",
149
+ "title": "Android READ_CONTACTS permission requested",
150
+ "description": "Contacts access is sensitive; ensure collection is necessary and minimized.",
151
+ "matcher": {
152
+ "type": "regex",
153
+ "fileGlobs": ["**/AndroidManifest.xml"],
154
+ "pattern": "android:name\\s*=\\s*\\\"android\\.permission\\.READ_CONTACTS\\\"",
155
+ "message": "READ_CONTACTS permission requested"
156
+ }
157
+ },
158
+ {
159
+ "id": "rn/android-permission-write-contacts",
160
+ "severity": "medium",
161
+ "title": "Android WRITE_CONTACTS permission requested",
162
+ "description": "Writing contacts is sensitive; ensure it is necessary and properly disclosed.",
163
+ "matcher": {
164
+ "type": "regex",
165
+ "fileGlobs": ["**/AndroidManifest.xml"],
166
+ "pattern": "android:name\\s*=\\s*\\\"android\\.permission\\.WRITE_CONTACTS\\\"",
167
+ "message": "WRITE_CONTACTS permission requested"
168
+ }
169
+ },
170
+ {
171
+ "id": "rn/android-permission-access-fine-location",
172
+ "severity": "medium",
173
+ "title": "Android ACCESS_FINE_LOCATION permission requested",
174
+ "description": "Fine location is sensitive. Ensure collection is necessary and minimized.",
175
+ "matcher": {
176
+ "type": "regex",
177
+ "fileGlobs": ["**/AndroidManifest.xml"],
178
+ "pattern": "android:name\\s*=\\s*\\\"android\\.permission\\.ACCESS_FINE_LOCATION\\\"",
179
+ "message": "ACCESS_FINE_LOCATION permission requested"
180
+ }
181
+ },
182
+ {
183
+ "id": "rn/android-permission-access-background-location",
184
+ "severity": "high",
185
+ "title": "Android ACCESS_BACKGROUND_LOCATION permission requested",
186
+ "description": "Background location is highly sensitive; avoid requesting unless strictly required.",
187
+ "matcher": {
188
+ "type": "regex",
189
+ "fileGlobs": ["**/AndroidManifest.xml"],
190
+ "pattern": "android:name\\s*=\\s*\\\"android\\.permission\\.ACCESS_BACKGROUND_LOCATION\\\"",
191
+ "message": "ACCESS_BACKGROUND_LOCATION permission requested"
192
+ }
193
+ },
194
+ {
195
+ "id": "rn/android-permission-read-phone-state",
196
+ "severity": "medium",
197
+ "title": "Android READ_PHONE_STATE permission requested",
198
+ "description": "Phone state access can be sensitive; ensure it is necessary and minimized.",
199
+ "matcher": {
200
+ "type": "regex",
201
+ "fileGlobs": ["**/AndroidManifest.xml"],
202
+ "pattern": "android:name\\s*=\\s*\\\"android\\.permission\\.READ_PHONE_STATE\\\"",
203
+ "message": "READ_PHONE_STATE permission requested"
204
+ }
205
+ },
206
+ {
207
+ "id": "rn/android-permission-read-call-log",
208
+ "severity": "high",
209
+ "title": "Android READ_CALL_LOG permission requested",
210
+ "description": "Call logs are highly sensitive; avoid requesting READ_CALL_LOG unless strictly required.",
211
+ "matcher": {
212
+ "type": "regex",
213
+ "fileGlobs": ["**/AndroidManifest.xml"],
214
+ "pattern": "android:name\\s*=\\s*\\\"android\\.permission\\.READ_CALL_LOG\\\"",
215
+ "message": "READ_CALL_LOG permission requested"
216
+ }
217
+ },
218
+ {
219
+ "id": "rn/android-permission-write-call-log",
220
+ "severity": "high",
221
+ "title": "Android WRITE_CALL_LOG permission requested",
222
+ "description": "Writing call logs is highly sensitive; avoid requesting WRITE_CALL_LOG unless strictly required.",
223
+ "matcher": {
224
+ "type": "regex",
225
+ "fileGlobs": ["**/AndroidManifest.xml"],
226
+ "pattern": "android:name\\s*=\\s*\\\"android\\.permission\\.WRITE_CALL_LOG\\\"",
227
+ "message": "WRITE_CALL_LOG permission requested"
228
+ }
229
+ },
230
+ {
231
+ "id": "rn/android-permission-manage-external-storage",
232
+ "severity": "high",
233
+ "title": "Android MANAGE_EXTERNAL_STORAGE permission requested",
234
+ "description": "All files access is highly sensitive and broad; avoid requesting unless strictly required.",
235
+ "matcher": {
236
+ "type": "regex",
237
+ "fileGlobs": ["**/AndroidManifest.xml"],
238
+ "pattern": "android:name\\s*=\\s*\\\"android\\.permission\\.MANAGE_EXTERNAL_STORAGE\\\"",
239
+ "message": "MANAGE_EXTERNAL_STORAGE permission requested"
240
+ }
241
+ },
242
+ {
243
+ "id": "rn/android-permission-system-alert-window",
244
+ "severity": "high",
245
+ "title": "Android SYSTEM_ALERT_WINDOW permission requested",
246
+ "description": "Overlay permission can enable phishing and UI redress attacks; avoid requesting unless strictly required.",
247
+ "matcher": {
248
+ "type": "regex",
249
+ "fileGlobs": ["**/AndroidManifest.xml"],
250
+ "pattern": "android:name\\s*=\\s*\\\"android\\.permission\\.SYSTEM_ALERT_WINDOW\\\"",
251
+ "message": "SYSTEM_ALERT_WINDOW permission requested"
252
+ }
253
+ },
254
+ {
255
+ "id": "rn/android-permission-request-install-packages",
256
+ "severity": "high",
257
+ "title": "Android REQUEST_INSTALL_PACKAGES permission requested",
258
+ "description": "Allowing package installs can enable sideloading and abuse; avoid requesting unless strictly required.",
259
+ "matcher": {
260
+ "type": "regex",
261
+ "fileGlobs": ["**/AndroidManifest.xml"],
262
+ "pattern": "android:name\\s*=\\s*\\\"android\\.permission\\.REQUEST_INSTALL_PACKAGES\\\"",
263
+ "message": "REQUEST_INSTALL_PACKAGES permission requested"
264
+ }
265
+ },
266
+ {
267
+ "id": "rn/android-permission-package-usage-stats",
268
+ "severity": "high",
269
+ "title": "Android PACKAGE_USAGE_STATS permission requested",
270
+ "description": "Usage stats can reveal sensitive user behavior; avoid requesting unless strictly required.",
271
+ "matcher": {
272
+ "type": "regex",
273
+ "fileGlobs": ["**/AndroidManifest.xml"],
274
+ "pattern": "android:name\\s*=\\s*\\\"android\\.permission\\.PACKAGE_USAGE_STATS\\\"",
275
+ "message": "PACKAGE_USAGE_STATS permission requested"
276
+ }
277
+ },
278
+ {
279
+ "id": "rn/android-permission-bind-accessibility-service",
280
+ "severity": "high",
281
+ "title": "Android BIND_ACCESSIBILITY_SERVICE permission referenced",
282
+ "description": "Accessibility services can capture sensitive data; ensure appropriate justification and protections.",
283
+ "matcher": {
284
+ "type": "regex",
285
+ "fileGlobs": ["**/AndroidManifest.xml"],
286
+ "pattern": "android:name\\s*=\\s*\\\"android\\.permission\\.BIND_ACCESSIBILITY_SERVICE\\\"",
287
+ "message": "BIND_ACCESSIBILITY_SERVICE permission referenced"
288
+ }
289
+ },
14
290
  {
15
291
  "id": "rn/ats-arbitrary-loads",
16
292
  "severity": "high",
17
- "title": "ATS allows arbitrary loads on iOS",
18
- "description": "Disabling App Transport Security can allow insecure HTTP traffic.",
293
+ "title": "ATS allows arbitrary loads",
294
+ "description": "NSAllowsArbitraryLoads disables ATS protections and can permit insecure HTTP connections.",
295
+ "matcher": {
296
+ "type": "regex",
297
+ "fileGlobs": ["**/Info.plist"],
298
+ "pattern": "NSAllowsArbitraryLoads</key>\\s*<true\\s*/>",
299
+ "message": "NSAllowsArbitraryLoads enabled"
300
+ }
301
+ },
302
+ {
303
+ "id": "rn/ios-ats-arbitrary-loads-in-webcontent",
304
+ "severity": "high",
305
+ "title": "ATS allows arbitrary loads in web content",
306
+ "description": "NSAllowsArbitraryLoadsInWebContent permits insecure loads inside WKWebView / embedded web content.",
307
+ "matcher": {
308
+ "type": "regex",
309
+ "fileGlobs": ["**/Info.plist"],
310
+ "pattern": "NSAllowsArbitraryLoadsInWebContent</key>\\s*<true\\s*/>",
311
+ "message": "NSAllowsArbitraryLoadsInWebContent enabled"
312
+ }
313
+ },
314
+ {
315
+ "id": "rn/ios-ats-arbitrary-loads-for-media",
316
+ "severity": "medium",
317
+ "title": "ATS allows arbitrary loads for media",
318
+ "description": "NSAllowsArbitraryLoadsForMedia allows insecure media loads; review necessity.",
319
+ "matcher": {
320
+ "type": "regex",
321
+ "fileGlobs": ["**/Info.plist"],
322
+ "pattern": "NSAllowsArbitraryLoadsForMedia</key>\\s*<true\\s*/>",
323
+ "message": "NSAllowsArbitraryLoadsForMedia enabled"
324
+ }
325
+ },
326
+ {
327
+ "id": "rn/ios-ats-arbitrary-loads-for-webcontent",
328
+ "severity": "medium",
329
+ "title": "ATS allows arbitrary loads for web content",
330
+ "description": "NSAllowsArbitraryLoadsForWebContent allows insecure web loads; review necessity.",
331
+ "matcher": {
332
+ "type": "regex",
333
+ "fileGlobs": ["**/Info.plist"],
334
+ "pattern": "NSAllowsArbitraryLoadsForWebContent</key>\\s*<true\\s*/>",
335
+ "message": "NSAllowsArbitraryLoadsForWebContent enabled"
336
+ }
337
+ },
338
+ {
339
+ "id": "rn/ios-ats-exception-insecure-http-loads",
340
+ "severity": "high",
341
+ "title": "ATS exception allows insecure HTTP loads",
342
+ "description": "NSExceptionAllowsInsecureHTTPLoads allows non-TLS traffic for exception domains.",
343
+ "matcher": {
344
+ "type": "regex",
345
+ "fileGlobs": ["**/Info.plist"],
346
+ "pattern": "NSExceptionAllowsInsecureHTTPLoads</key>\\s*<true\\s*/>",
347
+ "message": "NSExceptionAllowsInsecureHTTPLoads enabled"
348
+ }
349
+ },
350
+ {
351
+ "id": "rn/ios-ats-exception-minimum-tls-1-0",
352
+ "severity": "high",
353
+ "title": "ATS exception allows TLSv1.0",
354
+ "description": "Allowing TLSv1.0 weakens transport security; prefer TLS 1.2+.",
355
+ "matcher": {
356
+ "type": "regex",
357
+ "fileGlobs": ["**/Info.plist"],
358
+ "pattern": "NSExceptionMinimumTLSVersion</key>\\s*<string>TLSv1\\.0</string>",
359
+ "message": "NSExceptionMinimumTLSVersion set to TLSv1.0"
360
+ }
361
+ },
362
+ {
363
+ "id": "rn/ios-ats-allows-local-networking",
364
+ "severity": "low",
365
+ "title": "ATS allows local networking",
366
+ "description": "Allowing local networking may be intended, but review for exposure to untrusted networks.",
367
+ "matcher": {
368
+ "type": "regex",
369
+ "fileGlobs": ["**/Info.plist"],
370
+ "pattern": "NSAllowsLocalNetworking</key>\\s*<true\\s*/>",
371
+ "message": "NSAllowsLocalNetworking enabled"
372
+ }
373
+ },
374
+ {
375
+ "id": "rn/ios-ui-filesharing-enabled",
376
+ "severity": "medium",
377
+ "title": "iOS UIFileSharingEnabled enabled",
378
+ "description": "Enabling iTunes File Sharing can expose app documents to users and desktop access.",
19
379
  "matcher": {
20
380
  "type": "regex",
21
381
  "fileGlobs": ["**/Info.plist"],
22
- "pattern": "NSAllowsArbitraryLoads[\\s\\S]*<true\\s*/>",
23
- "message": "NSAllowsArbitraryLoads appears enabled"
382
+ "pattern": "UIFileSharingEnabled</key>\\s*<true\\s*/>",
383
+ "message": "UIFileSharingEnabled enabled"
384
+ }
385
+ },
386
+ {
387
+ "id": "rn/ios-documents-in-place",
388
+ "severity": "low",
389
+ "title": "iOS supports opening documents in place",
390
+ "description": "Opening documents in place can interact with external providers; review implications for sensitive files.",
391
+ "matcher": {
392
+ "type": "regex",
393
+ "fileGlobs": ["**/Info.plist"],
394
+ "pattern": "LSSupportsOpeningDocumentsInPlace</key>\\s*<true\\s*/>",
395
+ "message": "LSSupportsOpeningDocumentsInPlace enabled"
396
+ }
397
+ },
398
+ {
399
+ "id": "rn/insecure-universal-links",
400
+ "severity": "low",
401
+ "title": "Associated domains configured",
402
+ "description": "Ensure associated domains are correct and validated to prevent deep link hijacking.",
403
+ "matcher": {
404
+ "type": "regex",
405
+ "fileGlobs": ["**/*.entitlements"],
406
+ "pattern": "com\\.apple\\.developer\\.associated-domains",
407
+ "message": "Associated domains entitlement referenced"
408
+ }
409
+ },
410
+ {
411
+ "id": "rn/ios-get-task-allow-enabled",
412
+ "severity": "high",
413
+ "title": "iOS get-task-allow enabled",
414
+ "description": "get-task-allow enables debugging/attaching; ensure it is disabled for production builds.",
415
+ "matcher": {
416
+ "type": "regex",
417
+ "fileGlobs": ["**/*.entitlements"],
418
+ "pattern": "get-task-allow</key>\\s*<true\\s*/>",
419
+ "message": "get-task-allow is enabled"
420
+ }
421
+ },
422
+ {
423
+ "id": "rn/ios-keychain-access-groups",
424
+ "severity": "medium",
425
+ "title": "iOS keychain access groups configured",
426
+ "description": "Review keychain access groups for unnecessary sharing between apps/extensions.",
427
+ "matcher": {
428
+ "type": "regex",
429
+ "fileGlobs": ["**/*.entitlements"],
430
+ "pattern": "keychain-access-groups",
431
+ "message": "keychain-access-groups referenced"
432
+ }
433
+ },
434
+ {
435
+ "id": "rn/insecure-biometrics-fallback",
436
+ "severity": "low",
437
+ "title": "Biometrics fallback allowed",
438
+ "description": "Allowing biometrics fallback to device passcode may be acceptable, but ensure security requirements are met.",
439
+ "matcher": {
440
+ "type": "regex",
441
+ "fileGlobs": ["**/*.{js,jsx,ts,tsx}"],
442
+ "pattern": "allowDeviceCredentials\\s*:\\s*true",
443
+ "message": "allowDeviceCredentials: true detected"
444
+ }
445
+ },
446
+ {
447
+ "id": "rn/unsafe-webview-file-url",
448
+ "severity": "high",
449
+ "title": "WebView loads file:// URL",
450
+ "description": "Loading local file URLs in a WebView can increase risk of file access and injection.",
451
+ "matcher": {
452
+ "type": "regex",
453
+ "fileGlobs": ["**/*.{js,jsx,ts,tsx}"],
454
+ "pattern": "file://",
455
+ "message": "file:// URL referenced"
456
+ }
457
+ },
458
+ {
459
+ "id": "rn/insecure-allowlist-missing",
460
+ "severity": "low",
461
+ "title": "No explicit allowlist",
462
+ "description": "Allowlisting origins and inputs can reduce attack surface.",
463
+ "matcher": {
464
+ "type": "regex",
465
+ "fileGlobs": ["**/*.{js,jsx,ts,tsx}"],
466
+ "pattern": "\\ballowlist\\b",
467
+ "message": "allowlist referenced"
468
+ }
469
+ },
470
+ {
471
+ "id": "rn/insecure-debug-flag",
472
+ "severity": "low",
473
+ "title": "Debug flag referenced",
474
+ "description": "Ensure debug features are disabled in production builds.",
475
+ "matcher": {
476
+ "type": "regex",
477
+ "fileGlobs": ["**/*.{js,jsx,ts,tsx}"],
478
+ "pattern": "__DEV__|debug\\s*:\\s*true",
479
+ "message": "Debug flag detected"
480
+ }
481
+ },
482
+ {
483
+ "id": "rn/insecure-crypto-random-by-math",
484
+ "severity": "low",
485
+ "title": "Non-cryptographic random referenced",
486
+ "description": "Avoid using Math.random for secrets, tokens, or identifiers.",
487
+ "matcher": {
488
+ "type": "regex",
489
+ "fileGlobs": ["**/*.{js,jsx,ts,tsx}"],
490
+ "pattern": "Math\\.random\\s*\\(",
491
+ "message": "Math.random() detected"
492
+ }
493
+ },
494
+ {
495
+ "id": "rn/insecure-webview-postmessage",
496
+ "severity": "medium",
497
+ "title": "WebView postMessage bridge used",
498
+ "description": "WebView messaging bridges can enable injection if messages are not validated.",
499
+ "matcher": {
500
+ "type": "regex",
501
+ "fileGlobs": ["**/*.{js,jsx,ts,tsx}"],
502
+ "pattern": "onMessage\\s*=|postMessage\\s*\\(",
503
+ "message": "WebView messaging bridge detected"
504
+ }
505
+ },
506
+ {
507
+ "id": "rn/insecure-remote-debugging",
508
+ "severity": "low",
509
+ "title": "Remote debugging referenced",
510
+ "description": "Ensure remote debugging is disabled in production.",
511
+ "matcher": {
512
+ "type": "regex",
513
+ "fileGlobs": ["**/*.{js,jsx,ts,tsx}"],
514
+ "pattern": "remote debugging|Debug JS Remotely",
515
+ "message": "Remote debugging referenced"
516
+ }
517
+ },
518
+ {
519
+ "id": "rn/insecure-pasteboard",
520
+ "severity": "medium",
521
+ "title": "Clipboard used for sensitive data",
522
+ "description": "Clipboard/Pasteboard can be read by other apps; avoid storing secrets there.",
523
+ "matcher": {
524
+ "type": "regex",
525
+ "fileGlobs": ["**/*.{js,jsx,ts,tsx}"],
526
+ "pattern": "Clipboard\\.|Pasteboard",
527
+ "message": "Clipboard/Pasteboard referenced"
528
+ }
529
+ },
530
+ {
531
+ "id": "rn/insecure-http-fetch",
532
+ "severity": "high",
533
+ "title": "HTTP request via fetch",
534
+ "description": "Using http:// in network requests can expose traffic to interception.",
535
+ "matcher": {
536
+ "type": "regex",
537
+ "fileGlobs": ["**/*.{js,jsx,ts,tsx}"],
538
+ "pattern": "fetch\\s*\\(\\s*['\\\"]http://",
539
+ "message": "fetch() called with http:// URL"
540
+ }
541
+ },
542
+ {
543
+ "id": "rn/insecure-http-axios-baseurl",
544
+ "severity": "high",
545
+ "title": "HTTP baseURL configured for axios",
546
+ "description": "Using http:// as a base URL can expose traffic to interception.",
547
+ "matcher": {
548
+ "type": "regex",
549
+ "fileGlobs": ["**/*.{js,jsx,ts,tsx}"],
550
+ "pattern": "baseURL\\s*:\\s*['\\\"]http://",
551
+ "message": "axios baseURL uses http://"
552
+ }
553
+ },
554
+ {
555
+ "id": "rn/insecure-webview-http-source",
556
+ "severity": "medium",
557
+ "title": "WebView loads http:// content",
558
+ "description": "Loading http:// content in a WebView can enable injection and interception.",
559
+ "matcher": {
560
+ "type": "regex",
561
+ "fileGlobs": ["**/*.{js,jsx,ts,tsx}"],
562
+ "pattern": "uri\\s*:\\s*['\\\"]http://",
563
+ "message": "WebView source uri uses http://"
564
+ }
565
+ },
566
+ {
567
+ "id": "rn/webview-allows-any-origin",
568
+ "severity": "high",
569
+ "title": "WebView allows any origin via originWhitelist",
570
+ "description": "Allowing any origin can enable navigation to untrusted content.",
571
+ "matcher": {
572
+ "type": "regex",
573
+ "fileGlobs": ["**/*.{js,jsx,ts,tsx}"],
574
+ "pattern": "originWhitelist\\s*=\\s*\\[\\s*['\\\"]\\*['\\\"]",
575
+ "message": "originWhitelist includes '*'"
576
+ }
577
+ },
578
+ {
579
+ "id": "rn/webview-mixed-content-always",
580
+ "severity": "high",
581
+ "title": "WebView mixed content allowed",
582
+ "description": "Allowing mixed content can permit insecure resource loads alongside HTTPS.",
583
+ "matcher": {
584
+ "type": "regex",
585
+ "fileGlobs": ["**/*.{js,jsx,ts,tsx}"],
586
+ "pattern": "mixedContentMode\\s*=\\s*['\\\"]always['\\\"]",
587
+ "message": "mixedContentMode set to always"
588
+ }
589
+ },
590
+ {
591
+ "id": "rn/webview-javascript-enabled",
592
+ "severity": "low",
593
+ "title": "WebView JavaScript enabled",
594
+ "description": "JavaScript in WebViews can increase risk when rendering untrusted content.",
595
+ "matcher": {
596
+ "type": "regex",
597
+ "fileGlobs": ["**/*.{js,jsx,ts,tsx}"],
598
+ "pattern": "javaScriptEnabled\\s*=\\s*(\\{\\s*true\\s*\\}|true)",
599
+ "message": "javaScriptEnabled enabled"
600
+ }
601
+ },
602
+ {
603
+ "id": "rn/webview-domstorage-enabled",
604
+ "severity": "low",
605
+ "title": "WebView DOM storage enabled",
606
+ "description": "DOM storage can persist data in web contexts; review exposure for sensitive info.",
607
+ "matcher": {
608
+ "type": "regex",
609
+ "fileGlobs": ["**/*.{js,jsx,ts,tsx}"],
610
+ "pattern": "domStorageEnabled\\s*=\\s*(\\{\\s*true\\s*\\}|true)",
611
+ "message": "domStorageEnabled enabled"
612
+ }
613
+ },
614
+ {
615
+ "id": "rn/webview-injectedjavascript",
616
+ "severity": "medium",
617
+ "title": "WebView injectedJavaScript used",
618
+ "description": "Injecting JavaScript into WebViews can be risky when combined with untrusted content.",
619
+ "matcher": {
620
+ "type": "regex",
621
+ "fileGlobs": ["**/*.{js,jsx,ts,tsx}"],
622
+ "pattern": "injectedJavaScript\\s*=",
623
+ "message": "injectedJavaScript prop used"
624
+ }
625
+ },
626
+ {
627
+ "id": "rn/webview-shared-cookies-enabled",
628
+ "severity": "low",
629
+ "title": "WebView shared cookies enabled",
630
+ "description": "Sharing cookies between WebViews and the native cookie store can increase tracking and leakage risk.",
631
+ "matcher": {
632
+ "type": "regex",
633
+ "fileGlobs": ["**/*.{js,jsx,ts,tsx}"],
634
+ "pattern": "sharedCookiesEnabled\\s*=\\s*\\{\\s*true\\s*\\}",
635
+ "message": "sharedCookiesEnabled enabled"
636
+ }
637
+ },
638
+ {
639
+ "id": "rn/webview-third-party-cookies-enabled",
640
+ "severity": "low",
641
+ "title": "WebView third-party cookies enabled",
642
+ "description": "Third-party cookies can increase tracking and leakage risk.",
643
+ "matcher": {
644
+ "type": "regex",
645
+ "fileGlobs": ["**/*.{js,jsx,ts,tsx}"],
646
+ "pattern": "thirdPartyCookiesEnabled\\s*=\\s*\\{\\s*true\\s*\\}",
647
+ "message": "thirdPartyCookiesEnabled enabled"
648
+ }
649
+ },
650
+ {
651
+ "id": "rn/insecure-deeplink-getinitialurl",
652
+ "severity": "medium",
653
+ "title": "Deep link URL retrieved",
654
+ "description": "Deep link URLs should be validated before use to prevent navigation to untrusted destinations.",
655
+ "matcher": {
656
+ "type": "regex",
657
+ "fileGlobs": ["**/*.{js,jsx,ts,tsx}"],
658
+ "pattern": "Linking\\.getInitialURL\\s*\\(",
659
+ "message": "Linking.getInitialURL() detected"
660
+ }
661
+ },
662
+ {
663
+ "id": "rn/insecure-deeplink-openurl",
664
+ "severity": "medium",
665
+ "title": "Deep link URL opened",
666
+ "description": "Opening URLs should be restricted/validated to avoid navigation to untrusted destinations.",
667
+ "matcher": {
668
+ "type": "regex",
669
+ "fileGlobs": ["**/*.{js,jsx,ts,tsx}"],
670
+ "pattern": "Linking\\.openURL\\s*\\(",
671
+ "message": "Linking.openURL() detected"
672
+ }
673
+ },
674
+ {
675
+ "id": "rn/insecure-deeplink-url-event-listener",
676
+ "severity": "low",
677
+ "title": "Deep link URL event listener registered",
678
+ "description": "When handling URL events, validate scheme/host and reject untrusted inputs.",
679
+ "matcher": {
680
+ "type": "regex",
681
+ "fileGlobs": ["**/*.{js,jsx,ts,tsx}"],
682
+ "pattern": "Linking\\.addEventListener\\s*\\(\\s*['\\\"]url['\\\"]",
683
+ "message": "Linking url event listener detected"
24
684
  }
25
685
  },
26
686
  {
27
687
  "id": "rn/asyncstorage-token-key",
28
688
  "severity": "high",
29
- "title": "Potential token stored in AsyncStorage",
30
- "description": "AsyncStorage is not suitable for storing secrets; prefer platform secure storage for tokens.",
689
+ "title": "AsyncStorage stores auth token",
690
+ "description": "Storing authentication tokens in AsyncStorage is not encrypted by default.",
691
+ "matcher": {
692
+ "type": "regex",
693
+ "fileGlobs": ["**/*.{js,jsx,ts,tsx}"],
694
+ "pattern": "AsyncStorage\\.setItem\\s*\\(\\s*['\\\"](auth_)?token['\\\"]",
695
+ "message": "AsyncStorage.setItem() called with token key"
696
+ }
697
+ },
698
+ {
699
+ "id": "rn/insecure-storage-asyncstorage-setitem",
700
+ "severity": "medium",
701
+ "title": "AsyncStorage used to store data",
702
+ "description": "AsyncStorage is not encrypted by default; avoid storing secrets or tokens in plaintext.",
703
+ "matcher": {
704
+ "type": "regex",
705
+ "fileGlobs": ["**/*.{js,jsx,ts,tsx}"],
706
+ "pattern": "AsyncStorage\\.setItem\\s*\\(",
707
+ "message": "AsyncStorage.setItem() detected"
708
+ }
709
+ },
710
+ {
711
+ "id": "rn/insecure-storage-asyncstorage-getitem",
712
+ "severity": "low",
713
+ "title": "AsyncStorage used to read data",
714
+ "description": "When reading from AsyncStorage, ensure secrets are not stored unencrypted.",
715
+ "matcher": {
716
+ "type": "regex",
717
+ "fileGlobs": ["**/*.{js,jsx,ts,tsx}"],
718
+ "pattern": "AsyncStorage\\.getItem\\s*\\(",
719
+ "message": "AsyncStorage.getItem() detected"
720
+ }
721
+ },
722
+ {
723
+ "id": "rn/insecure-storage-mmkv",
724
+ "severity": "low",
725
+ "title": "MMKV storage referenced",
726
+ "description": "Ensure sensitive values stored in MMKV are encrypted or otherwise protected.",
727
+ "matcher": {
728
+ "type": "regex",
729
+ "fileGlobs": ["**/*.{js,jsx,ts,tsx}"],
730
+ "pattern": "new\\s+MMKV\\s*\\(",
731
+ "message": "MMKV instantiated"
732
+ }
733
+ },
734
+ {
735
+ "id": "rn/insecure-ios-keychain-accessible-always",
736
+ "severity": "high",
737
+ "title": "iOS Keychain accessibleAlways referenced",
738
+ "description": "kSecAttrAccessibleAlways can allow keychain items to be accessible more broadly than intended.",
739
+ "matcher": {
740
+ "type": "regex",
741
+ "fileGlobs": ["**/*.{js,jsx,ts,tsx}"],
742
+ "pattern": "kSecAttrAccessibleAlways",
743
+ "message": "kSecAttrAccessibleAlways referenced"
744
+ }
745
+ },
746
+ {
747
+ "id": "rn/insecure-logging-secrets",
748
+ "severity": "medium",
749
+ "title": "Potential secret logged",
750
+ "description": "Logging secrets (tokens/passwords) can leak sensitive data to logs and third-party crash reporters.",
751
+ "matcher": {
752
+ "type": "regex",
753
+ "fileGlobs": ["**/*.{js,jsx,ts,tsx}"],
754
+ "pattern": "console\\.log\\([^\\n]*(token|password|secret)",
755
+ "message": "console.log with potential secret keyword"
756
+ }
757
+ },
758
+ {
759
+ "id": "rn/insecure-crypto-md5",
760
+ "severity": "medium",
761
+ "title": "Weak hash (MD5) referenced",
762
+ "description": "MD5 is considered cryptographically broken; avoid using it for security purposes.",
763
+ "matcher": {
764
+ "type": "regex",
765
+ "fileGlobs": ["**/*.{js,jsx,ts,tsx}"],
766
+ "pattern": "createHash\\s*\\(\\s*['\\\"]md5['\\\"]\\s*\\)|\\bMD5\\b",
767
+ "message": "MD5 referenced"
768
+ }
769
+ },
770
+ {
771
+ "id": "rn/insecure-crypto-sha1",
772
+ "severity": "medium",
773
+ "title": "Weak hash (SHA1) referenced",
774
+ "description": "SHA1 is deprecated for many security uses; prefer SHA-256+.",
31
775
  "matcher": {
32
776
  "type": "regex",
33
777
  "fileGlobs": ["**/*.{js,jsx,ts,tsx}"],
34
- "pattern": "AsyncStorage\\.setItem\\(\\s*['\\\"][^'\\\"]*(token|secret|key|password)[^'\\\"]*['\\\"]",
35
- "message": "AsyncStorage key name suggests sensitive data storage"
778
+ "pattern": "createHash\\s*\\(\\s*['\\\"]sha1['\\\"]\\s*\\)|\\bSHA1\\b",
779
+ "message": "SHA1 referenced"
36
780
  }
37
781
  }
38
782
  ]