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
@@ -1,488 +0,0 @@
1
- /**
2
- * ESLint Rule: database-injection
3
- * Comprehensive SQL/NoSQL injection vulnerability detection
4
- * Inspired by SonarQube RSPEC-3649
5
- *
6
- * @see https://rules.sonarsource.com/javascript/RSPEC-3649/
7
- */
8
- import type { TSESLint, TSESTree } from '@interlace/eslint-devkit';
9
- import { formatLLMMessage, MessageIcons } from '@interlace/eslint-devkit';
10
- import { createRule } from '@interlace/eslint-devkit';
11
-
12
- type MessageIds =
13
- | 'databaseInjection'
14
- | 'usePrisma'
15
- | 'useTypeORM'
16
- | 'useParameterized'
17
- | 'useMongoSanitize'
18
- | 'strategyParameterize'
19
- | 'strategyORM'
20
- | 'strategySanitize'
21
- | 'strategyAuto';
22
-
23
- export interface Options {
24
- /** Detect NoSQL injection patterns. Default: true */
25
- detectNoSQL?: boolean;
26
-
27
- /** Detect ORM-specific vulnerabilities. Default: true */
28
- detectORMs?: boolean;
29
-
30
- /** Trusted data sources that bypass detection */
31
- trustedSources?: string[];
32
-
33
- /** Show framework-specific recommendations. Default: true */
34
- frameworkHints?: boolean;
35
-
36
- /** Strategy for fixing injection: 'parameterize', 'orm', 'sanitize', 'auto' */
37
- strategy?: 'parameterize' | 'orm' | 'sanitize' | 'auto';
38
- }
39
-
40
- type RuleOptions = [Options?];
41
-
42
- interface VulnerabilityDetails {
43
- type: 'SQL' | 'NoSQL';
44
- pattern: string;
45
- severity: 'critical' | 'high' | 'medium';
46
- exploitability: string;
47
- cwe: string;
48
- owasp: string;
49
- }
50
-
51
- export const databaseInjection = createRule<RuleOptions, MessageIds>({
52
- name: 'database-injection',
53
- meta: {
54
- type: 'problem',
55
- docs: {
56
- description: 'Detects SQL and NoSQL injection vulnerabilities with framework-specific fixes',
57
- },
58
- messages: (() => {
59
- const databaseInjection = formatLLMMessage({
60
- icon: MessageIcons.SECURITY,
61
- issueName: 'SQL Injection',
62
- cwe: 'CWE-89',
63
- description: 'SQL Injection detected',
64
- severity: 'CRITICAL',
65
- fix: 'Use parameterized query: db.query("SELECT * FROM users WHERE id = ?", [userId])',
66
- documentationLink: 'https://owasp.org/www-community/attacks/SQL_Injection',
67
- });
68
- const usePrisma = formatLLMMessage({
69
- icon: MessageIcons.INFO,
70
- issueName: 'Use Prisma',
71
- description: 'Use Prisma ORM',
72
- severity: 'LOW',
73
- fix: 'await prisma.user.findMany({ where: { id } })',
74
- documentationLink: 'https://www.prisma.io/docs',
75
- });
76
- const useTypeORM = formatLLMMessage({
77
- icon: MessageIcons.INFO,
78
- issueName: 'Use TypeORM',
79
- description: 'Use TypeORM with QueryBuilder',
80
- severity: 'LOW',
81
- fix: 'userRepository.createQueryBuilder().where("id = :id", { id })',
82
- documentationLink: 'https://typeorm.io/',
83
- });
84
- const useParameterized = formatLLMMessage({
85
- icon: MessageIcons.INFO,
86
- issueName: 'Use Parameterized',
87
- description: 'Use parameterized query',
88
- severity: 'LOW',
89
- fix: 'db.query("SELECT * FROM users WHERE id = ?", [userId])',
90
- documentationLink: 'https://owasp.org/www-community/attacks/SQL_Injection',
91
- });
92
- const useMongoSanitize = formatLLMMessage({
93
- icon: MessageIcons.INFO,
94
- issueName: 'Use mongo-sanitize',
95
- description: 'Use mongo-sanitize for MongoDB',
96
- severity: 'LOW',
97
- fix: 'sanitize(req.body)',
98
- documentationLink: 'https://github.com/vkarpov15/mongo-sanitize',
99
- });
100
- const strategyParameterize = formatLLMMessage({
101
- icon: MessageIcons.STRATEGY,
102
- issueName: 'Parameterize Strategy',
103
- description: 'Use parameterized queries',
104
- severity: 'LOW',
105
- fix: 'Use ? or :name placeholders for user input',
106
- documentationLink: 'https://owasp.org/www-community/attacks/SQL_Injection',
107
- });
108
- const strategyORM = formatLLMMessage({
109
- icon: MessageIcons.STRATEGY,
110
- issueName: 'ORM Strategy',
111
- description: 'Migrate to ORM for automatic protection',
112
- severity: 'LOW',
113
- fix: 'Use Prisma, TypeORM, or Sequelize',
114
- documentationLink: 'https://www.prisma.io/docs/concepts/overview/why-prisma',
115
- });
116
- const strategySanitize = formatLLMMessage({
117
- icon: MessageIcons.STRATEGY,
118
- issueName: 'Sanitize Strategy',
119
- description: 'Add input sanitization',
120
- severity: 'LOW',
121
- fix: 'Sanitize input as last resort',
122
- documentationLink: 'https://owasp.org/www-community/attacks/SQL_Injection',
123
- });
124
- const strategyAuto = formatLLMMessage({
125
- icon: MessageIcons.STRATEGY,
126
- issueName: 'Auto Strategy',
127
- description: 'Apply context-aware injection prevention',
128
- severity: 'LOW',
129
- fix: 'Use context-appropriate protection',
130
- documentationLink: 'https://owasp.org/www-community/attacks/SQL_Injection',
131
- });
132
-
133
- return {
134
- databaseInjection,
135
- usePrisma,
136
- useTypeORM,
137
- useParameterized,
138
- useMongoSanitize,
139
- strategyParameterize,
140
- strategyORM,
141
- strategySanitize,
142
- strategyAuto,
143
- };
144
- })(),
145
- schema: [
146
- {
147
- type: 'object',
148
- properties: {
149
- detectNoSQL: {
150
- type: 'boolean',
151
- default: true,
152
- },
153
- detectORMs: {
154
- type: 'boolean',
155
- default: true,
156
- description: 'Detect unsafe ORM usage',
157
- },
158
- trustedSources: {
159
- type: 'array',
160
- items: { type: 'string' },
161
- default: [],
162
- },
163
- frameworkHints: {
164
- type: 'boolean',
165
- default: true,
166
- description: 'Provide framework-specific suggestions',
167
- },
168
- strategy: {
169
- type: 'string',
170
- enum: ['parameterize', 'orm', 'sanitize', 'auto'],
171
- default: 'auto',
172
- description: 'Strategy for fixing injection (auto = smart detection)'
173
- },
174
- },
175
- additionalProperties: false,
176
- },
177
- ],
178
- },
179
- defaultOptions: [
180
- {
181
- detectNoSQL: true,
182
- detectORMs: true,
183
- trustedSources: [],
184
- frameworkHints: true,
185
- strategy: 'auto',
186
- },
187
- ],
188
- create(context: TSESLint.RuleContext<MessageIds, RuleOptions>) {
189
- const options = context.options[0] || {};
190
- const {
191
- detectNoSQL = true,
192
- strategy = 'auto'
193
- }: Options = options || {};
194
-
195
- const sourceCode = context.sourceCode || context.sourceCode;
196
-
197
- /**
198
- * Select message ID based on strategy
199
- * @todo Consider using this for suggestions in future versions
200
- */
201
-
202
- const selectStrategyMessage = (): MessageIds => {
203
- switch (strategy) {
204
- case 'parameterize':
205
- return 'strategyParameterize';
206
- case 'orm':
207
- return 'strategyORM';
208
- case 'sanitize':
209
- return 'strategySanitize';
210
- case 'auto':
211
- default:
212
- // Auto mode: prefer parameterized queries
213
- return 'useParameterized';
214
- }
215
- };
216
- const filename = context.filename || context.getFilename();
217
-
218
- /**
219
- * SQL keywords for detection
220
- */
221
- const SQL_KEYWORDS = [
222
- 'SELECT', 'INSERT', 'UPDATE', 'DELETE', 'DROP', 'CREATE', 'ALTER',
223
- 'EXEC', 'EXECUTE', 'TRUNCATE', 'GRANT', 'REVOKE', 'WHERE', 'FROM', 'JOIN'
224
- ];
225
-
226
- /**
227
- * NoSQL patterns
228
- */
229
- const NOSQL_PATTERNS = [
230
- 'find', 'findOne', 'findById', 'updateOne', 'updateMany', 'deleteOne',
231
- 'deleteMany', 'aggregate', '$where', '$regex'
232
- ];
233
-
234
- /**
235
- * NoSQL query patterns in template literals (e.g., `this.name === "${userName}"`)
236
- */
237
- const NOSQL_QUERY_PATTERNS = [
238
- /this\.\w+\s*===?\s*["']/i, // this.name === "value"
239
- /this\.\w+\s*!==?\s*["']/i, // this.name !== "value"
240
- /\$\w+\s*===?\s*["']/i, // $where === "value"
241
- ];
242
-
243
- /**
244
- * Check if text contains SQL keywords
245
- */
246
- function containsSQLKeywords(text: string): boolean {
247
- const upperText = text.toUpperCase();
248
- return SQL_KEYWORDS.some(keyword => upperText.includes(keyword));
249
- }
250
-
251
- /**
252
- * Check if code is using NoSQL operations
253
- */
254
- function isNoSQLOperation(node: TSESTree.Node): boolean {
255
- const text = sourceCode.getText(node);
256
- return NOSQL_PATTERNS.some(pattern => text.includes(pattern));
257
- }
258
-
259
- /**
260
- * Check if expression is tainted (contains user input)
261
- */
262
- function isTainted(node: TSESTree.Node): {
263
- tainted: boolean;
264
- source?: string;
265
- confidence: 'high' | 'medium' | 'low';
266
- } {
267
- const text = sourceCode.getText(node);
268
- const { trustedSources = [] } = options;
269
-
270
- // High confidence taint sources
271
- const highConfidenceSources = [
272
- 'req.body', 'req.query', 'req.params', 'request.body',
273
- 'params.', 'query.', 'body.', 'input.', 'userInput'
274
- ];
275
-
276
- // Medium confidence taint sources
277
- const mediumConfidenceSources = [
278
- 'props.', 'state.', 'context.', 'event.', 'data.'
279
- ];
280
-
281
- for (const source of highConfidenceSources) {
282
- if (text.includes(source)) {
283
- return { tainted: true, source, confidence: 'high' };
284
- }
285
- }
286
-
287
- for (const source of mediumConfidenceSources) {
288
- if (text.includes(source)) {
289
- return { tainted: true, source, confidence: 'medium' };
290
- }
291
- }
292
-
293
- // Check if this source is explicitly trusted (only for low-confidence sources)
294
- for (const trusted of trustedSources) {
295
- if (text.includes(trusted)) {
296
- return { tainted: false, confidence: 'low' };
297
- }
298
- }
299
-
300
- // Check if it's a variable (low confidence)
301
- if (node.type === 'Identifier' && !text.match(/^[A-Z_]+$/)) {
302
- return { tainted: true, source: 'variable', confidence: 'low' };
303
- }
304
-
305
- return { tainted: false, confidence: 'low' };
306
- }
307
-
308
- /**
309
- * Analyze vulnerability and provide detailed report
310
- */
311
- function analyzeVulnerability(
312
- node: TSESTree.Node,
313
- vulnType: 'SQL' | 'NoSQL'
314
- ): VulnerabilityDetails {
315
- const taintInfo = isTainted(node);
316
-
317
- return {
318
- type: vulnType,
319
- pattern: taintInfo.tainted
320
- ? `User input (${taintInfo.source}) in query`
321
- : 'Dynamic query construction',
322
- severity: taintInfo.confidence === 'high' ? 'critical' : taintInfo.confidence === 'medium' ? 'high' : 'medium',
323
- exploitability: taintInfo.confidence === 'high'
324
- ? 'Easily exploitable via API parameters'
325
- : 'Exploitable with access to input sources',
326
- cwe: vulnType === 'SQL' ? 'CWE-89' : 'CWE-943',
327
- owasp: 'A03:2021 - Injection',
328
- };
329
- }
330
-
331
- /**
332
- * Report additional strategy-specific suggestions
333
- */
334
- function reportStrategySuggestions(node: TSESTree.Node) {
335
- const strategyMessageId = selectStrategyMessage();
336
- if (strategyMessageId !== 'useParameterized') { // Don't duplicate the main message
337
- context.report({
338
- node,
339
- messageId: strategyMessageId,
340
- });
341
- }
342
- }
343
-
344
- /**
345
- * Check template literal for SQL or NoSQL injection
346
- */
347
- function checkTemplateLiteral(node: TSESTree.TemplateLiteral) {
348
- const text = sourceCode.getText(node);
349
-
350
- // Check for SQL injection
351
- if (containsSQLKeywords(text) && node.expressions.length > 0) {
352
- // Check if any expression is tainted
353
- const taintedExprs = node.expressions.filter((expr: TSESTree.Expression | TSESTree.SpreadElement) => isTainted(expr).tainted);
354
- if (taintedExprs.length > 0) {
355
- const vulnDetails = analyzeVulnerability(node, 'SQL');
356
- const data = {
357
- type: vulnDetails.type,
358
- severity: vulnDetails.severity.toUpperCase(),
359
- filePath: filename,
360
- line: String(node.loc?.start.line ?? 0),
361
- cwe: vulnDetails.cwe,
362
- cweCode: vulnDetails.cwe.replace('CWE-', ''),
363
- currentExample: `db.query(\`SELECT * FROM users WHERE id = ${'${userId}'}\`)`,
364
- fixExample: `Use parameterized: db.query("SELECT * FROM users WHERE id = ?", [userId])`,
365
- docLink: 'https://owasp.org/www-community/attacks/SQL_Injection',
366
- };
367
- context.report({
368
- node,
369
- messageId: 'databaseInjection',
370
- data,
371
- });
372
- reportStrategySuggestions(node);
373
- return;
374
- }
375
- }
376
-
377
- // Check for NoSQL injection patterns in template literals
378
- if (detectNoSQL && node.expressions.length > 0) {
379
- const hasNoSQLPattern = NOSQL_QUERY_PATTERNS.some(pattern => pattern.test(text));
380
- if (hasNoSQLPattern) {
381
- // Check if any expression is tainted
382
- const taintedExprs = node.expressions.filter((expr: TSESTree.Expression | TSESTree.SpreadElement) => isTainted(expr).tainted);
383
- if (taintedExprs.length > 0) {
384
- const vulnDetails = analyzeVulnerability(node, 'NoSQL');
385
- const data = {
386
- type: vulnDetails.type,
387
- severity: vulnDetails.severity.toUpperCase(),
388
- filePath: filename,
389
- line: String(node.loc?.start.line ?? 0),
390
- cwe: vulnDetails.cwe,
391
- cweCode: vulnDetails.cwe.replace('CWE-', ''),
392
- currentExample: `const query = \`this.name === "${'${userName}'}"\``,
393
- fixExample: `Sanitize input: const query = \`this.name === "\${mongoSanitize(userName)}"\``,
394
- docLink: 'https://owasp.org/www-community/attacks/NoSQL_Injection',
395
- };
396
- context.report({
397
- node,
398
- messageId: 'databaseInjection',
399
- data,
400
- });
401
- reportStrategySuggestions(node);
402
- return;
403
- }
404
- }
405
- }
406
- }
407
-
408
- /**
409
- * Check NoSQL operations
410
- */
411
- function checkNoSQLOperation(node: TSESTree.CallExpression) {
412
- if (!detectNoSQL) return;
413
- if (!isNoSQLOperation(node)) return;
414
-
415
- // Check if arguments contain user input
416
- const taintedArgs = node.arguments.filter((arg: TSESTree.CallExpressionArgument) => isTainted(arg).tainted);
417
- if (taintedArgs.length === 0) return;
418
-
419
- const vulnDetails = analyzeVulnerability(node, 'NoSQL');
420
- const data = {
421
- type: vulnDetails.type,
422
- severity: vulnDetails.severity.toUpperCase(),
423
- filePath: filename,
424
- line: String(node.loc?.start.line ?? 0),
425
- cwe: vulnDetails.cwe,
426
- cweCode: vulnDetails.cwe.replace('CWE-', ''),
427
- currentExample: `User.findOne({ email: req.body.email })`,
428
- fixExample: `Sanitize input: User.findOne({ email: mongoSanitize(req.body.email) })`,
429
- docLink: 'https://owasp.org/www-community/attacks/NoSQL_Injection',
430
- };
431
- context.report({
432
- node,
433
- messageId: 'databaseInjection',
434
- data,
435
- });
436
- reportStrategySuggestions(node);
437
- }
438
-
439
- /**
440
- * Check binary expression (string concatenation) for SQL injection
441
- */
442
- function checkBinaryExpression(node: TSESTree.BinaryExpression) {
443
- // Only check string concatenation with + operator
444
- if (node.operator !== '+') return;
445
-
446
- // Get the full text of the binary expression
447
- const text = sourceCode.getText(node);
448
-
449
- // Check if it contains SQL keywords
450
- if (!containsSQLKeywords(text)) return;
451
-
452
- // Check if any part of the expression is tainted
453
- const taintInfo = isTainted(node);
454
- if (!taintInfo.tainted) {
455
- // Also check left and right sides individually
456
- const leftTainted = isTainted(node.left).tainted;
457
- const rightTainted = isTainted(node.right).tainted;
458
- if (!leftTainted && !rightTainted) return;
459
- }
460
-
461
- const vulnDetails = analyzeVulnerability(node, 'SQL');
462
- const data = {
463
- type: vulnDetails.type,
464
- severity: vulnDetails.severity.toUpperCase(),
465
- filePath: filename,
466
- line: String(node.loc?.start.line ?? 0),
467
- cwe: vulnDetails.cwe,
468
- cweCode: vulnDetails.cwe.replace('CWE-', ''),
469
- currentExample: `const query = "SELECT * FROM users WHERE name = '" + userName + "'"`,
470
- fixExample: `Use parameterized: db.query("SELECT * FROM users WHERE name = ?", [userName])`,
471
- docLink: 'https://owasp.org/www-community/attacks/SQL_Injection',
472
- };
473
- context.report({
474
- node,
475
- messageId: 'databaseInjection',
476
- data,
477
- });
478
- reportStrategySuggestions(node);
479
- }
480
-
481
- return {
482
- TemplateLiteral: checkTemplateLiteral,
483
- CallExpression: checkNoSQLOperation,
484
- BinaryExpression: checkBinaryExpression,
485
- };
486
- },
487
- });
488
-
@@ -1,207 +0,0 @@
1
- /**
2
- * Comprehensive tests for detect-child-process rule
3
- * Security: CWE-78 (Command Injection)
4
- */
5
- import { RuleTester } from '@typescript-eslint/rule-tester';
6
- import { describe, it, afterAll } from 'vitest';
7
- import parser from '@typescript-eslint/parser';
8
- import { detectChildProcess } from './index';
9
-
10
- // Configure RuleTester for Vitest
11
- RuleTester.afterAll = afterAll;
12
- RuleTester.it = it;
13
- RuleTester.itOnly = it.only;
14
- RuleTester.describe = describe;
15
-
16
- // Use Flat Config format (ESLint 9+)
17
- const ruleTester = new RuleTester({
18
- languageOptions: {
19
- parser,
20
- ecmaVersion: 2022,
21
- sourceType: 'module',
22
- },
23
- });
24
-
25
- describe('detect-child-process', () => {
26
- describe('Valid Code', () => {
27
- ruleTester.run('valid - safe child process usage', detectChildProcess, {
28
- valid: [
29
- // Not child_process methods
30
- {
31
- code: 'const exec = myFunction; exec(command);',
32
- },
33
- {
34
- code: 'obj.exec(command);',
35
- },
36
- // Note: Rule flags ALL child_process methods, even execFile/spawn
37
- // These are considered "safe" in practice but rule detects them
38
- ],
39
- invalid: [],
40
- });
41
- });
42
-
43
- describe('Invalid Code - exec()', () => {
44
- ruleTester.run('invalid - exec with dynamic commands', detectChildProcess, {
45
- valid: [],
46
- invalid: [
47
- {
48
- code: 'child_process.exec(`git clone ${repoUrl}`);',
49
- errors: [{ messageId: 'childProcessCommandInjection' }],
50
- },
51
- {
52
- code: 'child_process.exec("git clone " + repoUrl);',
53
- errors: [{ messageId: 'childProcessCommandInjection' }],
54
- },
55
- {
56
- code: 'child_process.execSync(`npm install ${packageName}`);',
57
- errors: [{ messageId: 'childProcessCommandInjection' }],
58
- },
59
- {
60
- code: `
61
- const command = getUserInput();
62
- child_process.exec(command);
63
- `,
64
- errors: [{ messageId: 'childProcessCommandInjection' }],
65
- },
66
- ],
67
- });
68
- });
69
-
70
- describe('Invalid Code - execFile/spawn (Rule flags all methods)', () => {
71
- ruleTester.run('invalid - execFile and spawn (rule flags all child_process methods)', detectChildProcess, {
72
- valid: [],
73
- invalid: [
74
- // Note: Rule flags ALL child_process methods, even safe ones like execFile/spawn
75
- {
76
- code: 'child_process.execFile("git", ["clone", repoUrl], { shell: false });',
77
- errors: [{ messageId: 'childProcessCommandInjection' }],
78
- },
79
- {
80
- code: 'child_process.execFileSync("npm", ["install", packageName], { shell: false });',
81
- errors: [{ messageId: 'childProcessCommandInjection' }],
82
- },
83
- {
84
- code: 'child_process.spawn("node", ["script.js"], { shell: false });',
85
- errors: [{ messageId: 'childProcessCommandInjection' }],
86
- },
87
- {
88
- code: 'child_process.spawnSync("ls", ["-la"], { shell: false });',
89
- errors: [{ messageId: 'childProcessCommandInjection' }],
90
- },
91
- ],
92
- });
93
- });
94
-
95
- describe('Invalid Code - spawn()', () => {
96
- ruleTester.run('invalid - spawn with unsafe arguments', detectChildProcess, {
97
- valid: [],
98
- invalid: [
99
- {
100
- code: 'child_process.spawn("bash", ["-c", userCommand]);',
101
- errors: [{ messageId: 'childProcessCommandInjection' }],
102
- },
103
- {
104
- code: 'child_process.spawn(userCommand, args);',
105
- errors: [{ messageId: 'childProcessCommandInjection' }],
106
- },
107
- {
108
- code: 'child_process.spawnSync("sh", ["-c", userInput]);',
109
- errors: [{ messageId: 'childProcessCommandInjection' }],
110
- },
111
- ],
112
- });
113
- });
114
-
115
- describe('Suggestions', () => {
116
- ruleTester.run('suggestions for fixes', detectChildProcess, {
117
- valid: [],
118
- invalid: [
119
- {
120
- code: 'child_process.exec(`git clone ${repoUrl}`);',
121
- errors: [
122
- {
123
- messageId: 'childProcessCommandInjection',
124
- // Note: Rule provides suggestions but they don't have output (fix: () => null)
125
- // Test framework requires output for suggestions, so we don't test them here
126
- },
127
- ],
128
- },
129
- ],
130
- });
131
- });
132
-
133
- describe('Edge Cases', () => {
134
- ruleTester.run('edge cases', detectChildProcess, {
135
- valid: [
136
- // Literal strings (if allowLiteralStrings is true)
137
- {
138
- code: 'child_process.exec("git clone https://example.com/repo.git");',
139
- options: [{ allowLiteralStrings: true }],
140
- },
141
- ],
142
- invalid: [
143
- // Note: Rule only checks child_process.exec() directly, not imported calls
144
- // These would need rule enhancement to detect
145
- ],
146
- });
147
- });
148
-
149
- describe('Options', () => {
150
- ruleTester.run('options testing', detectChildProcess, {
151
- valid: [
152
- {
153
- code: 'child_process.exec("literal string");',
154
- options: [{ allowLiteralStrings: true }],
155
- },
156
- {
157
- code: 'child_process.spawn("node", ["script.js"]);',
158
- options: [{ allowLiteralSpawn: true }],
159
- },
160
- ],
161
- invalid: [
162
- {
163
- code: 'child_process.exec(userCommand);',
164
- options: [{ allowLiteralStrings: true }],
165
- errors: [{ messageId: 'childProcessCommandInjection' }],
166
- },
167
- ],
168
- });
169
- });
170
-
171
- describe('Edge Cases - Coverage', () => {
172
- ruleTester.run('edge cases - default case in switch (line 251)', detectChildProcess, {
173
- valid: [],
174
- invalid: [
175
- // Test with execFileSync to trigger default case in generateRefactoringSteps (line 251)
176
- {
177
- code: 'child_process.execFileSync(userCommand, args);',
178
- errors: [{ messageId: 'childProcessCommandInjection' }],
179
- },
180
- // Test with fork to trigger default case
181
- {
182
- code: 'child_process.fork(userScript);',
183
- errors: [{ messageId: 'childProcessCommandInjection' }],
184
- },
185
- // Test with forkSync to trigger forkSync case in generateRefactoringSteps (lines 429-438)
186
- {
187
- code: 'child_process.forkSync(userScript);',
188
- errors: [{ messageId: 'childProcessCommandInjection' }],
189
- },
190
- ],
191
- });
192
-
193
- ruleTester.run('edge cases - non-dangerous method (line 290)', detectChildProcess, {
194
- valid: [
195
- // Test with a method that's NOT in dangerousMethods to cover line 290
196
- // Note: child_process doesn't have many other methods, but if one exists that's not dangerous,
197
- // it should be valid. However, since we can't easily test this without modifying the rule,
198
- // we'll test with a method that might not be in the default list
199
- {
200
- code: 'child_process.someOtherMethod(command);',
201
- },
202
- ],
203
- invalid: [],
204
- });
205
- });
206
- });
207
-