eslint-plugin-secure-coding 2.3.3 → 2.4.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 (337) hide show
  1. package/CHANGELOG.md +51 -1
  2. package/README.md +2 -2
  3. package/package.json +1 -1
  4. package/src/index.d.ts +32 -0
  5. package/src/index.js +416 -0
  6. package/src/rules/detect-child-process/index.d.ts +11 -0
  7. package/src/rules/detect-child-process/index.js +529 -0
  8. package/src/rules/detect-eval-with-expression/index.d.ts +9 -0
  9. package/src/rules/detect-eval-with-expression/index.js +392 -0
  10. package/src/rules/detect-mixed-content/index.d.ts +8 -0
  11. package/src/rules/detect-mixed-content/index.js +44 -0
  12. package/src/rules/detect-non-literal-fs-filename/index.d.ts +7 -0
  13. package/src/rules/detect-non-literal-fs-filename/index.js +454 -0
  14. package/src/rules/detect-non-literal-regexp/index.d.ts +9 -0
  15. package/src/rules/detect-non-literal-regexp/index.js +403 -0
  16. package/src/rules/detect-object-injection/index.d.ts +11 -0
  17. package/src/rules/detect-object-injection/index.js +560 -0
  18. package/src/rules/detect-suspicious-dependencies/index.d.ts +8 -0
  19. package/src/rules/detect-suspicious-dependencies/index.js +71 -0
  20. package/src/rules/detect-weak-password-validation/index.d.ts +6 -0
  21. package/src/rules/detect-weak-password-validation/index.js +58 -0
  22. package/src/rules/no-allow-arbitrary-loads/index.d.ts +8 -0
  23. package/src/rules/no-allow-arbitrary-loads/index.js +47 -0
  24. package/src/rules/no-arbitrary-file-access/index.d.ts +13 -0
  25. package/src/rules/no-arbitrary-file-access/index.js +195 -0
  26. package/src/rules/no-buffer-overread/index.d.ts +29 -0
  27. package/src/rules/no-buffer-overread/index.js +606 -0
  28. package/src/rules/no-clickjacking/index.d.ts +10 -0
  29. package/src/rules/no-clickjacking/index.js +396 -0
  30. package/src/rules/no-client-side-auth-logic/index.d.ts +6 -0
  31. package/src/rules/no-client-side-auth-logic/index.js +69 -0
  32. package/src/rules/no-credentials-in-query-params/index.d.ts +8 -0
  33. package/src/rules/no-credentials-in-query-params/index.js +57 -0
  34. package/src/rules/no-data-in-temp-storage/index.d.ts +6 -0
  35. package/src/rules/no-data-in-temp-storage/index.js +64 -0
  36. package/src/rules/no-debug-code-in-production/index.d.ts +8 -0
  37. package/src/rules/no-debug-code-in-production/index.js +51 -0
  38. package/src/rules/no-directive-injection/index.d.ts +12 -0
  39. package/src/rules/no-directive-injection/index.js +457 -0
  40. package/src/rules/no-disabled-certificate-validation/index.d.ts +6 -0
  41. package/src/rules/no-disabled-certificate-validation/index.js +61 -0
  42. package/src/rules/no-dynamic-dependency-loading/index.d.ts +8 -0
  43. package/src/rules/no-dynamic-dependency-loading/index.js +51 -0
  44. package/src/rules/no-electron-security-issues/index.d.ts +10 -0
  45. package/src/rules/no-electron-security-issues/index.js +423 -0
  46. package/src/rules/no-exposed-debug-endpoints/index.d.ts +6 -0
  47. package/src/rules/no-exposed-debug-endpoints/index.js +62 -0
  48. package/src/rules/no-exposed-sensitive-data/index.d.ts +11 -0
  49. package/src/rules/no-exposed-sensitive-data/index.js +340 -0
  50. package/src/rules/no-format-string-injection/index.d.ts +17 -0
  51. package/src/rules/no-format-string-injection/index.js +660 -0
  52. package/src/rules/no-graphql-injection/index.d.ts +12 -0
  53. package/src/rules/no-graphql-injection/index.js +411 -0
  54. package/src/rules/no-hardcoded-credentials/index.d.ts +26 -0
  55. package/src/rules/no-hardcoded-credentials/index.js +376 -0
  56. package/src/rules/no-hardcoded-session-tokens/index.d.ts +6 -0
  57. package/src/rules/no-hardcoded-session-tokens/index.js +59 -0
  58. package/src/rules/no-http-urls/index.d.ts +12 -0
  59. package/src/rules/no-http-urls/index.js +114 -0
  60. package/src/rules/no-improper-sanitization/index.d.ts +12 -0
  61. package/src/rules/no-improper-sanitization/index.js +411 -0
  62. package/src/rules/no-improper-type-validation/index.d.ts +10 -0
  63. package/src/rules/no-improper-type-validation/index.js +475 -0
  64. package/src/rules/no-insecure-comparison/index.d.ts +7 -0
  65. package/src/rules/no-insecure-comparison/index.js +193 -0
  66. package/src/rules/no-insecure-redirects/index.d.ts +7 -0
  67. package/src/rules/no-insecure-redirects/index.js +216 -0
  68. package/src/rules/no-insecure-websocket/index.d.ts +6 -0
  69. package/src/rules/no-insecure-websocket/index.js +61 -0
  70. package/src/rules/no-ldap-injection/index.d.ts +10 -0
  71. package/src/rules/no-ldap-injection/index.js +455 -0
  72. package/src/rules/no-missing-authentication/index.d.ts +13 -0
  73. package/src/rules/no-missing-authentication/index.js +333 -0
  74. package/src/rules/no-missing-cors-check/index.d.ts +9 -0
  75. package/src/rules/no-missing-cors-check/index.js +399 -0
  76. package/src/rules/no-missing-csrf-protection/index.d.ts +11 -0
  77. package/src/rules/no-missing-csrf-protection/index.js +180 -0
  78. package/src/rules/no-missing-security-headers/index.d.ts +7 -0
  79. package/src/rules/no-missing-security-headers/index.js +218 -0
  80. package/src/rules/no-password-in-url/index.d.ts +8 -0
  81. package/src/rules/no-password-in-url/index.js +54 -0
  82. package/src/rules/no-permissive-cors/index.d.ts +8 -0
  83. package/src/rules/no-permissive-cors/index.js +65 -0
  84. package/src/rules/no-pii-in-logs/index.d.ts +8 -0
  85. package/src/rules/no-pii-in-logs/index.js +70 -0
  86. package/src/rules/no-privilege-escalation/index.d.ts +13 -0
  87. package/src/rules/no-privilege-escalation/index.js +321 -0
  88. package/src/rules/no-redos-vulnerable-regex/index.d.ts +7 -0
  89. package/src/rules/no-redos-vulnerable-regex/index.js +306 -0
  90. package/src/rules/no-sensitive-data-exposure/index.d.ts +11 -0
  91. package/src/rules/no-sensitive-data-exposure/index.js +250 -0
  92. package/src/rules/no-sensitive-data-in-analytics/index.d.ts +8 -0
  93. package/src/rules/no-sensitive-data-in-analytics/index.js +62 -0
  94. package/src/rules/no-sensitive-data-in-cache/index.d.ts +8 -0
  95. package/src/rules/no-sensitive-data-in-cache/index.js +52 -0
  96. package/src/rules/no-toctou-vulnerability/index.d.ts +7 -0
  97. package/src/rules/no-toctou-vulnerability/index.js +208 -0
  98. package/src/rules/no-tracking-without-consent/index.d.ts +6 -0
  99. package/src/rules/no-tracking-without-consent/index.js +67 -0
  100. package/src/rules/no-unchecked-loop-condition/index.d.ts +12 -0
  101. package/src/rules/no-unchecked-loop-condition/index.js +646 -0
  102. package/src/rules/no-unencrypted-transmission/index.d.ts +11 -0
  103. package/src/rules/no-unencrypted-transmission/index.js +236 -0
  104. package/src/rules/no-unescaped-url-parameter/index.d.ts +9 -0
  105. package/src/rules/no-unescaped-url-parameter/index.js +355 -0
  106. package/src/rules/no-unlimited-resource-allocation/index.d.ts +12 -0
  107. package/src/rules/no-unlimited-resource-allocation/index.js +643 -0
  108. package/src/rules/no-unsafe-deserialization/index.d.ts +10 -0
  109. package/src/rules/no-unsafe-deserialization/index.js +491 -0
  110. package/src/rules/no-unsafe-dynamic-require/index.d.ts +5 -0
  111. package/src/rules/no-unsafe-dynamic-require/index.js +106 -0
  112. package/src/rules/no-unsafe-regex-construction/index.d.ts +9 -0
  113. package/src/rules/no-unsafe-regex-construction/index.js +291 -0
  114. package/src/rules/no-unvalidated-deeplinks/index.d.ts +6 -0
  115. package/src/rules/no-unvalidated-deeplinks/index.js +62 -0
  116. package/src/rules/no-unvalidated-user-input/index.d.ts +9 -0
  117. package/src/rules/no-unvalidated-user-input/index.js +420 -0
  118. package/src/rules/no-verbose-error-messages/index.d.ts +8 -0
  119. package/src/rules/no-verbose-error-messages/index.js +68 -0
  120. package/src/rules/no-weak-password-recovery/index.d.ts +12 -0
  121. package/src/rules/no-weak-password-recovery/index.js +424 -0
  122. package/src/rules/no-xpath-injection/index.d.ts +10 -0
  123. package/src/rules/no-xpath-injection/index.js +487 -0
  124. package/src/rules/no-xxe-injection/index.d.ts +7 -0
  125. package/src/rules/no-xxe-injection/index.js +266 -0
  126. package/src/rules/no-zip-slip/index.d.ts +9 -0
  127. package/src/rules/no-zip-slip/index.js +445 -0
  128. package/src/rules/require-backend-authorization/index.d.ts +6 -0
  129. package/src/rules/require-backend-authorization/index.js +60 -0
  130. package/src/rules/require-code-minification/index.d.ts +8 -0
  131. package/src/rules/require-code-minification/index.js +47 -0
  132. package/src/rules/require-csp-headers/index.d.ts +6 -0
  133. package/src/rules/require-csp-headers/index.js +64 -0
  134. package/src/rules/require-data-minimization/index.d.ts +8 -0
  135. package/src/rules/require-data-minimization/index.js +53 -0
  136. package/src/rules/require-dependency-integrity/index.d.ts +6 -0
  137. package/src/rules/require-dependency-integrity/index.js +64 -0
  138. package/src/rules/require-https-only/index.d.ts +8 -0
  139. package/src/rules/require-https-only/index.js +62 -0
  140. package/src/rules/require-mime-type-validation/index.d.ts +6 -0
  141. package/src/rules/require-mime-type-validation/index.js +66 -0
  142. package/src/rules/require-network-timeout/index.d.ts +8 -0
  143. package/src/rules/require-network-timeout/index.js +50 -0
  144. package/src/rules/require-package-lock/index.d.ts +8 -0
  145. package/src/rules/require-package-lock/index.js +63 -0
  146. package/src/rules/require-secure-credential-storage/index.d.ts +8 -0
  147. package/src/rules/require-secure-credential-storage/index.js +50 -0
  148. package/src/rules/require-secure-defaults/index.d.ts +8 -0
  149. package/src/rules/require-secure-defaults/index.js +47 -0
  150. package/src/rules/require-secure-deletion/index.d.ts +8 -0
  151. package/src/rules/require-secure-deletion/index.js +44 -0
  152. package/src/rules/require-storage-encryption/index.d.ts +8 -0
  153. package/src/rules/require-storage-encryption/index.js +50 -0
  154. package/src/rules/require-url-validation/index.d.ts +6 -0
  155. package/src/rules/require-url-validation/index.js +72 -0
  156. package/src/types/index.d.ts +106 -0
  157. package/src/types/index.js +16 -0
  158. package/src/index.ts +0 -605
  159. package/src/rules/__tests__/integration-demo.test.ts +0 -290
  160. package/src/rules/__tests__/integration-llm.test.ts +0 -89
  161. package/src/rules/database-injection/database-injection.test.ts +0 -456
  162. package/src/rules/database-injection/index.ts +0 -488
  163. package/src/rules/detect-child-process/detect-child-process.test.ts +0 -207
  164. package/src/rules/detect-child-process/index.ts +0 -634
  165. package/src/rules/detect-eval-with-expression/detect-eval-with-expression.test.ts +0 -416
  166. package/src/rules/detect-eval-with-expression/index.ts +0 -463
  167. package/src/rules/detect-mixed-content/detect-mixed-content.test.ts +0 -28
  168. package/src/rules/detect-mixed-content/index.ts +0 -52
  169. package/src/rules/detect-non-literal-fs-filename/detect-non-literal-fs-filename.test.ts +0 -269
  170. package/src/rules/detect-non-literal-fs-filename/index.ts +0 -551
  171. package/src/rules/detect-non-literal-regexp/detect-non-literal-regexp.test.ts +0 -189
  172. package/src/rules/detect-non-literal-regexp/index.ts +0 -490
  173. package/src/rules/detect-object-injection/detect-object-injection.test.ts +0 -440
  174. package/src/rules/detect-object-injection/index.ts +0 -674
  175. package/src/rules/detect-suspicious-dependencies/detect-suspicious-dependencies.test.ts +0 -32
  176. package/src/rules/detect-suspicious-dependencies/index.ts +0 -84
  177. package/src/rules/detect-weak-password-validation/detect-weak-password-validation.test.ts +0 -31
  178. package/src/rules/detect-weak-password-validation/index.ts +0 -68
  179. package/src/rules/no-allow-arbitrary-loads/index.ts +0 -54
  180. package/src/rules/no-allow-arbitrary-loads/no-allow-arbitrary-loads.test.ts +0 -28
  181. package/src/rules/no-arbitrary-file-access/index.ts +0 -238
  182. package/src/rules/no-arbitrary-file-access/no-arbitrary-file-access.test.ts +0 -119
  183. package/src/rules/no-buffer-overread/index.ts +0 -724
  184. package/src/rules/no-buffer-overread/no-buffer-overread.test.ts +0 -313
  185. package/src/rules/no-clickjacking/index.ts +0 -481
  186. package/src/rules/no-clickjacking/no-clickjacking.test.ts +0 -253
  187. package/src/rules/no-client-side-auth-logic/index.ts +0 -81
  188. package/src/rules/no-client-side-auth-logic/no-client-side-auth-logic.test.ts +0 -33
  189. package/src/rules/no-credentials-in-query-params/index.ts +0 -69
  190. package/src/rules/no-credentials-in-query-params/no-credentials-in-query-params.test.ts +0 -33
  191. package/src/rules/no-credentials-in-storage-api/index.ts +0 -64
  192. package/src/rules/no-credentials-in-storage-api/no-credentials-in-storage-api.test.ts +0 -31
  193. package/src/rules/no-data-in-temp-storage/index.ts +0 -75
  194. package/src/rules/no-data-in-temp-storage/no-data-in-temp-storage.test.ts +0 -33
  195. package/src/rules/no-debug-code-in-production/index.ts +0 -59
  196. package/src/rules/no-debug-code-in-production/no-debug-code-in-production.test.ts +0 -26
  197. package/src/rules/no-directive-injection/index.ts +0 -551
  198. package/src/rules/no-directive-injection/no-directive-injection.test.ts +0 -305
  199. package/src/rules/no-disabled-certificate-validation/index.ts +0 -72
  200. package/src/rules/no-disabled-certificate-validation/no-disabled-certificate-validation.test.ts +0 -33
  201. package/src/rules/no-document-cookie/index.ts +0 -113
  202. package/src/rules/no-document-cookie/no-document-cookie.test.ts +0 -382
  203. package/src/rules/no-dynamic-dependency-loading/index.ts +0 -60
  204. package/src/rules/no-dynamic-dependency-loading/no-dynamic-dependency-loading.test.ts +0 -27
  205. package/src/rules/no-electron-security-issues/index.ts +0 -504
  206. package/src/rules/no-electron-security-issues/no-electron-security-issues.test.ts +0 -324
  207. package/src/rules/no-exposed-debug-endpoints/index.ts +0 -73
  208. package/src/rules/no-exposed-debug-endpoints/no-exposed-debug-endpoints.test.ts +0 -40
  209. package/src/rules/no-exposed-sensitive-data/index.ts +0 -428
  210. package/src/rules/no-exposed-sensitive-data/no-exposed-sensitive-data.test.ts +0 -75
  211. package/src/rules/no-format-string-injection/index.ts +0 -801
  212. package/src/rules/no-format-string-injection/no-format-string-injection.test.ts +0 -437
  213. package/src/rules/no-graphql-injection/index.ts +0 -508
  214. package/src/rules/no-graphql-injection/no-graphql-injection.test.ts +0 -371
  215. package/src/rules/no-hardcoded-credentials/index.ts +0 -478
  216. package/src/rules/no-hardcoded-credentials/no-hardcoded-credentials.test.ts +0 -639
  217. package/src/rules/no-hardcoded-session-tokens/index.ts +0 -69
  218. package/src/rules/no-hardcoded-session-tokens/no-hardcoded-session-tokens.test.ts +0 -42
  219. package/src/rules/no-http-urls/index.ts +0 -131
  220. package/src/rules/no-http-urls/no-http-urls.test.ts +0 -60
  221. package/src/rules/no-improper-sanitization/index.ts +0 -502
  222. package/src/rules/no-improper-sanitization/no-improper-sanitization.test.ts +0 -156
  223. package/src/rules/no-improper-type-validation/index.ts +0 -572
  224. package/src/rules/no-improper-type-validation/no-improper-type-validation.test.ts +0 -372
  225. package/src/rules/no-insecure-comparison/index.ts +0 -232
  226. package/src/rules/no-insecure-comparison/no-insecure-comparison.test.ts +0 -218
  227. package/src/rules/no-insecure-cookie-settings/index.ts +0 -391
  228. package/src/rules/no-insecure-cookie-settings/no-insecure-cookie-settings.test.ts +0 -409
  229. package/src/rules/no-insecure-jwt/index.ts +0 -467
  230. package/src/rules/no-insecure-jwt/no-insecure-jwt.test.ts +0 -259
  231. package/src/rules/no-insecure-redirects/index.ts +0 -267
  232. package/src/rules/no-insecure-redirects/no-insecure-redirects.test.ts +0 -108
  233. package/src/rules/no-insecure-websocket/index.ts +0 -72
  234. package/src/rules/no-insecure-websocket/no-insecure-websocket.test.ts +0 -42
  235. package/src/rules/no-insufficient-postmessage-validation/index.ts +0 -497
  236. package/src/rules/no-insufficient-postmessage-validation/no-insufficient-postmessage-validation.test.ts +0 -360
  237. package/src/rules/no-insufficient-random/index.ts +0 -288
  238. package/src/rules/no-insufficient-random/no-insufficient-random.test.ts +0 -246
  239. package/src/rules/no-ldap-injection/index.ts +0 -547
  240. package/src/rules/no-ldap-injection/no-ldap-injection.test.ts +0 -317
  241. package/src/rules/no-missing-authentication/index.ts +0 -408
  242. package/src/rules/no-missing-authentication/no-missing-authentication.test.ts +0 -350
  243. package/src/rules/no-missing-cors-check/index.ts +0 -453
  244. package/src/rules/no-missing-cors-check/no-missing-cors-check.test.ts +0 -392
  245. package/src/rules/no-missing-csrf-protection/index.ts +0 -229
  246. package/src/rules/no-missing-csrf-protection/no-missing-csrf-protection.test.ts +0 -222
  247. package/src/rules/no-missing-security-headers/index.ts +0 -266
  248. package/src/rules/no-missing-security-headers/no-missing-security-headers.test.ts +0 -98
  249. package/src/rules/no-password-in-url/index.ts +0 -64
  250. package/src/rules/no-password-in-url/no-password-in-url.test.ts +0 -27
  251. package/src/rules/no-permissive-cors/index.ts +0 -78
  252. package/src/rules/no-permissive-cors/no-permissive-cors.test.ts +0 -28
  253. package/src/rules/no-pii-in-logs/index.ts +0 -83
  254. package/src/rules/no-pii-in-logs/no-pii-in-logs.test.ts +0 -26
  255. package/src/rules/no-postmessage-origin-wildcard/index.ts +0 -67
  256. package/src/rules/no-postmessage-origin-wildcard/no-postmessage-origin-wildcard.test.ts +0 -27
  257. package/src/rules/no-privilege-escalation/index.ts +0 -403
  258. package/src/rules/no-privilege-escalation/no-privilege-escalation.test.ts +0 -306
  259. package/src/rules/no-redos-vulnerable-regex/index.ts +0 -379
  260. package/src/rules/no-redos-vulnerable-regex/no-redos-vulnerable-regex.test.ts +0 -83
  261. package/src/rules/no-sensitive-data-exposure/index.ts +0 -294
  262. package/src/rules/no-sensitive-data-exposure/no-sensitive-data-exposure.test.ts +0 -262
  263. package/src/rules/no-sensitive-data-in-analytics/index.ts +0 -73
  264. package/src/rules/no-sensitive-data-in-analytics/no-sensitive-data-in-analytics.test.ts +0 -42
  265. package/src/rules/no-sensitive-data-in-cache/index.ts +0 -59
  266. package/src/rules/no-sensitive-data-in-cache/no-sensitive-data-in-cache.test.ts +0 -32
  267. package/src/rules/no-sql-injection/index.ts +0 -424
  268. package/src/rules/no-sql-injection/no-sql-injection.test.ts +0 -303
  269. package/src/rules/no-timing-attack/index.ts +0 -552
  270. package/src/rules/no-timing-attack/no-timing-attack.test.ts +0 -348
  271. package/src/rules/no-toctou-vulnerability/index.ts +0 -250
  272. package/src/rules/no-toctou-vulnerability/no-toctou-vulnerability.test.ts +0 -60
  273. package/src/rules/no-tracking-without-consent/index.ts +0 -78
  274. package/src/rules/no-tracking-without-consent/no-tracking-without-consent.test.ts +0 -34
  275. package/src/rules/no-unchecked-loop-condition/index.ts +0 -781
  276. package/src/rules/no-unchecked-loop-condition/no-unchecked-loop-condition.test.ts +0 -459
  277. package/src/rules/no-unencrypted-local-storage/index.ts +0 -73
  278. package/src/rules/no-unencrypted-local-storage/no-unencrypted-local-storage.test.ts +0 -41
  279. package/src/rules/no-unencrypted-transmission/index.ts +0 -296
  280. package/src/rules/no-unencrypted-transmission/no-unencrypted-transmission.test.ts +0 -287
  281. package/src/rules/no-unescaped-url-parameter/index.ts +0 -424
  282. package/src/rules/no-unescaped-url-parameter/no-unescaped-url-parameter.test.ts +0 -263
  283. package/src/rules/no-unlimited-resource-allocation/index.ts +0 -767
  284. package/src/rules/no-unlimited-resource-allocation/no-unlimited-resource-allocation.test.ts +0 -544
  285. package/src/rules/no-unsafe-deserialization/index.ts +0 -593
  286. package/src/rules/no-unsafe-deserialization/no-unsafe-deserialization.test.ts +0 -310
  287. package/src/rules/no-unsafe-dynamic-require/index.ts +0 -125
  288. package/src/rules/no-unsafe-dynamic-require/no-unsafe-dynamic-require.test.ts +0 -151
  289. package/src/rules/no-unsafe-regex-construction/index.ts +0 -370
  290. package/src/rules/no-unsafe-regex-construction/no-unsafe-regex-construction.test.ts +0 -181
  291. package/src/rules/no-unsanitized-html/index.ts +0 -400
  292. package/src/rules/no-unsanitized-html/no-unsanitized-html.test.ts +0 -488
  293. package/src/rules/no-unvalidated-deeplinks/index.ts +0 -73
  294. package/src/rules/no-unvalidated-deeplinks/no-unvalidated-deeplinks.test.ts +0 -29
  295. package/src/rules/no-unvalidated-user-input/index.ts +0 -498
  296. package/src/rules/no-unvalidated-user-input/no-unvalidated-user-input.test.ts +0 -463
  297. package/src/rules/no-verbose-error-messages/index.ts +0 -83
  298. package/src/rules/no-verbose-error-messages/no-verbose-error-messages.test.ts +0 -34
  299. package/src/rules/no-weak-crypto/index.ts +0 -447
  300. package/src/rules/no-weak-crypto/no-weak-crypto.test.ts +0 -297
  301. package/src/rules/no-weak-password-recovery/index.ts +0 -509
  302. package/src/rules/no-weak-password-recovery/no-weak-password-recovery.test.ts +0 -184
  303. package/src/rules/no-xpath-injection/index.ts +0 -596
  304. package/src/rules/no-xpath-injection/no-xpath-injection.test.ts +0 -405
  305. package/src/rules/no-xxe-injection/index.ts +0 -342
  306. package/src/rules/no-xxe-injection/no-xxe-injection.test.ts +0 -122
  307. package/src/rules/no-zip-slip/index.ts +0 -526
  308. package/src/rules/no-zip-slip/no-zip-slip.test.ts +0 -305
  309. package/src/rules/require-backend-authorization/index.ts +0 -71
  310. package/src/rules/require-backend-authorization/require-backend-authorization.test.ts +0 -31
  311. package/src/rules/require-code-minification/index.ts +0 -54
  312. package/src/rules/require-code-minification/require-code-minification.test.ts +0 -30
  313. package/src/rules/require-csp-headers/index.ts +0 -74
  314. package/src/rules/require-csp-headers/require-csp-headers.test.ts +0 -34
  315. package/src/rules/require-data-minimization/index.ts +0 -65
  316. package/src/rules/require-data-minimization/require-data-minimization.test.ts +0 -31
  317. package/src/rules/require-dependency-integrity/index.ts +0 -78
  318. package/src/rules/require-dependency-integrity/require-dependency-integrity.test.ts +0 -44
  319. package/src/rules/require-https-only/index.ts +0 -75
  320. package/src/rules/require-https-only/require-https-only.test.ts +0 -26
  321. package/src/rules/require-mime-type-validation/index.ts +0 -77
  322. package/src/rules/require-mime-type-validation/require-mime-type-validation.test.ts +0 -32
  323. package/src/rules/require-network-timeout/index.ts +0 -58
  324. package/src/rules/require-network-timeout/require-network-timeout.test.ts +0 -26
  325. package/src/rules/require-package-lock/index.ts +0 -75
  326. package/src/rules/require-package-lock/require-package-lock.test.ts +0 -27
  327. package/src/rules/require-secure-credential-storage/index.ts +0 -60
  328. package/src/rules/require-secure-credential-storage/require-secure-credential-storage.test.ts +0 -26
  329. package/src/rules/require-secure-defaults/index.ts +0 -54
  330. package/src/rules/require-secure-defaults/require-secure-defaults.test.ts +0 -26
  331. package/src/rules/require-secure-deletion/index.ts +0 -52
  332. package/src/rules/require-secure-deletion/require-secure-deletion.test.ts +0 -29
  333. package/src/rules/require-storage-encryption/index.ts +0 -60
  334. package/src/rules/require-storage-encryption/require-storage-encryption.test.ts +0 -26
  335. package/src/rules/require-url-validation/index.ts +0 -85
  336. package/src/rules/require-url-validation/require-url-validation.test.ts +0 -32
  337. package/src/types/index.ts +0 -235
@@ -0,0 +1,321 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.noPrivilegeEscalation = void 0;
4
+ const eslint_devkit_1 = require("@interlace/eslint-devkit");
5
+ const eslint_devkit_2 = require("@interlace/eslint-devkit");
6
+ /**
7
+ * Common role check patterns
8
+ */
9
+ const DEFAULT_ROLE_CHECK_PATTERNS = [
10
+ 'hasRole',
11
+ 'checkRole',
12
+ 'isAdmin',
13
+ 'isAuthorized',
14
+ 'hasPermission',
15
+ 'checkPermission',
16
+ 'verifyRole',
17
+ 'requireRole',
18
+ ];
19
+ /**
20
+ * Common user input patterns
21
+ */
22
+ const DEFAULT_USER_INPUT_PATTERNS = [
23
+ /\breq\.(body|query|params)\b/,
24
+ /\brequest\.(body|query|params)\b/,
25
+ /\buserInput\b/,
26
+ /\binput\b/,
27
+ ];
28
+ /**
29
+ * Check if a string matches any ignore pattern
30
+ */
31
+ function matchesIgnorePattern(text, patterns) {
32
+ return patterns.some(pattern => {
33
+ try {
34
+ const regex = new RegExp(pattern, 'i');
35
+ return regex.test(text);
36
+ }
37
+ catch {
38
+ // Invalid regex - treat as literal string match
39
+ return text.toLowerCase().includes(pattern.toLowerCase());
40
+ }
41
+ });
42
+ }
43
+ /**
44
+ * Check if a node contains user input patterns
45
+ */
46
+ function containsUserInput(node, sourceCode, userInputPatterns) {
47
+ const text = sourceCode.getText(node);
48
+ return userInputPatterns.some(pattern => pattern.test(text));
49
+ }
50
+ /**
51
+ * Check if a node is inside a role check call
52
+ */
53
+ function isInsideRoleCheck(node, sourceCode, roleCheckPatterns) {
54
+ let current = node;
55
+ while (current) {
56
+ // Check if current is inside an IfStatement with role check in condition
57
+ if (current.parent && current.parent.type === 'IfStatement') {
58
+ const ifStmt = current.parent;
59
+ const conditionText = sourceCode.getText(ifStmt.test);
60
+ // Check if condition contains role check patterns (text-based check catches all patterns)
61
+ if (roleCheckPatterns.some(pattern => conditionText.toLowerCase().includes(pattern.toLowerCase()))) {
62
+ return true;
63
+ }
64
+ }
65
+ // Check if current is inside a ConditionalExpression (ternary) with role check
66
+ if (current.parent && current.parent.type === 'ConditionalExpression') {
67
+ const condExpr = current.parent;
68
+ const testText = sourceCode.getText(condExpr.test);
69
+ // Check if test contains role check patterns (text-based check catches all patterns)
70
+ if (roleCheckPatterns.some(pattern => testText.toLowerCase().includes(pattern.toLowerCase()))) {
71
+ return true;
72
+ }
73
+ }
74
+ // Check if current is inside a CallExpression with role check
75
+ if (current.parent && current.parent.type === 'CallExpression') {
76
+ const callExpr = current.parent;
77
+ const callee = callExpr.callee;
78
+ if (callee.type === 'Identifier') {
79
+ const calleeName = callee.name.toLowerCase();
80
+ if (roleCheckPatterns.some(pattern => calleeName.includes(pattern.toLowerCase()))) {
81
+ return true;
82
+ }
83
+ }
84
+ if (callee.type === 'MemberExpression' && callee.property.type === 'Identifier') {
85
+ const propertyName = callee.property.name.toLowerCase();
86
+ if (roleCheckPatterns.some(pattern => propertyName.includes(pattern.toLowerCase()))) {
87
+ return true;
88
+ }
89
+ }
90
+ }
91
+ // Traverse up the AST
92
+ if ('parent' in current && current.parent) {
93
+ current = current.parent;
94
+ }
95
+ else {
96
+ break;
97
+ }
98
+ }
99
+ return false;
100
+ }
101
+ exports.noPrivilegeEscalation = (0, eslint_devkit_2.createRule)({
102
+ name: 'no-privilege-escalation',
103
+ meta: {
104
+ type: 'problem',
105
+ docs: {
106
+ description: 'Detects potential privilege escalation vulnerabilities',
107
+ },
108
+ hasSuggestions: true,
109
+ messages: {
110
+ privilegeEscalation: (0, eslint_devkit_1.formatLLMMessage)({
111
+ icon: eslint_devkit_1.MessageIcons.SECURITY,
112
+ issueName: 'Privilege Escalation',
113
+ cwe: 'CWE-269',
114
+ description: 'Potential privilege escalation: {{issue}} - user input used without role validation',
115
+ severity: 'HIGH',
116
+ fix: 'Add role check before using user input: if (!hasRole(user, requiredRole)) throw new Error("Unauthorized");',
117
+ documentationLink: 'https://cwe.mitre.org/data/definitions/269.html',
118
+ }),
119
+ addRoleCheck: (0, eslint_devkit_1.formatLLMMessage)({
120
+ icon: eslint_devkit_1.MessageIcons.INFO,
121
+ issueName: 'Add Role Check',
122
+ description: 'Add role check before privilege operations',
123
+ severity: 'LOW',
124
+ fix: 'if (!hasRole(user, requiredRole)) throw new Error("Unauthorized")',
125
+ documentationLink: 'https://cwe.mitre.org/data/definitions/269.html',
126
+ }),
127
+ },
128
+ schema: [
129
+ {
130
+ type: 'object',
131
+ properties: {
132
+ allowInTests: {
133
+ type: 'boolean',
134
+ default: false,
135
+ description: 'Allow privilege escalation patterns in test files',
136
+ },
137
+ testFilePattern: {
138
+ type: 'string',
139
+ default: '\\.(test|spec)\\.(ts|tsx|js|jsx)$',
140
+ description: 'Test file pattern regex string',
141
+ },
142
+ roleCheckPatterns: {
143
+ type: 'array',
144
+ items: { type: 'string' },
145
+ default: DEFAULT_ROLE_CHECK_PATTERNS,
146
+ description: 'Role check patterns to recognize',
147
+ },
148
+ userInputPatterns: {
149
+ type: 'array',
150
+ items: { type: 'string' },
151
+ default: [],
152
+ description: 'Additional user input patterns to check (regex strings)',
153
+ },
154
+ ignorePatterns: {
155
+ type: 'array',
156
+ items: { type: 'string' },
157
+ default: [],
158
+ description: 'Additional patterns to ignore',
159
+ },
160
+ },
161
+ additionalProperties: false,
162
+ },
163
+ ],
164
+ },
165
+ defaultOptions: [
166
+ {
167
+ allowInTests: false,
168
+ testFilePattern: '\\.(test|spec)\\.(ts|tsx|js|jsx)$',
169
+ roleCheckPatterns: DEFAULT_ROLE_CHECK_PATTERNS,
170
+ userInputPatterns: [],
171
+ ignorePatterns: [],
172
+ },
173
+ ],
174
+ create(context, [options = {}]) {
175
+ const { allowInTests = false, testFilePattern = '\\.(test|spec)\\.(ts|tsx|js|jsx)$', roleCheckPatterns = DEFAULT_ROLE_CHECK_PATTERNS, userInputPatterns: additionalUserInputPatterns = [], ignorePatterns = [], } = options;
176
+ const filename = context.getFilename();
177
+ const testFileRegex = new RegExp(testFilePattern);
178
+ const isTestFile = allowInTests && testFileRegex.test(filename);
179
+ const sourceCode = context.sourceCode || context.sourceCode;
180
+ // Combine default and additional user input patterns
181
+ const userInputPatterns = [
182
+ ...DEFAULT_USER_INPUT_PATTERNS,
183
+ ...additionalUserInputPatterns.map(pattern => new RegExp(pattern, 'i')),
184
+ ];
185
+ /**
186
+ * Check AssignmentExpression for privilege escalation
187
+ */
188
+ function checkAssignmentExpression(node) {
189
+ if (isTestFile) {
190
+ return;
191
+ }
192
+ // Check for role assignment from user input
193
+ // Pattern: user.role = req.body.role
194
+ if (node.left.type === 'MemberExpression' &&
195
+ node.left.property.type === 'Identifier') {
196
+ const propertyName = node.left.property.name.toLowerCase();
197
+ // Check if it's a role/permission related property
198
+ if (['role', 'permission', 'privilege', 'access', 'level'].includes(propertyName)) {
199
+ const text = sourceCode.getText(node);
200
+ // Check if it matches any ignore pattern
201
+ if (matchesIgnorePattern(text, ignorePatterns)) {
202
+ return;
203
+ }
204
+ // Check if right side contains user input
205
+ if (containsUserInput(node.right, sourceCode, userInputPatterns)) {
206
+ // Check if it's inside a role check
207
+ if (!isInsideRoleCheck(node, sourceCode, roleCheckPatterns)) {
208
+ context.report({
209
+ node: node,
210
+ messageId: 'privilegeEscalation',
211
+ data: {
212
+ issue: `Role assignment from user input: ${sourceCode.getText(node.left)} = ${sourceCode.getText(node.right)}`,
213
+ },
214
+ suggest: [
215
+ {
216
+ messageId: 'addRoleCheck',
217
+ fix: () => null,
218
+ },
219
+ ],
220
+ });
221
+ }
222
+ }
223
+ }
224
+ }
225
+ }
226
+ /**
227
+ * Check CallExpression for privilege operations with user input
228
+ */
229
+ function checkCallExpression(node) {
230
+ if (isTestFile) {
231
+ return;
232
+ }
233
+ // Check for privilege-related function calls with user input
234
+ const callee = node.callee;
235
+ let isPrivilegeOperation = false;
236
+ let operationName = '';
237
+ if (callee.type === 'Identifier') {
238
+ const calleeName = callee.name.toLowerCase();
239
+ if (['setrole', 'grant', 'revoke', 'elevate', 'promote'].some(op => calleeName.includes(op))) {
240
+ isPrivilegeOperation = true;
241
+ operationName = callee.name;
242
+ }
243
+ }
244
+ if (callee.type === 'MemberExpression' && callee.property.type === 'Identifier') {
245
+ const propertyName = callee.property.name.toLowerCase();
246
+ if (['setrole', 'grant', 'revoke', 'elevate', 'promote', 'updaterole'].some(op => propertyName.includes(op))) {
247
+ isPrivilegeOperation = true;
248
+ operationName = propertyName;
249
+ }
250
+ }
251
+ if (isPrivilegeOperation) {
252
+ const text = sourceCode.getText(node);
253
+ // Check if it matches any ignore pattern
254
+ if (matchesIgnorePattern(text, ignorePatterns)) {
255
+ return;
256
+ }
257
+ // Check if any argument contains user input
258
+ for (const arg of node.arguments) {
259
+ if (containsUserInput(arg, sourceCode, userInputPatterns)) {
260
+ // Check if it's inside a role check
261
+ if (!isInsideRoleCheck(node, sourceCode, roleCheckPatterns)) {
262
+ context.report({
263
+ node: node,
264
+ messageId: 'privilegeEscalation',
265
+ data: {
266
+ issue: `Privilege operation (${operationName}) with user input without role validation`,
267
+ },
268
+ suggest: [
269
+ {
270
+ messageId: 'addRoleCheck',
271
+ fix: () => null,
272
+ },
273
+ ],
274
+ });
275
+ return; // Report once per call
276
+ }
277
+ }
278
+ }
279
+ }
280
+ }
281
+ /**
282
+ * Check ObjectExpression for role assignment in objects (e.g. arguments)
283
+ */
284
+ function checkObjectExpression(node) {
285
+ if (isTestFile)
286
+ return;
287
+ for (const prop of node.properties) {
288
+ if (prop.type === 'Property' && prop.key.type === 'Identifier') {
289
+ const keyName = prop.key.name.toLowerCase();
290
+ if (['role', 'permission', 'privilege', 'access', 'level'].includes(keyName)) {
291
+ const text = sourceCode.getText(prop);
292
+ if (matchesIgnorePattern(text, ignorePatterns))
293
+ continue;
294
+ if (containsUserInput(prop.value, sourceCode, userInputPatterns)) {
295
+ if (!isInsideRoleCheck(node, sourceCode, roleCheckPatterns)) {
296
+ context.report({
297
+ node: prop,
298
+ messageId: 'privilegeEscalation',
299
+ data: {
300
+ issue: `Role assignment in object from user input: ${sourceCode.getText(prop)}`,
301
+ },
302
+ suggest: [
303
+ {
304
+ messageId: 'addRoleCheck',
305
+ fix: () => null, // No auto-fix for logic
306
+ },
307
+ ],
308
+ });
309
+ }
310
+ }
311
+ }
312
+ }
313
+ }
314
+ }
315
+ return {
316
+ AssignmentExpression: checkAssignmentExpression,
317
+ CallExpression: checkCallExpression,
318
+ ObjectExpression: checkObjectExpression,
319
+ };
320
+ },
321
+ });
@@ -0,0 +1,7 @@
1
+ export interface Options {
2
+ /** Allow certain common patterns. Default: false */
3
+ allowCommonPatterns?: boolean;
4
+ /** Maximum pattern length to analyze. Default: 500 */
5
+ maxPatternLength?: number;
6
+ }
7
+ export declare const noRedosVulnerableRegex: ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;
@@ -0,0 +1,306 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.noRedosVulnerableRegex = void 0;
4
+ const eslint_devkit_1 = require("@interlace/eslint-devkit");
5
+ const eslint_devkit_2 = require("@interlace/eslint-devkit");
6
+ // Type guard for regex literal nodes
7
+ const isRegExpLiteral = (node) => {
8
+ return node.type === 'Literal' && Object.prototype.hasOwnProperty.call(node, 'regex');
9
+ };
10
+ const REDOS_PATTERNS = [
11
+ {
12
+ pattern: /\([^)]*\+\)\+|\([^)]*\*\)\*|\([^)]*\?\)\?/,
13
+ name: 'Nested Quantifiers',
14
+ description: 'Nested quantifiers like (a+)+, (a*)*, (a?)? cause exponential backtracking',
15
+ example: {
16
+ bad: '/(a+)+b/',
17
+ good: '/(?>a+)b/ or /a+b/'
18
+ },
19
+ fix: 'Use atomic groups (?>...) or restructure to avoid nesting',
20
+ severity: 'critical'
21
+ },
22
+ {
23
+ pattern: /\([^)]*\+[^)]*\)\+|\([^)]*\*[^)]*\)\*/,
24
+ name: 'Nested Repetition',
25
+ description: 'Quantifiers nested within groups with quantifiers',
26
+ example: {
27
+ bad: '/(x+)+y/',
28
+ good: '/x+y/'
29
+ },
30
+ fix: 'Flatten nested quantifiers',
31
+ severity: 'critical'
32
+ },
33
+ {
34
+ pattern: /\([^)]*\|[^)]*\)\+|\([^)]*\|[^)]*\)\*/,
35
+ name: 'Alternation with Quantifier',
36
+ description: 'Alternation groups with quantifiers can cause backtracking',
37
+ example: {
38
+ bad: '/(a|b)+c/',
39
+ good: '/[ab]+c/'
40
+ },
41
+ fix: 'Use character classes instead of alternation when possible',
42
+ severity: 'high'
43
+ },
44
+ {
45
+ pattern: /\.\*\.\*|\.\+\+\.\+/,
46
+ name: 'Nested Wildcards',
47
+ description: 'Nested wildcard quantifiers cause catastrophic backtracking',
48
+ example: {
49
+ bad: '/.*.*/',
50
+ good: '/.*/ or be more specific'
51
+ },
52
+ fix: 'Remove redundant wildcards or be more specific',
53
+ severity: 'critical'
54
+ },
55
+ {
56
+ pattern: /\([^)]*\)\{[0-9]+,\}[^)]*\([^)]*\)\{[0-9]+,\}/,
57
+ name: 'Multiple Repetition Groups',
58
+ description: 'Multiple repetition groups can cause exponential backtracking',
59
+ example: {
60
+ bad: '/(a{2,})+(b{2,})+/',
61
+ good: 'Restructure to avoid nested repetitions'
62
+ },
63
+ fix: 'Restructure regex to avoid nested repetitions',
64
+ severity: 'high'
65
+ }
66
+ ];
67
+ /**
68
+ * Check if a regex pattern contains ReDoS vulnerabilities
69
+ */
70
+ function hasReDoSVulnerability(pattern) {
71
+ for (const redosPattern of REDOS_PATTERNS) {
72
+ if (redosPattern.pattern.test(pattern)) {
73
+ return redosPattern;
74
+ }
75
+ }
76
+ // Additional checks for common ReDoS patterns
77
+ // Nested quantifiers: (a+)+, (a*)*, (a?)?
78
+ if (/(\([^)]*[+*?][^)]*\)[+*?])/.test(pattern)) {
79
+ return {
80
+ pattern: /\([^)]*[+*?][^)]*\)[+*?]/,
81
+ name: 'Nested Quantifier Pattern',
82
+ description: 'Pattern contains nested quantifiers that can cause exponential backtracking',
83
+ example: {
84
+ bad: pattern.substring(0, 30),
85
+ good: 'Restructure to avoid nested quantifiers'
86
+ },
87
+ fix: 'Use atomic groups or restructure regex',
88
+ severity: 'critical'
89
+ };
90
+ }
91
+ return null;
92
+ }
93
+ /**
94
+ * Generate fix suggestions based on the vulnerability
95
+ */
96
+ function generateFixSuggestions(vulnerability) {
97
+ const suggestions = [];
98
+ if (vulnerability.severity === 'critical' || vulnerability.name.includes('Nested')) {
99
+ suggestions.push({
100
+ messageId: 'useAtomicGroups',
101
+ description: vulnerability.fix
102
+ });
103
+ suggestions.push({
104
+ messageId: 'restructureRegex',
105
+ description: 'Restructure the regex to avoid nested quantifiers'
106
+ });
107
+ }
108
+ if (vulnerability.name.includes('Quantifier')) {
109
+ suggestions.push({
110
+ messageId: 'usePossessiveQuantifiers',
111
+ description: 'Use possessive quantifiers (*+, ++, ?+) if supported'
112
+ });
113
+ }
114
+ suggestions.push({
115
+ messageId: 'useSafeLibrary',
116
+ description: 'Consider using safe-regex library to validate patterns'
117
+ });
118
+ return suggestions;
119
+ }
120
+ exports.noRedosVulnerableRegex = (0, eslint_devkit_2.createRule)({
121
+ name: 'no-redos-vulnerable-regex',
122
+ meta: {
123
+ type: 'problem',
124
+ docs: {
125
+ description: 'Detects ReDoS-vulnerable regex patterns in literal regex patterns',
126
+ },
127
+ hasSuggestions: true,
128
+ messages: {
129
+ redosVulnerable: (0, eslint_devkit_1.formatLLMMessage)({
130
+ icon: eslint_devkit_1.MessageIcons.SECURITY,
131
+ issueName: 'ReDoS vulnerable regex',
132
+ cwe: 'CWE-400',
133
+ description: '{{vulnerabilityName}}: {{description}}',
134
+ severity: '{{severity}}',
135
+ fix: '{{fix}}',
136
+ documentationLink: 'https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS',
137
+ }),
138
+ useAtomicGroups: (0, eslint_devkit_1.formatLLMMessage)({
139
+ icon: eslint_devkit_1.MessageIcons.INFO,
140
+ issueName: 'Use Atomic Groups',
141
+ description: 'Use atomic groups to prevent backtracking',
142
+ severity: 'LOW',
143
+ fix: '(?>...) to prevent backtracking',
144
+ documentationLink: 'https://www.regular-expressions.info/atomic.html',
145
+ }),
146
+ usePossessiveQuantifiers: (0, eslint_devkit_1.formatLLMMessage)({
147
+ icon: eslint_devkit_1.MessageIcons.INFO,
148
+ issueName: 'Use Possessive Quantifiers',
149
+ description: 'Use possessive quantifiers',
150
+ severity: 'LOW',
151
+ fix: '*+, ++, ?+ (if supported)',
152
+ documentationLink: 'https://www.regular-expressions.info/possessive.html',
153
+ }),
154
+ restructureRegex: (0, eslint_devkit_1.formatLLMMessage)({
155
+ icon: eslint_devkit_1.MessageIcons.INFO,
156
+ issueName: 'Restructure Regex',
157
+ description: 'Restructure to avoid nested quantifiers',
158
+ severity: 'LOW',
159
+ fix: 'Avoid (a+)+ patterns',
160
+ documentationLink: 'https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS',
161
+ }),
162
+ useSafeLibrary: (0, eslint_devkit_1.formatLLMMessage)({
163
+ icon: eslint_devkit_1.MessageIcons.INFO,
164
+ issueName: 'Use safe-regex',
165
+ description: 'Validate with safe-regex library',
166
+ severity: 'LOW',
167
+ fix: 'if (safeRegex(pattern)) { new RegExp(pattern) }',
168
+ documentationLink: 'https://github.com/substack/safe-regex',
169
+ }),
170
+ },
171
+ schema: [
172
+ {
173
+ type: 'object',
174
+ properties: {
175
+ allowCommonPatterns: {
176
+ type: 'boolean',
177
+ default: false,
178
+ description: 'Allow certain common patterns',
179
+ },
180
+ maxPatternLength: {
181
+ type: 'number',
182
+ default: 500,
183
+ minimum: 1,
184
+ description: 'Maximum pattern length to analyze',
185
+ },
186
+ },
187
+ additionalProperties: false,
188
+ },
189
+ ],
190
+ },
191
+ defaultOptions: [
192
+ {
193
+ allowCommonPatterns: false,
194
+ maxPatternLength: 500,
195
+ },
196
+ ],
197
+ create(context, [options = {}]) {
198
+ const { allowCommonPatterns = false, maxPatternLength = 500 } = options || {};
199
+ /**
200
+ * Check literal regex patterns for ReDoS vulnerabilities
201
+ */
202
+ function checkLiteralRegExp(node) {
203
+ if (!isRegExpLiteral(node)) {
204
+ return;
205
+ }
206
+ const pattern = node.regex.pattern;
207
+ // Skip if pattern is too long (performance)
208
+ if (pattern.length > maxPatternLength) {
209
+ return;
210
+ }
211
+ const vulnerability = hasReDoSVulnerability(pattern);
212
+ if (!vulnerability) {
213
+ return;
214
+ }
215
+ // Allow common patterns if configured
216
+ if (allowCommonPatterns && (vulnerability.severity === 'medium' || vulnerability.name === 'Alternation with Quantifier')) {
217
+ return;
218
+ }
219
+ const suggestions = generateFixSuggestions(vulnerability);
220
+ const severity = vulnerability.severity.toUpperCase();
221
+ context.report({
222
+ node,
223
+ messageId: 'redosVulnerable',
224
+ data: {
225
+ vulnerabilityName: vulnerability.name,
226
+ description: vulnerability.description,
227
+ severity,
228
+ fix: vulnerability.fix,
229
+ },
230
+ suggest: suggestions.map(suggestion => ({
231
+ messageId: suggestion.messageId,
232
+ fix: () => null, // Complex refactoring, cannot auto-fix
233
+ })),
234
+ });
235
+ }
236
+ /**
237
+ * Check new RegExp() calls for ReDoS vulnerabilities
238
+ */
239
+ function checkNewRegExp(node) {
240
+ // Check for new RegExp(pattern) or RegExp(pattern)
241
+ let callee;
242
+ if (node.type === 'NewExpression') {
243
+ callee = node.callee;
244
+ }
245
+ else if (node.type === 'CallExpression') {
246
+ callee = node.callee;
247
+ }
248
+ else {
249
+ /* c8 ignore next */
250
+ return;
251
+ }
252
+ const isRegExp = callee.type === 'Identifier' && callee.name === 'RegExp';
253
+ if (!isRegExp) {
254
+ /* c8 ignore next */
255
+ return;
256
+ }
257
+ // Check if first argument is a string literal
258
+ if (node.arguments.length === 0) {
259
+ /* c8 ignore next */
260
+ return;
261
+ }
262
+ const firstArg = node.arguments[0];
263
+ if (firstArg.type !== 'Literal' || typeof firstArg.value !== 'string') {
264
+ /* c8 ignore next */
265
+ return;
266
+ }
267
+ const pattern = firstArg.value;
268
+ // Skip if pattern is too long (performance)
269
+ if (pattern.length > maxPatternLength) {
270
+ /* c8 ignore next */
271
+ return;
272
+ }
273
+ const vulnerability = hasReDoSVulnerability(pattern);
274
+ if (!vulnerability) {
275
+ /* c8 ignore next */
276
+ return;
277
+ }
278
+ // Allow common patterns if configured
279
+ if (allowCommonPatterns && (vulnerability.severity === 'medium' || vulnerability.name === 'Alternation with Quantifier')) {
280
+ /* c8 ignore next */
281
+ return;
282
+ }
283
+ const suggestions = generateFixSuggestions(vulnerability);
284
+ const severity = vulnerability.severity.toUpperCase();
285
+ context.report({
286
+ node,
287
+ messageId: 'redosVulnerable',
288
+ data: {
289
+ vulnerabilityName: vulnerability.name,
290
+ description: vulnerability.description,
291
+ severity,
292
+ fix: vulnerability.fix,
293
+ },
294
+ suggest: suggestions.map(suggestion => ({
295
+ messageId: suggestion.messageId,
296
+ fix: () => null, // Complex refactoring, cannot auto-fix
297
+ })),
298
+ });
299
+ }
300
+ return {
301
+ Literal: checkLiteralRegExp,
302
+ CallExpression: checkNewRegExp,
303
+ NewExpression: checkNewRegExp,
304
+ };
305
+ },
306
+ });
@@ -0,0 +1,11 @@
1
+ export interface Options {
2
+ /** Sensitive data patterns. Default: ['password', 'secret', 'token', 'key', 'ssn', 'credit', 'card'] */
3
+ sensitivePatterns?: string[];
4
+ /** Check console.log statements. Default: true */
5
+ checkConsoleLog?: boolean;
6
+ /** Check error messages. Default: true */
7
+ checkErrorMessages?: boolean;
8
+ /** Check API responses. Default: true */
9
+ checkApiResponses?: boolean;
10
+ }
11
+ export declare const noSensitiveDataExposure: ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;