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,643 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.noUnlimitedResourceAllocation = void 0;
4
+ const eslint_devkit_1 = require("@interlace/eslint-devkit");
5
+ const eslint_devkit_2 = require("@interlace/eslint-devkit");
6
+ const eslint_devkit_3 = require("@interlace/eslint-devkit");
7
+ exports.noUnlimitedResourceAllocation = (0, eslint_devkit_1.createRule)({
8
+ name: 'no-unlimited-resource-allocation',
9
+ meta: {
10
+ type: 'problem',
11
+ docs: {
12
+ description: 'Detects unlimited resource allocation that could cause DoS',
13
+ },
14
+ fixable: 'code',
15
+ hasSuggestions: true,
16
+ messages: {
17
+ unlimitedResourceAllocation: (0, eslint_devkit_2.formatLLMMessage)({
18
+ icon: eslint_devkit_2.MessageIcons.SECURITY,
19
+ issueName: 'Unlimited Resource Allocation',
20
+ cwe: 'CWE-770',
21
+ description: 'Resource allocation without limits',
22
+ severity: '{{severity}}',
23
+ fix: '{{safeAlternative}}',
24
+ documentationLink: 'https://cwe.mitre.org/data/definitions/770.html',
25
+ }),
26
+ unlimitedBufferAllocation: (0, eslint_devkit_2.formatLLMMessage)({
27
+ icon: eslint_devkit_2.MessageIcons.SECURITY,
28
+ issueName: 'Unlimited Buffer Allocation',
29
+ cwe: 'CWE-770',
30
+ description: 'Buffer allocated without size limits',
31
+ severity: 'HIGH',
32
+ fix: 'Set maximum buffer size limits',
33
+ documentationLink: 'https://nodejs.org/api/buffer.html',
34
+ }),
35
+ unlimitedFileOperations: (0, eslint_devkit_2.formatLLMMessage)({
36
+ icon: eslint_devkit_2.MessageIcons.SECURITY,
37
+ issueName: 'Unlimited File Operations',
38
+ cwe: 'CWE-770',
39
+ description: 'File operations without size limits',
40
+ severity: 'MEDIUM',
41
+ fix: 'Validate file size before operations',
42
+ documentationLink: 'https://nodejs.org/api/fs.html',
43
+ }),
44
+ unlimitedNetworkConnections: (0, eslint_devkit_2.formatLLMMessage)({
45
+ icon: eslint_devkit_2.MessageIcons.SECURITY,
46
+ issueName: 'Unlimited Network Connections',
47
+ cwe: 'CWE-770',
48
+ description: 'Network connections without limits',
49
+ severity: 'MEDIUM',
50
+ fix: 'Limit concurrent connections',
51
+ documentationLink: 'https://nodejs.org/api/http.html',
52
+ }),
53
+ unlimitedMemoryAllocation: (0, eslint_devkit_2.formatLLMMessage)({
54
+ icon: eslint_devkit_2.MessageIcons.SECURITY,
55
+ issueName: 'Unlimited Memory Allocation',
56
+ cwe: 'CWE-770',
57
+ description: 'Memory allocated without limits',
58
+ severity: 'MEDIUM',
59
+ fix: 'Set memory allocation limits',
60
+ documentationLink: 'https://nodejs.org/api/buffer.html',
61
+ }),
62
+ userControlledResourceSize: (0, eslint_devkit_2.formatLLMMessage)({
63
+ icon: eslint_devkit_2.MessageIcons.SECURITY,
64
+ issueName: 'User Controlled Resource Size',
65
+ cwe: 'CWE-770',
66
+ description: 'Resource size controlled by user input',
67
+ severity: 'HIGH',
68
+ fix: 'Validate and limit user-controlled resource sizes',
69
+ documentationLink: 'https://cwe.mitre.org/data/definitions/770.html',
70
+ }),
71
+ missingResourceLimits: (0, eslint_devkit_2.formatLLMMessage)({
72
+ icon: eslint_devkit_2.MessageIcons.SECURITY,
73
+ issueName: 'Missing Resource Limits',
74
+ cwe: 'CWE-770',
75
+ description: 'Resource allocation lacks proper limits',
76
+ severity: 'MEDIUM',
77
+ fix: 'Implement resource size validation',
78
+ documentationLink: 'https://cwe.mitre.org/data/definitions/770.html',
79
+ }),
80
+ resourceAllocationInLoop: (0, eslint_devkit_2.formatLLMMessage)({
81
+ icon: eslint_devkit_2.MessageIcons.SECURITY,
82
+ issueName: 'Resource Allocation in Loop',
83
+ cwe: 'CWE-770',
84
+ description: 'Resource allocation inside loop without limits',
85
+ severity: 'HIGH',
86
+ fix: 'Move resource allocation outside loop or add iteration limits',
87
+ documentationLink: 'https://cwe.mitre.org/data/definitions/770.html',
88
+ }),
89
+ implementResourceLimits: (0, eslint_devkit_2.formatLLMMessage)({
90
+ icon: eslint_devkit_2.MessageIcons.INFO,
91
+ issueName: 'Implement Resource Limits',
92
+ description: 'Add limits to resource allocation',
93
+ severity: 'LOW',
94
+ fix: 'const limitedSize = Math.min(userSize, MAX_SIZE);',
95
+ documentationLink: 'https://cwe.mitre.org/data/definitions/770.html',
96
+ }),
97
+ validateResourceSize: (0, eslint_devkit_2.formatLLMMessage)({
98
+ icon: eslint_devkit_2.MessageIcons.INFO,
99
+ issueName: 'Validate Resource Size',
100
+ description: 'Validate resource size before allocation',
101
+ severity: 'LOW',
102
+ fix: 'if (size > MAX_SIZE) throw new Error("Size too large");',
103
+ documentationLink: 'https://cwe.mitre.org/data/definitions/770.html',
104
+ }),
105
+ useResourcePools: (0, eslint_devkit_2.formatLLMMessage)({
106
+ icon: eslint_devkit_2.MessageIcons.INFO,
107
+ issueName: 'Use Resource Pools',
108
+ description: 'Use resource pools for better control',
109
+ severity: 'LOW',
110
+ fix: 'Implement connection pooling and resource reuse',
111
+ documentationLink: 'https://en.wikipedia.org/wiki/Object_pool_pattern',
112
+ }),
113
+ strategyResourceManagement: (0, eslint_devkit_2.formatLLMMessage)({
114
+ icon: eslint_devkit_2.MessageIcons.STRATEGY,
115
+ issueName: 'Resource Management Strategy',
116
+ description: 'Implement comprehensive resource management',
117
+ severity: 'LOW',
118
+ fix: 'Use resource pools, limits, and cleanup mechanisms',
119
+ documentationLink: 'https://cwe.mitre.org/data/definitions/770.html',
120
+ }),
121
+ strategyRateLimiting: (0, eslint_devkit_2.formatLLMMessage)({
122
+ icon: eslint_devkit_2.MessageIcons.STRATEGY,
123
+ issueName: 'Rate Limiting Strategy',
124
+ description: 'Implement rate limiting for resource allocation',
125
+ severity: 'LOW',
126
+ fix: 'Use rate limiters to prevent resource exhaustion',
127
+ documentationLink: 'https://en.wikipedia.org/wiki/Rate_limiting',
128
+ }),
129
+ strategyResourceCleanup: (0, eslint_devkit_2.formatLLMMessage)({
130
+ icon: eslint_devkit_2.MessageIcons.STRATEGY,
131
+ issueName: 'Resource Cleanup Strategy',
132
+ description: 'Ensure proper resource cleanup',
133
+ severity: 'LOW',
134
+ fix: 'Implement try-finally blocks and resource disposal',
135
+ documentationLink: 'https://en.wikipedia.org/wiki/Resource_management_(computing)',
136
+ })
137
+ },
138
+ schema: [
139
+ {
140
+ type: 'object',
141
+ properties: {
142
+ maxResourceSize: {
143
+ type: 'number',
144
+ minimum: 1024,
145
+ default: 1048576, // 1MB
146
+ },
147
+ userInputVariables: {
148
+ type: 'array',
149
+ items: { type: 'string' },
150
+ default: ['req', 'request', 'body', 'query', 'params', 'input', 'data'],
151
+ },
152
+ safeResourceFunctions: {
153
+ type: 'array',
154
+ items: { type: 'string' },
155
+ default: ['validateSize', 'checkLimits', 'limitResource', 'safeAlloc'],
156
+ },
157
+ requireResourceValidation: {
158
+ type: 'boolean',
159
+ default: true,
160
+ },
161
+ trustedSanitizers: {
162
+ type: 'array',
163
+ items: { type: 'string' },
164
+ default: [],
165
+ description: 'Additional function names to consider as resource validators',
166
+ },
167
+ trustedAnnotations: {
168
+ type: 'array',
169
+ items: { type: 'string' },
170
+ default: [],
171
+ description: 'Additional JSDoc annotations to consider as safe markers',
172
+ },
173
+ strictMode: {
174
+ type: 'boolean',
175
+ default: false,
176
+ description: 'Disable all false positive detection (strict mode)',
177
+ },
178
+ },
179
+ additionalProperties: false,
180
+ },
181
+ ],
182
+ },
183
+ defaultOptions: [
184
+ {
185
+ maxResourceSize: 1048576, // 1MB
186
+ userInputVariables: ['req', 'request', 'body', 'query', 'params', 'input', 'data'],
187
+ safeResourceFunctions: ['validateSize', 'checkLimits', 'limitResource', 'safeAlloc'],
188
+ requireResourceValidation: true,
189
+ trustedSanitizers: [],
190
+ trustedAnnotations: [],
191
+ strictMode: false,
192
+ },
193
+ ],
194
+ create(context) {
195
+ const options = context.options[0] || {};
196
+ const { maxResourceSize = 1048576, userInputVariables = ['req', 'request', 'body', 'query', 'params', 'input', 'data'], safeResourceFunctions = ['validateSize', 'checkLimits', 'limitResource', 'safeAlloc'], requireResourceValidation = true, trustedSanitizers = [], trustedAnnotations = [], strictMode = false, } = options;
197
+ const sourceCode = context.sourceCode || context.sourceCode;
198
+ const filename = context.filename || context.getFilename();
199
+ // Create safety checker for false positive detection
200
+ const safetyChecker = (0, eslint_devkit_3.createSafetyChecker)({
201
+ trustedSanitizers,
202
+ trustedAnnotations,
203
+ trustedOrmPatterns: [],
204
+ strictMode,
205
+ });
206
+ /**
207
+ * Check if an expression contains user input - using shared utility
208
+ */
209
+ const isUserInput = (expression) => (0, eslint_devkit_3.isUserInputExpression)(expression, sourceCode, userInputVariables);
210
+ /**
211
+ * Check if resource allocation has size validation
212
+ */
213
+ const hasSizeValidation = (node) => {
214
+ const args = node.arguments;
215
+ if (args.length === 0) {
216
+ return false;
217
+ }
218
+ // Check if size argument is a validated expression
219
+ const sizeArg = args[0];
220
+ const sizeText = sourceCode.getText(sizeArg);
221
+ // Look for validation patterns
222
+ return sizeText.includes('Math.min(') ||
223
+ sizeText.includes('Math.max(') ||
224
+ sizeText.includes('Math.clamp(') ||
225
+ safeResourceFunctions.some(func => sizeText.includes(func));
226
+ };
227
+ /**
228
+ * Estimate resource size from static analysis
229
+ */
230
+ const estimateResourceSize = (sizeExpression) => {
231
+ if (sizeExpression.type === 'Literal' && typeof sizeExpression.value === 'number') {
232
+ return sizeExpression.value;
233
+ }
234
+ // Handle binary expressions like 1024 * 1024 * 100
235
+ if (sizeExpression.type === 'BinaryExpression') {
236
+ const left = estimateResourceSize(sizeExpression.left);
237
+ const right = estimateResourceSize(sizeExpression.right);
238
+ if (left !== null && right !== null) {
239
+ switch (sizeExpression.operator) {
240
+ case '*':
241
+ return left * right;
242
+ case '+':
243
+ return left + right;
244
+ case '-':
245
+ return left - right;
246
+ case '/':
247
+ return right !== 0 ? left / right : null;
248
+ default:
249
+ return null;
250
+ }
251
+ }
252
+ }
253
+ return null;
254
+ };
255
+ return {
256
+ // Check Buffer allocation
257
+ CallExpression(node) {
258
+ const callee = node.callee;
259
+ const calleeText = sourceCode.getText(callee);
260
+ // Check for Buffer.alloc(), Buffer.allocUnsafe() or new Buffer()
261
+ const isBufferAlloc = callee.type === 'MemberExpression' &&
262
+ callee.object.type === 'Identifier' &&
263
+ callee.object.name === 'Buffer' &&
264
+ callee.property.type === 'Identifier' &&
265
+ (callee.property.name === 'alloc' || callee.property.name === 'allocUnsafe');
266
+ const isNewBuffer = callee.type === 'NewExpression' &&
267
+ callee.callee.type === 'Identifier' &&
268
+ callee.callee.name === 'Buffer';
269
+ if (isBufferAlloc || isNewBuffer) {
270
+ const args = node.arguments;
271
+ if (args.length > 0) {
272
+ const sizeArg = args[0];
273
+ // Check if size comes from user input (but skip if validated)
274
+ if (sizeArg.type !== 'SpreadElement' && isUserInput(sizeArg) && !hasSizeValidation(node)) {
275
+ /* c8 ignore start -- safetyChecker requires JSDoc annotations not testable via RuleTester */
276
+ if (safetyChecker.isSafe(node, context)) {
277
+ return;
278
+ }
279
+ /* c8 ignore stop */
280
+ context.report({
281
+ node: sizeArg,
282
+ messageId: 'userControlledResourceSize',
283
+ data: {
284
+ filePath: filename,
285
+ line: String(node.loc?.start.line ?? 0),
286
+ },
287
+ });
288
+ return;
289
+ }
290
+ // Check if size exceeds limits
291
+ const estimatedSize = sizeArg.type === 'SpreadElement' ? null : estimateResourceSize(sizeArg);
292
+ if (estimatedSize && estimatedSize > maxResourceSize) {
293
+ /* c8 ignore start -- safetyChecker requires JSDoc annotations not testable via RuleTester */
294
+ if (safetyChecker.isSafe(node, context)) {
295
+ return;
296
+ }
297
+ /* c8 ignore stop */
298
+ context.report({
299
+ node: sizeArg,
300
+ messageId: 'unlimitedBufferAllocation',
301
+ data: {
302
+ filePath: filename,
303
+ line: String(node.loc?.start.line ?? 0),
304
+ },
305
+ });
306
+ return;
307
+ }
308
+ // Check if no size validation present (only for non-literal sizes from user input)
309
+ const isLiteralSize = sizeArg.type === 'Literal' && typeof sizeArg.value === 'number';
310
+ const comesFromUserInput = sizeArg.type !== 'SpreadElement' && isUserInput(sizeArg);
311
+ if (requireResourceValidation && !hasSizeValidation(node) && !isLiteralSize && comesFromUserInput) {
312
+ /* c8 ignore start -- safetyChecker requires JSDoc annotations not testable via RuleTester */
313
+ if (safetyChecker.isSafe(node, context)) {
314
+ return;
315
+ }
316
+ /* c8 ignore stop */
317
+ context.report({
318
+ node,
319
+ messageId: 'missingResourceLimits',
320
+ data: {
321
+ filePath: filename,
322
+ line: String(node.loc?.start.line ?? 0),
323
+ },
324
+ });
325
+ }
326
+ }
327
+ }
328
+ // Check for multer configuration without limits
329
+ if (callee.type === 'Identifier' && callee.name === 'multer') {
330
+ const args = node.arguments;
331
+ if (args.length > 0 && args[0].type === 'ObjectExpression') {
332
+ const props = args[0].properties;
333
+ // Check for valid limits definition
334
+ const hasValidLimits = props.some((prop) => {
335
+ if (prop.type !== 'Property' || prop.key.type !== 'Identifier') {
336
+ return false;
337
+ }
338
+ // Direct fileSize (not standard but maybe used?)
339
+ if (prop.key.name === 'fileSize')
340
+ return true;
341
+ // Limits object
342
+ if (prop.key.name === 'limits' && prop.value.type === 'ObjectExpression') {
343
+ return prop.value.properties.some((limitProp) => limitProp.type === 'Property' &&
344
+ limitProp.key.type === 'Identifier' &&
345
+ limitProp.key.name === 'fileSize');
346
+ }
347
+ return false;
348
+ });
349
+ if (!hasValidLimits) {
350
+ /* c8 ignore start -- safetyChecker requires JSDoc annotations not testable via RuleTester */
351
+ if (safetyChecker.isSafe(node, context)) {
352
+ return;
353
+ }
354
+ /* c8 ignore stop */
355
+ context.report({
356
+ node,
357
+ messageId: 'unlimitedFileOperations',
358
+ data: {
359
+ filePath: filename,
360
+ line: String(node.loc?.start.line ?? 0),
361
+ },
362
+ });
363
+ }
364
+ }
365
+ return;
366
+ }
367
+ // Check for fs operations
368
+ if (callee.type === 'MemberExpression' &&
369
+ callee.object.type === 'Identifier' &&
370
+ callee.object.name === 'fs' &&
371
+ callee.property.type === 'Identifier' &&
372
+ ['readFile', 'writeFile', 'readFileSync', 'writeFileSync'].includes(callee.property.name)) {
373
+ const args = node.arguments;
374
+ if (args.length > 0) {
375
+ // Check if file path comes from user input (potential for large files)
376
+ const pathArg = args[0];
377
+ // SAFE: Static path construction with path.join(__dirname, ...literals)
378
+ // This is a common pattern that doesn't involve user input
379
+ if (pathArg.type === 'CallExpression' &&
380
+ pathArg.callee.type === 'MemberExpression' &&
381
+ pathArg.callee.object.type === 'Identifier' &&
382
+ pathArg.callee.object.name === 'path' &&
383
+ pathArg.callee.property.type === 'Identifier' &&
384
+ (pathArg.callee.property.name === 'join' || pathArg.callee.property.name === 'resolve')) {
385
+ // Check if first arg is __dirname and all subsequent args are literals
386
+ const pathArgs = pathArg.arguments;
387
+ if (pathArgs.length > 0 &&
388
+ pathArgs[0].type === 'Identifier' &&
389
+ pathArgs[0].name === '__dirname' &&
390
+ pathArgs.slice(1).every(arg => arg.type === 'Literal')) {
391
+ // Safe: path.join(__dirname, 'static', 'path')
392
+ return;
393
+ }
394
+ }
395
+ if (pathArg.type !== 'SpreadElement' && isUserInput(pathArg)) {
396
+ /* c8 ignore start -- safetyChecker requires JSDoc annotations not testable via RuleTester */
397
+ if (safetyChecker.isSafe(node, context)) {
398
+ return;
399
+ }
400
+ /* c8 ignore stop */
401
+ context.report({
402
+ node: pathArg,
403
+ messageId: 'unlimitedFileOperations',
404
+ data: {
405
+ filePath: filename,
406
+ line: String(node.loc?.start.line ?? 0),
407
+ },
408
+ });
409
+ }
410
+ }
411
+ }
412
+ // Check for Array constructor with user input
413
+ if (callee.type === 'Identifier' && callee.name === 'Array') {
414
+ const args = node.arguments;
415
+ if (args.length === 1) {
416
+ const sizeArg = args[0];
417
+ if (sizeArg.type !== 'SpreadElement' && isUserInput(sizeArg)) {
418
+ /* c8 ignore start -- safetyChecker requires JSDoc annotations not testable via RuleTester */
419
+ if (safetyChecker.isSafe(node, context)) {
420
+ return;
421
+ }
422
+ /* c8 ignore stop */
423
+ context.report({
424
+ node: sizeArg,
425
+ messageId: 'unlimitedMemoryAllocation',
426
+ data: {
427
+ filePath: filename,
428
+ line: String(node.loc?.start.line ?? 0),
429
+ },
430
+ });
431
+ }
432
+ }
433
+ }
434
+ // Check for complex resource exhaustion patterns
435
+ /* c8 ignore start -- defensive detectors for rare patterns */
436
+ // ZIP bomb detection - unlimited decompression
437
+ if (calleeText.includes('unzipper') || calleeText.includes('Extract')) {
438
+ // Check for unlimited ZIP extraction
439
+ context.report({
440
+ node,
441
+ messageId: 'unlimitedFileOperations',
442
+ data: {
443
+ filePath: filename,
444
+ line: String(node.loc?.start.line ?? 0),
445
+ },
446
+ });
447
+ }
448
+ // XML expansion attack detection
449
+ if (calleeText.includes('xml2js') || calleeText.includes('parseString')) {
450
+ context.report({
451
+ node,
452
+ messageId: 'unlimitedMemoryAllocation',
453
+ data: {
454
+ filePath: filename,
455
+ line: String(node.loc?.start.line ?? 0),
456
+ },
457
+ });
458
+ }
459
+ // Check for cache with unlimited growth
460
+ if (calleeText.includes('set') && sourceCode.getText(node).includes('Buffer.alloc')) {
461
+ // Detect cache patterns that allocate buffers without limits
462
+ const args = node.arguments;
463
+ if (args.length >= 2) {
464
+ const valueArg = args[1];
465
+ const valueText = sourceCode.getText(valueArg);
466
+ if (valueText.includes('Buffer.alloc') && valueText.includes('length')) {
467
+ context.report({
468
+ node,
469
+ messageId: 'unlimitedMemoryAllocation',
470
+ data: {
471
+ filePath: filename,
472
+ line: String(node.loc?.start.line ?? 0),
473
+ },
474
+ });
475
+ }
476
+ }
477
+ }
478
+ // Check for recursive data structure processing
479
+ if (calleeText.includes('map') || calleeText.includes('forEach')) {
480
+ const args = node.arguments;
481
+ if (args.length > 0) {
482
+ const callbackArg = args[0];
483
+ const callbackText = sourceCode.getText(callbackArg);
484
+ // Detect patterns that create arrays from nested object properties
485
+ if (callbackText.includes('Object.keys') && callbackText.includes('map')) {
486
+ context.report({
487
+ node,
488
+ messageId: 'unlimitedMemoryAllocation',
489
+ data: {
490
+ filePath: filename,
491
+ line: String(node.loc?.start.line ?? 0),
492
+ },
493
+ });
494
+ }
495
+ }
496
+ }
497
+ /* c8 ignore stop */
498
+ // Check for resource allocation inside loops
499
+ if ((0, eslint_devkit_3.isInsideLoop)(node)) {
500
+ const calleeText = sourceCode.getText(callee);
501
+ // Check if this allocates resources
502
+ if (calleeText.includes('alloc') ||
503
+ calleeText.includes('Array') ||
504
+ calleeText.includes('Buffer') ||
505
+ calleeText.includes('readFile') ||
506
+ calleeText.includes('writeFile')) {
507
+ /* c8 ignore start -- safetyChecker requires JSDoc annotations not testable via RuleTester */
508
+ if (safetyChecker.isSafe(node, context)) {
509
+ return;
510
+ }
511
+ /* c8 ignore stop */
512
+ // Skip if this is an assignment to an array element (pre-allocated pattern)
513
+ const parent = node.parent;
514
+ if (parent && parent.type === 'AssignmentExpression' &&
515
+ parent.left.type === 'MemberExpression' &&
516
+ parent.left.object.type === 'Identifier') {
517
+ // This is assigning to an array element, likely pre-allocated
518
+ return;
519
+ }
520
+ // Report resourceAllocationInLoop - this can be in addition to user input errors
521
+ context.report({
522
+ node,
523
+ messageId: 'resourceAllocationInLoop',
524
+ data: {
525
+ filePath: filename,
526
+ line: String(node.loc?.start.line ?? 0),
527
+ },
528
+ });
529
+ }
530
+ }
531
+ },
532
+ // Check new expressions for resource allocation
533
+ NewExpression(node) {
534
+ const callee = node.callee;
535
+ // Check for new Buffer() with user input
536
+ if (callee.type === 'Identifier' && callee.name === 'Buffer') {
537
+ const args = node.arguments;
538
+ if (args.length > 0) {
539
+ const sizeArg = args[0];
540
+ // Check if size comes from user input (but skip if validated)
541
+ if (sizeArg.type !== 'SpreadElement' && isUserInput(sizeArg) && !hasSizeValidation(node)) {
542
+ /* c8 ignore start -- safetyChecker requires JSDoc annotations not testable via RuleTester */
543
+ if (safetyChecker.isSafe(node, context)) {
544
+ return;
545
+ }
546
+ /* c8 ignore stop */
547
+ context.report({
548
+ node: sizeArg,
549
+ messageId: 'userControlledResourceSize',
550
+ data: {
551
+ filePath: filename,
552
+ line: String(node.loc?.start.line ?? 0),
553
+ },
554
+ });
555
+ return;
556
+ }
557
+ // Check if size exceeds limits
558
+ const estimatedSize = sizeArg.type === 'SpreadElement' ? null : estimateResourceSize(sizeArg);
559
+ if (estimatedSize && estimatedSize > maxResourceSize) {
560
+ /* c8 ignore start -- safetyChecker requires JSDoc annotations not testable via RuleTester */
561
+ if (safetyChecker.isSafe(node, context)) {
562
+ return;
563
+ }
564
+ /* c8 ignore stop */
565
+ context.report({
566
+ node: sizeArg,
567
+ messageId: 'unlimitedBufferAllocation',
568
+ data: {
569
+ filePath: filename,
570
+ line: String(node.loc?.start.line ?? 0),
571
+ },
572
+ });
573
+ return;
574
+ }
575
+ // Check if no size validation present (only for non-literal sizes from user input)
576
+ const isLiteralSize = sizeArg.type === 'Literal' && typeof sizeArg.value === 'number';
577
+ const comesFromUserInput = sizeArg.type !== 'SpreadElement' && isUserInput(sizeArg);
578
+ if (requireResourceValidation && !hasSizeValidation(node) && !isLiteralSize && comesFromUserInput) {
579
+ /* c8 ignore start -- safetyChecker requires JSDoc annotations not testable via RuleTester */
580
+ if (safetyChecker.isSafe(node, context)) {
581
+ return;
582
+ }
583
+ /* c8 ignore stop */
584
+ context.report({
585
+ node,
586
+ messageId: 'missingResourceLimits',
587
+ data: {
588
+ filePath: filename,
589
+ line: String(node.loc?.start.line ?? 0),
590
+ },
591
+ });
592
+ }
593
+ }
594
+ }
595
+ // Check for new Array() with user input
596
+ if (callee.type === 'Identifier' && callee.name === 'Array') {
597
+ const args = node.arguments;
598
+ if (args.length === 1) {
599
+ const sizeArg = args[0];
600
+ if (sizeArg.type !== 'SpreadElement' && isUserInput(sizeArg)) {
601
+ /* c8 ignore start -- safetyChecker requires JSDoc annotations not testable via RuleTester */
602
+ if (safetyChecker.isSafe(node, context)) {
603
+ return;
604
+ }
605
+ /* c8 ignore stop */
606
+ context.report({
607
+ node: sizeArg,
608
+ messageId: 'unlimitedMemoryAllocation',
609
+ data: {
610
+ filePath: filename,
611
+ line: String(node.loc?.start.line ?? 0),
612
+ },
613
+ });
614
+ }
615
+ }
616
+ }
617
+ // Check for resource allocation inside loops
618
+ if ((0, eslint_devkit_3.isInsideLoop)(node)) {
619
+ const calleeText = sourceCode.getText(callee);
620
+ // Check if this allocates resources
621
+ if (calleeText.includes('Buffer') ||
622
+ calleeText.includes('Array') ||
623
+ calleeText.includes('Map') ||
624
+ calleeText.includes('Set')) {
625
+ /* c8 ignore start -- safetyChecker requires JSDoc annotations not testable via RuleTester */
626
+ if (safetyChecker.isSafe(node, context)) {
627
+ return;
628
+ }
629
+ /* c8 ignore stop */
630
+ context.report({
631
+ node,
632
+ messageId: 'resourceAllocationInLoop',
633
+ data: {
634
+ filePath: filename,
635
+ line: String(node.loc?.start.line ?? 0),
636
+ },
637
+ });
638
+ }
639
+ }
640
+ }
641
+ };
642
+ },
643
+ });
@@ -0,0 +1,10 @@
1
+ import { type SecurityRuleOptions } from '@interlace/eslint-devkit';
2
+ export interface Options extends SecurityRuleOptions {
3
+ /** Dangerous deserialization functions to detect */
4
+ dangerousFunctions?: string[];
5
+ /** Safe deserialization libraries */
6
+ safeLibraries?: string[];
7
+ /** Functions that validate input before deserialization */
8
+ validationFunctions?: string[];
9
+ }
10
+ export declare const noUnsafeDeserialization: ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener>;