eslint-plugin-secure-coding 2.3.2 → 2.3.3

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 (361) hide show
  1. package/README.md +1 -0
  2. package/package.json +3 -10
  3. package/src/index.ts +605 -0
  4. package/src/rules/__tests__/integration-demo.test.ts +290 -0
  5. package/src/rules/__tests__/integration-llm.test.ts +89 -0
  6. package/src/rules/database-injection/database-injection.test.ts +456 -0
  7. package/src/rules/database-injection/index.ts +488 -0
  8. package/src/rules/detect-child-process/detect-child-process.test.ts +207 -0
  9. package/src/rules/detect-child-process/index.ts +634 -0
  10. package/src/rules/detect-eval-with-expression/detect-eval-with-expression.test.ts +416 -0
  11. package/src/rules/detect-eval-with-expression/index.ts +463 -0
  12. package/src/rules/detect-mixed-content/detect-mixed-content.test.ts +28 -0
  13. package/src/rules/detect-mixed-content/index.ts +52 -0
  14. package/src/rules/detect-non-literal-fs-filename/detect-non-literal-fs-filename.test.ts +269 -0
  15. package/src/rules/detect-non-literal-fs-filename/index.ts +551 -0
  16. package/src/rules/detect-non-literal-regexp/detect-non-literal-regexp.test.ts +189 -0
  17. package/src/rules/detect-non-literal-regexp/index.ts +490 -0
  18. package/src/rules/detect-object-injection/detect-object-injection.test.ts +440 -0
  19. package/src/rules/detect-object-injection/index.ts +674 -0
  20. package/src/rules/detect-suspicious-dependencies/detect-suspicious-dependencies.test.ts +32 -0
  21. package/src/rules/detect-suspicious-dependencies/index.ts +84 -0
  22. package/src/rules/detect-weak-password-validation/detect-weak-password-validation.test.ts +31 -0
  23. package/src/rules/detect-weak-password-validation/index.ts +68 -0
  24. package/src/rules/no-allow-arbitrary-loads/index.ts +54 -0
  25. package/src/rules/no-allow-arbitrary-loads/no-allow-arbitrary-loads.test.ts +28 -0
  26. package/src/rules/no-arbitrary-file-access/index.ts +238 -0
  27. package/src/rules/no-arbitrary-file-access/no-arbitrary-file-access.test.ts +119 -0
  28. package/src/rules/no-buffer-overread/index.ts +724 -0
  29. package/src/rules/no-buffer-overread/no-buffer-overread.test.ts +313 -0
  30. package/src/rules/no-clickjacking/index.ts +481 -0
  31. package/src/rules/no-clickjacking/no-clickjacking.test.ts +253 -0
  32. package/src/rules/no-client-side-auth-logic/index.ts +81 -0
  33. package/src/rules/no-client-side-auth-logic/no-client-side-auth-logic.test.ts +33 -0
  34. package/src/rules/no-credentials-in-query-params/index.ts +69 -0
  35. package/src/rules/no-credentials-in-query-params/no-credentials-in-query-params.test.ts +33 -0
  36. package/src/rules/no-credentials-in-storage-api/index.ts +64 -0
  37. package/src/rules/no-credentials-in-storage-api/no-credentials-in-storage-api.test.ts +31 -0
  38. package/src/rules/no-data-in-temp-storage/index.ts +75 -0
  39. package/src/rules/no-data-in-temp-storage/no-data-in-temp-storage.test.ts +33 -0
  40. package/src/rules/no-debug-code-in-production/index.ts +59 -0
  41. package/src/rules/no-debug-code-in-production/no-debug-code-in-production.test.ts +26 -0
  42. package/src/rules/no-directive-injection/index.ts +551 -0
  43. package/src/rules/no-directive-injection/no-directive-injection.test.ts +305 -0
  44. package/src/rules/no-disabled-certificate-validation/index.ts +72 -0
  45. package/src/rules/no-disabled-certificate-validation/no-disabled-certificate-validation.test.ts +33 -0
  46. package/src/rules/no-document-cookie/index.ts +113 -0
  47. package/src/rules/no-document-cookie/no-document-cookie.test.ts +382 -0
  48. package/src/rules/no-dynamic-dependency-loading/index.ts +60 -0
  49. package/src/rules/no-dynamic-dependency-loading/no-dynamic-dependency-loading.test.ts +27 -0
  50. package/src/rules/no-electron-security-issues/index.ts +504 -0
  51. package/src/rules/no-electron-security-issues/no-electron-security-issues.test.ts +324 -0
  52. package/src/rules/no-exposed-debug-endpoints/index.ts +73 -0
  53. package/src/rules/no-exposed-debug-endpoints/no-exposed-debug-endpoints.test.ts +40 -0
  54. package/src/rules/no-exposed-sensitive-data/index.ts +428 -0
  55. package/src/rules/no-exposed-sensitive-data/no-exposed-sensitive-data.test.ts +75 -0
  56. package/src/rules/no-format-string-injection/index.ts +801 -0
  57. package/src/rules/no-format-string-injection/no-format-string-injection.test.ts +437 -0
  58. package/src/rules/no-graphql-injection/index.ts +508 -0
  59. package/src/rules/no-graphql-injection/no-graphql-injection.test.ts +371 -0
  60. package/src/rules/no-hardcoded-credentials/index.ts +478 -0
  61. package/src/rules/no-hardcoded-credentials/no-hardcoded-credentials.test.ts +639 -0
  62. package/src/rules/no-hardcoded-session-tokens/index.ts +69 -0
  63. package/src/rules/no-hardcoded-session-tokens/no-hardcoded-session-tokens.test.ts +42 -0
  64. package/src/rules/no-http-urls/index.ts +131 -0
  65. package/src/rules/no-http-urls/no-http-urls.test.ts +60 -0
  66. package/src/rules/no-improper-sanitization/index.ts +502 -0
  67. package/src/rules/no-improper-sanitization/no-improper-sanitization.test.ts +156 -0
  68. package/src/rules/no-improper-type-validation/index.ts +572 -0
  69. package/src/rules/no-improper-type-validation/no-improper-type-validation.test.ts +372 -0
  70. package/src/rules/no-insecure-comparison/index.ts +232 -0
  71. package/src/rules/no-insecure-comparison/no-insecure-comparison.test.ts +218 -0
  72. package/src/rules/no-insecure-cookie-settings/index.ts +391 -0
  73. package/src/rules/no-insecure-cookie-settings/no-insecure-cookie-settings.test.ts +409 -0
  74. package/src/rules/no-insecure-jwt/index.ts +467 -0
  75. package/src/rules/no-insecure-jwt/no-insecure-jwt.test.ts +259 -0
  76. package/src/rules/no-insecure-redirects/index.ts +267 -0
  77. package/src/rules/no-insecure-redirects/no-insecure-redirects.test.ts +108 -0
  78. package/src/rules/no-insecure-websocket/index.ts +72 -0
  79. package/src/rules/no-insecure-websocket/no-insecure-websocket.test.ts +42 -0
  80. package/src/rules/no-insufficient-postmessage-validation/index.ts +497 -0
  81. package/src/rules/no-insufficient-postmessage-validation/no-insufficient-postmessage-validation.test.ts +360 -0
  82. package/src/rules/no-insufficient-random/index.ts +288 -0
  83. package/src/rules/no-insufficient-random/no-insufficient-random.test.ts +246 -0
  84. package/src/rules/no-ldap-injection/index.ts +547 -0
  85. package/src/rules/no-ldap-injection/no-ldap-injection.test.ts +317 -0
  86. package/src/rules/no-missing-authentication/index.ts +408 -0
  87. package/src/rules/no-missing-authentication/no-missing-authentication.test.ts +350 -0
  88. package/src/rules/no-missing-cors-check/index.ts +453 -0
  89. package/src/rules/no-missing-cors-check/no-missing-cors-check.test.ts +392 -0
  90. package/src/rules/no-missing-csrf-protection/index.ts +229 -0
  91. package/src/rules/no-missing-csrf-protection/no-missing-csrf-protection.test.ts +222 -0
  92. package/src/rules/no-missing-security-headers/index.ts +266 -0
  93. package/src/rules/no-missing-security-headers/no-missing-security-headers.test.ts +98 -0
  94. package/src/rules/no-password-in-url/index.ts +64 -0
  95. package/src/rules/no-password-in-url/no-password-in-url.test.ts +27 -0
  96. package/src/rules/no-permissive-cors/index.ts +78 -0
  97. package/src/rules/no-permissive-cors/no-permissive-cors.test.ts +28 -0
  98. package/src/rules/no-pii-in-logs/index.ts +83 -0
  99. package/src/rules/no-pii-in-logs/no-pii-in-logs.test.ts +26 -0
  100. package/src/rules/no-postmessage-origin-wildcard/index.ts +67 -0
  101. package/src/rules/no-postmessage-origin-wildcard/no-postmessage-origin-wildcard.test.ts +27 -0
  102. package/src/rules/no-privilege-escalation/index.ts +403 -0
  103. package/src/rules/no-privilege-escalation/no-privilege-escalation.test.ts +306 -0
  104. package/src/rules/no-redos-vulnerable-regex/index.ts +379 -0
  105. package/src/rules/no-redos-vulnerable-regex/no-redos-vulnerable-regex.test.ts +83 -0
  106. package/src/rules/no-sensitive-data-exposure/index.ts +294 -0
  107. package/src/rules/no-sensitive-data-exposure/no-sensitive-data-exposure.test.ts +262 -0
  108. package/src/rules/no-sensitive-data-in-analytics/index.ts +73 -0
  109. package/src/rules/no-sensitive-data-in-analytics/no-sensitive-data-in-analytics.test.ts +42 -0
  110. package/src/rules/no-sensitive-data-in-cache/index.ts +59 -0
  111. package/src/rules/no-sensitive-data-in-cache/no-sensitive-data-in-cache.test.ts +32 -0
  112. package/src/rules/no-sql-injection/index.ts +424 -0
  113. package/src/rules/no-sql-injection/no-sql-injection.test.ts +303 -0
  114. package/src/rules/no-timing-attack/index.ts +552 -0
  115. package/src/rules/no-timing-attack/no-timing-attack.test.ts +348 -0
  116. package/src/rules/no-toctou-vulnerability/index.ts +250 -0
  117. package/src/rules/no-toctou-vulnerability/no-toctou-vulnerability.test.ts +60 -0
  118. package/src/rules/no-tracking-without-consent/index.ts +78 -0
  119. package/src/rules/no-tracking-without-consent/no-tracking-without-consent.test.ts +34 -0
  120. package/src/rules/no-unchecked-loop-condition/index.ts +781 -0
  121. package/src/rules/no-unchecked-loop-condition/no-unchecked-loop-condition.test.ts +459 -0
  122. package/src/rules/no-unencrypted-local-storage/index.ts +73 -0
  123. package/src/rules/no-unencrypted-local-storage/no-unencrypted-local-storage.test.ts +41 -0
  124. package/src/rules/no-unencrypted-transmission/index.ts +296 -0
  125. package/src/rules/no-unencrypted-transmission/no-unencrypted-transmission.test.ts +287 -0
  126. package/src/rules/no-unescaped-url-parameter/index.ts +424 -0
  127. package/src/rules/no-unescaped-url-parameter/no-unescaped-url-parameter.test.ts +263 -0
  128. package/src/rules/no-unlimited-resource-allocation/index.ts +767 -0
  129. package/src/rules/no-unlimited-resource-allocation/no-unlimited-resource-allocation.test.ts +544 -0
  130. package/src/rules/no-unsafe-deserialization/index.ts +593 -0
  131. package/src/rules/no-unsafe-deserialization/no-unsafe-deserialization.test.ts +310 -0
  132. package/src/rules/no-unsafe-dynamic-require/index.ts +125 -0
  133. package/src/rules/no-unsafe-dynamic-require/no-unsafe-dynamic-require.test.ts +151 -0
  134. package/src/rules/no-unsafe-regex-construction/index.ts +370 -0
  135. package/src/rules/no-unsafe-regex-construction/no-unsafe-regex-construction.test.ts +181 -0
  136. package/src/rules/no-unsanitized-html/index.ts +400 -0
  137. package/src/rules/no-unsanitized-html/no-unsanitized-html.test.ts +488 -0
  138. package/src/rules/no-unvalidated-deeplinks/index.ts +73 -0
  139. package/src/rules/no-unvalidated-deeplinks/no-unvalidated-deeplinks.test.ts +29 -0
  140. package/src/rules/no-unvalidated-user-input/index.ts +498 -0
  141. package/src/rules/no-unvalidated-user-input/no-unvalidated-user-input.test.ts +463 -0
  142. package/src/rules/no-verbose-error-messages/index.ts +83 -0
  143. package/src/rules/no-verbose-error-messages/no-verbose-error-messages.test.ts +34 -0
  144. package/src/rules/no-weak-crypto/index.ts +447 -0
  145. package/src/rules/no-weak-crypto/no-weak-crypto.test.ts +297 -0
  146. package/src/rules/no-weak-password-recovery/index.ts +509 -0
  147. package/src/rules/no-weak-password-recovery/no-weak-password-recovery.test.ts +184 -0
  148. package/src/rules/no-xpath-injection/index.ts +596 -0
  149. package/src/rules/no-xpath-injection/no-xpath-injection.test.ts +405 -0
  150. package/src/rules/no-xxe-injection/index.ts +342 -0
  151. package/src/rules/no-xxe-injection/no-xxe-injection.test.ts +122 -0
  152. package/src/rules/no-zip-slip/index.ts +526 -0
  153. package/src/rules/no-zip-slip/no-zip-slip.test.ts +305 -0
  154. package/src/rules/require-backend-authorization/index.ts +71 -0
  155. package/src/rules/require-backend-authorization/require-backend-authorization.test.ts +31 -0
  156. package/src/rules/require-code-minification/index.ts +54 -0
  157. package/src/rules/require-code-minification/require-code-minification.test.ts +30 -0
  158. package/src/rules/require-csp-headers/index.ts +74 -0
  159. package/src/rules/require-csp-headers/require-csp-headers.test.ts +34 -0
  160. package/src/rules/require-data-minimization/index.ts +65 -0
  161. package/src/rules/require-data-minimization/require-data-minimization.test.ts +31 -0
  162. package/src/rules/require-dependency-integrity/index.ts +78 -0
  163. package/src/rules/require-dependency-integrity/require-dependency-integrity.test.ts +44 -0
  164. package/src/rules/require-https-only/index.ts +75 -0
  165. package/src/rules/require-https-only/require-https-only.test.ts +26 -0
  166. package/src/rules/require-mime-type-validation/index.ts +77 -0
  167. package/src/rules/require-mime-type-validation/require-mime-type-validation.test.ts +32 -0
  168. package/src/rules/require-network-timeout/index.ts +58 -0
  169. package/src/rules/require-network-timeout/require-network-timeout.test.ts +26 -0
  170. package/src/rules/require-package-lock/index.ts +75 -0
  171. package/src/rules/require-package-lock/require-package-lock.test.ts +27 -0
  172. package/src/rules/require-secure-credential-storage/index.ts +60 -0
  173. package/src/rules/require-secure-credential-storage/require-secure-credential-storage.test.ts +26 -0
  174. package/src/rules/require-secure-defaults/index.ts +54 -0
  175. package/src/rules/require-secure-defaults/require-secure-defaults.test.ts +26 -0
  176. package/src/rules/require-secure-deletion/index.ts +52 -0
  177. package/src/rules/require-secure-deletion/require-secure-deletion.test.ts +29 -0
  178. package/src/rules/require-storage-encryption/index.ts +60 -0
  179. package/src/rules/require-storage-encryption/require-storage-encryption.test.ts +26 -0
  180. package/src/rules/require-url-validation/index.ts +85 -0
  181. package/src/rules/require-url-validation/require-url-validation.test.ts +32 -0
  182. package/src/types/{index.d.ts → index.ts} +157 -53
  183. package/src/index.d.ts +0 -32
  184. package/src/index.js +0 -465
  185. package/src/rules/database-injection/index.d.ts +0 -13
  186. package/src/rules/database-injection/index.js +0 -406
  187. package/src/rules/detect-child-process/index.d.ts +0 -11
  188. package/src/rules/detect-child-process/index.js +0 -529
  189. package/src/rules/detect-eval-with-expression/index.d.ts +0 -9
  190. package/src/rules/detect-eval-with-expression/index.js +0 -392
  191. package/src/rules/detect-mixed-content/index.d.ts +0 -8
  192. package/src/rules/detect-mixed-content/index.js +0 -44
  193. package/src/rules/detect-non-literal-fs-filename/index.d.ts +0 -7
  194. package/src/rules/detect-non-literal-fs-filename/index.js +0 -454
  195. package/src/rules/detect-non-literal-regexp/index.d.ts +0 -9
  196. package/src/rules/detect-non-literal-regexp/index.js +0 -403
  197. package/src/rules/detect-object-injection/index.d.ts +0 -11
  198. package/src/rules/detect-object-injection/index.js +0 -560
  199. package/src/rules/detect-suspicious-dependencies/index.d.ts +0 -8
  200. package/src/rules/detect-suspicious-dependencies/index.js +0 -71
  201. package/src/rules/detect-weak-password-validation/index.d.ts +0 -6
  202. package/src/rules/detect-weak-password-validation/index.js +0 -58
  203. package/src/rules/no-allow-arbitrary-loads/index.d.ts +0 -8
  204. package/src/rules/no-allow-arbitrary-loads/index.js +0 -47
  205. package/src/rules/no-arbitrary-file-access/index.d.ts +0 -13
  206. package/src/rules/no-arbitrary-file-access/index.js +0 -195
  207. package/src/rules/no-buffer-overread/index.d.ts +0 -29
  208. package/src/rules/no-buffer-overread/index.js +0 -606
  209. package/src/rules/no-clickjacking/index.d.ts +0 -10
  210. package/src/rules/no-clickjacking/index.js +0 -396
  211. package/src/rules/no-client-side-auth-logic/index.d.ts +0 -6
  212. package/src/rules/no-client-side-auth-logic/index.js +0 -69
  213. package/src/rules/no-credentials-in-query-params/index.d.ts +0 -8
  214. package/src/rules/no-credentials-in-query-params/index.js +0 -57
  215. package/src/rules/no-credentials-in-storage-api/index.d.ts +0 -6
  216. package/src/rules/no-credentials-in-storage-api/index.js +0 -54
  217. package/src/rules/no-data-in-temp-storage/index.d.ts +0 -6
  218. package/src/rules/no-data-in-temp-storage/index.js +0 -64
  219. package/src/rules/no-debug-code-in-production/index.d.ts +0 -8
  220. package/src/rules/no-debug-code-in-production/index.js +0 -51
  221. package/src/rules/no-directive-injection/index.d.ts +0 -12
  222. package/src/rules/no-directive-injection/index.js +0 -457
  223. package/src/rules/no-disabled-certificate-validation/index.d.ts +0 -6
  224. package/src/rules/no-disabled-certificate-validation/index.js +0 -61
  225. package/src/rules/no-document-cookie/index.d.ts +0 -5
  226. package/src/rules/no-document-cookie/index.js +0 -89
  227. package/src/rules/no-dynamic-dependency-loading/index.d.ts +0 -8
  228. package/src/rules/no-dynamic-dependency-loading/index.js +0 -51
  229. package/src/rules/no-electron-security-issues/index.d.ts +0 -10
  230. package/src/rules/no-electron-security-issues/index.js +0 -423
  231. package/src/rules/no-exposed-debug-endpoints/index.d.ts +0 -6
  232. package/src/rules/no-exposed-debug-endpoints/index.js +0 -62
  233. package/src/rules/no-exposed-sensitive-data/index.d.ts +0 -11
  234. package/src/rules/no-exposed-sensitive-data/index.js +0 -340
  235. package/src/rules/no-format-string-injection/index.d.ts +0 -17
  236. package/src/rules/no-format-string-injection/index.js +0 -660
  237. package/src/rules/no-graphql-injection/index.d.ts +0 -12
  238. package/src/rules/no-graphql-injection/index.js +0 -411
  239. package/src/rules/no-hardcoded-credentials/index.d.ts +0 -26
  240. package/src/rules/no-hardcoded-credentials/index.js +0 -376
  241. package/src/rules/no-hardcoded-session-tokens/index.d.ts +0 -6
  242. package/src/rules/no-hardcoded-session-tokens/index.js +0 -59
  243. package/src/rules/no-http-urls/index.d.ts +0 -12
  244. package/src/rules/no-http-urls/index.js +0 -114
  245. package/src/rules/no-improper-sanitization/index.d.ts +0 -12
  246. package/src/rules/no-improper-sanitization/index.js +0 -411
  247. package/src/rules/no-improper-type-validation/index.d.ts +0 -10
  248. package/src/rules/no-improper-type-validation/index.js +0 -475
  249. package/src/rules/no-insecure-comparison/index.d.ts +0 -7
  250. package/src/rules/no-insecure-comparison/index.js +0 -193
  251. package/src/rules/no-insecure-cookie-settings/index.d.ts +0 -9
  252. package/src/rules/no-insecure-cookie-settings/index.js +0 -306
  253. package/src/rules/no-insecure-jwt/index.d.ts +0 -10
  254. package/src/rules/no-insecure-jwt/index.js +0 -380
  255. package/src/rules/no-insecure-redirects/index.d.ts +0 -7
  256. package/src/rules/no-insecure-redirects/index.js +0 -216
  257. package/src/rules/no-insecure-websocket/index.d.ts +0 -6
  258. package/src/rules/no-insecure-websocket/index.js +0 -61
  259. package/src/rules/no-insufficient-postmessage-validation/index.d.ts +0 -14
  260. package/src/rules/no-insufficient-postmessage-validation/index.js +0 -392
  261. package/src/rules/no-insufficient-random/index.d.ts +0 -9
  262. package/src/rules/no-insufficient-random/index.js +0 -208
  263. package/src/rules/no-ldap-injection/index.d.ts +0 -10
  264. package/src/rules/no-ldap-injection/index.js +0 -455
  265. package/src/rules/no-missing-authentication/index.d.ts +0 -13
  266. package/src/rules/no-missing-authentication/index.js +0 -333
  267. package/src/rules/no-missing-cors-check/index.d.ts +0 -9
  268. package/src/rules/no-missing-cors-check/index.js +0 -399
  269. package/src/rules/no-missing-csrf-protection/index.d.ts +0 -11
  270. package/src/rules/no-missing-csrf-protection/index.js +0 -180
  271. package/src/rules/no-missing-security-headers/index.d.ts +0 -7
  272. package/src/rules/no-missing-security-headers/index.js +0 -218
  273. package/src/rules/no-password-in-url/index.d.ts +0 -8
  274. package/src/rules/no-password-in-url/index.js +0 -54
  275. package/src/rules/no-permissive-cors/index.d.ts +0 -8
  276. package/src/rules/no-permissive-cors/index.js +0 -65
  277. package/src/rules/no-pii-in-logs/index.d.ts +0 -8
  278. package/src/rules/no-pii-in-logs/index.js +0 -70
  279. package/src/rules/no-postmessage-origin-wildcard/index.d.ts +0 -8
  280. package/src/rules/no-postmessage-origin-wildcard/index.js +0 -56
  281. package/src/rules/no-privilege-escalation/index.d.ts +0 -13
  282. package/src/rules/no-privilege-escalation/index.js +0 -321
  283. package/src/rules/no-redos-vulnerable-regex/index.d.ts +0 -7
  284. package/src/rules/no-redos-vulnerable-regex/index.js +0 -306
  285. package/src/rules/no-sensitive-data-exposure/index.d.ts +0 -11
  286. package/src/rules/no-sensitive-data-exposure/index.js +0 -250
  287. package/src/rules/no-sensitive-data-in-analytics/index.d.ts +0 -8
  288. package/src/rules/no-sensitive-data-in-analytics/index.js +0 -62
  289. package/src/rules/no-sensitive-data-in-cache/index.d.ts +0 -8
  290. package/src/rules/no-sensitive-data-in-cache/index.js +0 -52
  291. package/src/rules/no-sql-injection/index.d.ts +0 -10
  292. package/src/rules/no-sql-injection/index.js +0 -335
  293. package/src/rules/no-timing-attack/index.d.ts +0 -10
  294. package/src/rules/no-timing-attack/index.js +0 -447
  295. package/src/rules/no-toctou-vulnerability/index.d.ts +0 -7
  296. package/src/rules/no-toctou-vulnerability/index.js +0 -208
  297. package/src/rules/no-tracking-without-consent/index.d.ts +0 -6
  298. package/src/rules/no-tracking-without-consent/index.js +0 -67
  299. package/src/rules/no-unchecked-loop-condition/index.d.ts +0 -12
  300. package/src/rules/no-unchecked-loop-condition/index.js +0 -646
  301. package/src/rules/no-unencrypted-local-storage/index.d.ts +0 -8
  302. package/src/rules/no-unencrypted-local-storage/index.js +0 -61
  303. package/src/rules/no-unencrypted-transmission/index.d.ts +0 -11
  304. package/src/rules/no-unencrypted-transmission/index.js +0 -236
  305. package/src/rules/no-unescaped-url-parameter/index.d.ts +0 -9
  306. package/src/rules/no-unescaped-url-parameter/index.js +0 -355
  307. package/src/rules/no-unlimited-resource-allocation/index.d.ts +0 -12
  308. package/src/rules/no-unlimited-resource-allocation/index.js +0 -643
  309. package/src/rules/no-unsafe-deserialization/index.d.ts +0 -10
  310. package/src/rules/no-unsafe-deserialization/index.js +0 -491
  311. package/src/rules/no-unsafe-dynamic-require/index.d.ts +0 -5
  312. package/src/rules/no-unsafe-dynamic-require/index.js +0 -106
  313. package/src/rules/no-unsafe-regex-construction/index.d.ts +0 -9
  314. package/src/rules/no-unsafe-regex-construction/index.js +0 -291
  315. package/src/rules/no-unsanitized-html/index.d.ts +0 -9
  316. package/src/rules/no-unsanitized-html/index.js +0 -335
  317. package/src/rules/no-unvalidated-deeplinks/index.d.ts +0 -6
  318. package/src/rules/no-unvalidated-deeplinks/index.js +0 -62
  319. package/src/rules/no-unvalidated-user-input/index.d.ts +0 -9
  320. package/src/rules/no-unvalidated-user-input/index.js +0 -420
  321. package/src/rules/no-verbose-error-messages/index.d.ts +0 -8
  322. package/src/rules/no-verbose-error-messages/index.js +0 -68
  323. package/src/rules/no-weak-crypto/index.d.ts +0 -11
  324. package/src/rules/no-weak-crypto/index.js +0 -351
  325. package/src/rules/no-weak-password-recovery/index.d.ts +0 -12
  326. package/src/rules/no-weak-password-recovery/index.js +0 -424
  327. package/src/rules/no-xpath-injection/index.d.ts +0 -10
  328. package/src/rules/no-xpath-injection/index.js +0 -487
  329. package/src/rules/no-xxe-injection/index.d.ts +0 -7
  330. package/src/rules/no-xxe-injection/index.js +0 -266
  331. package/src/rules/no-zip-slip/index.d.ts +0 -9
  332. package/src/rules/no-zip-slip/index.js +0 -445
  333. package/src/rules/require-backend-authorization/index.d.ts +0 -6
  334. package/src/rules/require-backend-authorization/index.js +0 -60
  335. package/src/rules/require-code-minification/index.d.ts +0 -8
  336. package/src/rules/require-code-minification/index.js +0 -47
  337. package/src/rules/require-csp-headers/index.d.ts +0 -6
  338. package/src/rules/require-csp-headers/index.js +0 -64
  339. package/src/rules/require-data-minimization/index.d.ts +0 -8
  340. package/src/rules/require-data-minimization/index.js +0 -53
  341. package/src/rules/require-dependency-integrity/index.d.ts +0 -6
  342. package/src/rules/require-dependency-integrity/index.js +0 -64
  343. package/src/rules/require-https-only/index.d.ts +0 -8
  344. package/src/rules/require-https-only/index.js +0 -62
  345. package/src/rules/require-mime-type-validation/index.d.ts +0 -6
  346. package/src/rules/require-mime-type-validation/index.js +0 -66
  347. package/src/rules/require-network-timeout/index.d.ts +0 -8
  348. package/src/rules/require-network-timeout/index.js +0 -50
  349. package/src/rules/require-package-lock/index.d.ts +0 -8
  350. package/src/rules/require-package-lock/index.js +0 -63
  351. package/src/rules/require-secure-credential-storage/index.d.ts +0 -8
  352. package/src/rules/require-secure-credential-storage/index.js +0 -50
  353. package/src/rules/require-secure-defaults/index.d.ts +0 -8
  354. package/src/rules/require-secure-defaults/index.js +0 -47
  355. package/src/rules/require-secure-deletion/index.d.ts +0 -8
  356. package/src/rules/require-secure-deletion/index.js +0 -44
  357. package/src/rules/require-storage-encryption/index.d.ts +0 -8
  358. package/src/rules/require-storage-encryption/index.js +0 -50
  359. package/src/rules/require-url-validation/index.d.ts +0 -6
  360. package/src/rules/require-url-validation/index.js +0 -72
  361. package/src/types/index.js +0 -17
@@ -0,0 +1,498 @@
1
+ /**
2
+ * ESLint Rule: no-unvalidated-user-input
3
+ * Detects unvalidated user input usage (req.body, req.query, etc.)
4
+ * CWE-20: Improper Input Validation
5
+ *
6
+ * @see https://cwe.mitre.org/data/definitions/20.html
7
+ * @see https://owasp.org/www-community/vulnerabilities/Improper_Input_Validation
8
+ */
9
+ import type { TSESLint, TSESTree } from '@interlace/eslint-devkit';
10
+ import { AST_NODE_TYPES, formatLLMMessage, MessageIcons } from '@interlace/eslint-devkit';
11
+ import { createRule } from '@interlace/eslint-devkit';
12
+
13
+ type MessageIds = 'unvalidatedInput' | 'useValidationLibrary' | 'useZod' | 'useJoi';
14
+
15
+ export interface Options {
16
+ /** Allow unvalidated input in test files. Default: false */
17
+ allowInTests?: boolean;
18
+
19
+ /** Trusted validation libraries. Default: ['zod', 'joi', 'yup', 'class-validator'] */
20
+ trustedLibraries?: string[];
21
+
22
+ /** Additional safe patterns to ignore. Default: ['^safe', '^sanitized', '^validated', '^clean'] (prefix patterns) */
23
+ ignorePatterns?: string[];
24
+ }
25
+
26
+ type RuleOptions = [Options?];
27
+
28
+ /**
29
+ * Patterns that indicate unvalidated user input
30
+ */
31
+ const UNVALIDATED_INPUT_PATTERNS = [
32
+ // Express/Node.js patterns
33
+ { pattern: /\breq\.body\b/, name: 'req.body', context: 'Express request body' },
34
+ { pattern: /\breq\.query\b/, name: 'req.query', context: 'Express query parameters' },
35
+ { pattern: /\breq\.params\b/, name: 'req.params', context: 'Express route parameters' },
36
+ { pattern: /\breq\.headers\b/, name: 'req.headers', context: 'Express headers' },
37
+ { pattern: /\breq\.cookies\b/, name: 'req.cookies', context: 'Express cookies' },
38
+
39
+ // Fastify patterns
40
+ { pattern: /\brequest\.body\b/, name: 'request.body', context: 'Fastify request body' },
41
+ { pattern: /\brequest\.query\b/, name: 'request.query', context: 'Fastify query parameters' },
42
+ { pattern: /\brequest\.params\b/, name: 'request.params', context: 'Fastify route parameters' },
43
+
44
+ // Next.js patterns
45
+ { pattern: /\bsearchParams\b/, name: 'searchParams', context: 'Next.js search params' },
46
+
47
+ // Generic patterns - ONLY flag clearly user-related patterns
48
+ // Removed 'input' as it's too generic and causes many false positives
49
+ { pattern: /\buserInput\b/, name: 'userInput', context: 'Generic user input' },
50
+ { pattern: /\bunsafeInput\b/, name: 'unsafeInput', context: 'Explicitly unsafe input' },
51
+ { pattern: /\brawInput\b/, name: 'rawInput', context: 'Raw/unprocessed input' },
52
+ ];
53
+
54
+ /**
55
+ * Check if a node is inside a validation function call
56
+ */
57
+ function isInsideValidationCall(
58
+ node: TSESTree.Node,
59
+ sourceCode: TSESLint.SourceCode,
60
+ trustedLibraries: string[]
61
+ ): boolean {
62
+ let current: TSESTree.Node | null = node;
63
+
64
+ while (current) {
65
+ // Check if current is an argument to a CallExpression
66
+ if (current.parent && current.parent.type === 'CallExpression') {
67
+ const callExpr = current.parent as TSESTree.CallExpression;
68
+
69
+ // Verify that current is actually an argument of this call
70
+ const isArgument = callExpr.arguments.some((arg: TSESTree.CallExpressionArgument) => arg === current);
71
+ if (!isArgument) {
72
+ // Not an argument, continue traversing
73
+ if ('parent' in current && current.parent) {
74
+ current = current.parent as TSESTree.Node;
75
+ continue;
76
+ } else {
77
+ break;
78
+ }
79
+ }
80
+
81
+ const callee = callExpr.callee;
82
+
83
+ // Check if it's a validation library call (e.g., schema.parse(), schema.validate())
84
+ if (callee.type === 'MemberExpression') {
85
+ const property = callee.property;
86
+ if (property.type === 'Identifier') {
87
+ const methodName = property.name.toLowerCase();
88
+ // Check for validation methods (including async variants)
89
+ // Note: safeParse is one word, not two
90
+ if (['parse', 'validate', 'safeparse', 'parseasync', 'validateasync', 'safe_parse'].includes(methodName)) {
91
+ return true;
92
+ }
93
+ }
94
+
95
+ // Check if the object is a validation library
96
+ const object = callee.object;
97
+ if (object.type === 'Identifier') {
98
+ const objectName = object.name.toLowerCase();
99
+ if (trustedLibraries.some(lib => objectName.includes(lib.toLowerCase()))) {
100
+ return true;
101
+ }
102
+ }
103
+ }
104
+
105
+ // Check if it's a direct validation function call (e.g., validate(), plainToClass())
106
+ if (callee.type === 'Identifier') {
107
+ const calleeName = callee.name.toLowerCase();
108
+ if (['validate', 'plaintoclass', 'transform'].includes(calleeName)) {
109
+ return true;
110
+ }
111
+ if (trustedLibraries.some(lib => calleeName.includes(lib.toLowerCase()))) {
112
+ return true;
113
+ }
114
+ }
115
+ }
116
+
117
+ // Traverse up the AST
118
+ if ('parent' in current && current.parent) {
119
+ current = current.parent as TSESTree.Node;
120
+ } else {
121
+ break;
122
+ }
123
+ }
124
+
125
+ return false;
126
+ }
127
+
128
+ /**
129
+ * Check if a string matches any ignore pattern
130
+ */
131
+ function matchesIgnorePattern(text: string, ignorePatterns: string[]): boolean {
132
+ return ignorePatterns.some(pattern => {
133
+ try {
134
+ const regex = new RegExp(pattern, 'i');
135
+ return regex.test(text);
136
+ } catch {
137
+ // Invalid regex - treat as literal string match
138
+ return text.toLowerCase().includes(pattern.toLowerCase());
139
+ }
140
+ });
141
+ }
142
+
143
+ export const noUnvalidatedUserInput = createRule<RuleOptions, MessageIds>({
144
+ name: 'no-unvalidated-user-input',
145
+ meta: {
146
+ type: 'problem',
147
+ docs: {
148
+ description: 'Detects unvalidated user input usage (req.body, req.query, etc.)',
149
+ },
150
+ hasSuggestions: true,
151
+ messages: {
152
+ unvalidatedInput: formatLLMMessage({
153
+ icon: MessageIcons.SECURITY,
154
+ issueName: 'Unvalidated User Input',
155
+ cwe: 'CWE-20',
156
+ description: 'Unvalidated user input detected: {{inputSource}}',
157
+ severity: 'HIGH',
158
+ fix: 'Use validation library: {{validationExample}}',
159
+ documentationLink: 'https://cwe.mitre.org/data/definitions/20.html',
160
+ }),
161
+ useValidationLibrary: formatLLMMessage({
162
+ icon: MessageIcons.INFO,
163
+ issueName: 'Use Validation Library',
164
+ description: 'Use validation library',
165
+ severity: 'LOW',
166
+ fix: 'Use Zod, Joi, Yup, or class-validator',
167
+ documentationLink: 'https://zod.dev/',
168
+ }),
169
+ useZod: formatLLMMessage({
170
+ icon: MessageIcons.INFO,
171
+ issueName: 'Use Zod',
172
+ description: 'Use Zod for validation',
173
+ severity: 'LOW',
174
+ fix: 'const data = z.object({ name: z.string() }).parse(req.body)',
175
+ documentationLink: 'https://zod.dev/',
176
+ }),
177
+ useJoi: formatLLMMessage({
178
+ icon: MessageIcons.INFO,
179
+ issueName: 'Use Joi',
180
+ description: 'Use Joi for validation',
181
+ severity: 'LOW',
182
+ fix: 'Joi.object({ name: Joi.string() }).validate(req.body)',
183
+ documentationLink: 'https://joi.dev/',
184
+ }),
185
+ },
186
+ schema: [
187
+ {
188
+ type: 'object',
189
+ properties: {
190
+ allowInTests: {
191
+ type: 'boolean',
192
+ default: false,
193
+ description: 'Allow unvalidated input in test files',
194
+ },
195
+ trustedLibraries: {
196
+ type: 'array',
197
+ items: { type: 'string' },
198
+ default: ['zod', 'joi', 'yup', 'class-validator'],
199
+ description: 'Trusted validation libraries',
200
+ },
201
+ ignorePatterns: {
202
+ type: 'array',
203
+ items: { type: 'string' },
204
+ default: [],
205
+ description: 'Additional safe patterns to ignore',
206
+ },
207
+ },
208
+ additionalProperties: false,
209
+ },
210
+ ],
211
+ },
212
+ defaultOptions: [
213
+ {
214
+ allowInTests: false,
215
+ trustedLibraries: ['zod', 'joi', 'yup', 'class-validator'],
216
+ ignorePatterns: ['^safe', '^sanitized', '^validated', '^clean'],
217
+ },
218
+ ],
219
+ create(
220
+ context: TSESLint.RuleContext<MessageIds, RuleOptions>,
221
+ [options = {}]
222
+ ) {
223
+ const {
224
+ allowInTests = false,
225
+ trustedLibraries = ['zod', 'joi', 'yup', 'class-validator'],
226
+ ignorePatterns = ['^safe', '^sanitized', '^validated', '^clean'],
227
+ } = options as Options;
228
+
229
+ const filename = context.getFilename();
230
+ const isTestFile = allowInTests && /\.(test|spec)\.(ts|tsx|js|jsx)$/.test(filename);
231
+ const sourceCode = context.sourceCode || context.sourceCode;
232
+
233
+ function checkMemberExpression(node: TSESTree.MemberExpression) {
234
+ if (isTestFile) {
235
+ return;
236
+ }
237
+
238
+ const text = sourceCode.getText(node);
239
+
240
+ // Check if the variable name (if in assignment) matches ignore pattern
241
+ // For cases like: const safeInput = req.body;
242
+ if (node.parent && node.parent.type === 'VariableDeclarator' && node.parent.id.type === 'Identifier') {
243
+ const varName = node.parent.id.name;
244
+ if (matchesIgnorePattern(varName, ignorePatterns)) {
245
+ return;
246
+ }
247
+ }
248
+
249
+ // Check if it matches any ignore pattern
250
+ if (matchesIgnorePattern(text, ignorePatterns)) {
251
+ return;
252
+ }
253
+
254
+ // Check if it matches unvalidated input patterns
255
+ // For nested member expressions like req.body.name, check the base (req.body)
256
+ let baseText = text;
257
+ if (node.object.type === 'MemberExpression') {
258
+ baseText = sourceCode.getText(node.object);
259
+ }
260
+
261
+ const matchedPattern = UNVALIDATED_INPUT_PATTERNS.find(p =>
262
+ p.pattern.test(text) || p.pattern.test(baseText)
263
+ );
264
+
265
+ if (matchedPattern) {
266
+ // Skip if this is a nested member expression and the parent also matches
267
+ // This prevents double reporting for cases like req.query.id
268
+ // We only want to report on the outermost matching expression
269
+ if (node.object.type === 'MemberExpression') {
270
+ const parentText = sourceCode.getText(node.object);
271
+ const parentMatches = UNVALIDATED_INPUT_PATTERNS.some(p => p.pattern.test(parentText));
272
+ if (parentMatches) {
273
+ // Parent also matches, skip this nested one - it will be reported when we visit the parent
274
+ return;
275
+ }
276
+ }
277
+
278
+ // Skip if this is in a destructuring assignment - checkObjectPattern will handle it
279
+ // This prevents double reporting for cases like: const { email } = req.body;
280
+ if (node.parent && node.parent.type === 'VariableDeclarator' && node.parent.id.type === 'ObjectPattern') {
281
+ return; // checkObjectPattern will report on the init instead
282
+ }
283
+
284
+ // Check if it's inside a validation call
285
+ if (isInsideValidationCall(node, sourceCode, trustedLibraries)) {
286
+ return;
287
+ }
288
+
289
+ // Determine validation example based on context
290
+ let validationExample = 'const schema = z.object({ field: z.string() }); const data = schema.parse(req.body);';
291
+ if (text.includes('query')) {
292
+ validationExample = 'const schema = z.object({ id: z.string() }); const data = schema.parse(req.query);';
293
+ } else if (text.includes('params')) {
294
+ validationExample = 'const schema = z.object({ id: z.string() }); const data = schema.parse(req.params);';
295
+ }
296
+
297
+ // Build suggestions - provide same code as output for test framework recognition
298
+ const suggestions: TSESLint.SuggestionReportDescriptor<MessageIds>[] = [
299
+ {
300
+ messageId: 'useZod',
301
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
302
+ fix: (_fixer: TSESLint.RuleFixer) => {
303
+ // This is a suggestion, not an auto-fix, so we return null
304
+ return null;
305
+ },
306
+ },
307
+ {
308
+ messageId: 'useJoi',
309
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
310
+ fix: (_fixer: TSESLint.RuleFixer) => {
311
+ return null;
312
+ },
313
+ },
314
+ ];
315
+
316
+ context.report({
317
+ node,
318
+ messageId: 'unvalidatedInput',
319
+ data: {
320
+ inputSource: matchedPattern.name,
321
+ validationExample,
322
+ },
323
+ suggest: suggestions,
324
+ });
325
+ }
326
+ }
327
+
328
+ function checkIdentifier(node: TSESTree.Identifier) {
329
+ if (isTestFile) {
330
+ return;
331
+ }
332
+
333
+ const text = node.name;
334
+
335
+ // Check if it matches any ignore pattern
336
+ if (matchesIgnorePattern(text, ignorePatterns)) {
337
+ return;
338
+ }
339
+
340
+ // Skip if this identifier is assigned from a user input source (MemberExpression)
341
+ // For cases like: const userInput = req.body;
342
+ // We should only report on req.body, not on userInput
343
+ // But don't skip if the init is the same identifier (e.g., const data = input;)
344
+ if (node.parent && node.parent.type === 'VariableDeclarator' && node.parent.init) {
345
+ const init = node.parent.init;
346
+ // Only skip if init is a MemberExpression (like req.body) that will be caught by checkMemberExpression
347
+ // Don't skip if init is the same identifier (like input) - we want to report on it
348
+ if (init.type === 'MemberExpression') {
349
+ const initText = sourceCode.getText(init);
350
+ // Check if init matches any user input pattern
351
+ const initMatchesPattern = UNVALIDATED_INPUT_PATTERNS.some(p => p.pattern.test(initText));
352
+ if (initMatchesPattern) {
353
+ return; // Skip - the init (e.g., req.body) will be reported by checkMemberExpression
354
+ }
355
+ }
356
+ }
357
+
358
+ // Check for generic input patterns (userInput, unsafeInput, rawInput)
359
+ const genericInputPatternNames = ['userInput', 'unsafeInput', 'rawInput'];
360
+ const matchedPattern = UNVALIDATED_INPUT_PATTERNS.find(p =>
361
+ genericInputPatternNames.includes(p.name) && p.pattern.test(text)
362
+ );
363
+
364
+ if (matchedPattern) {
365
+ // Check if it's inside a validation call
366
+ if (isInsideValidationCall(node, sourceCode, trustedLibraries)) {
367
+ return;
368
+ }
369
+
370
+ context.report({
371
+ node,
372
+ messageId: 'unvalidatedInput',
373
+ data: {
374
+ inputSource: matchedPattern.name,
375
+ validationExample: 'const schema = z.object({ field: z.string() }); const data = schema.parse(input);',
376
+ },
377
+ suggest: [
378
+ {
379
+ messageId: 'useZod',
380
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
381
+ fix: (_fixer: TSESLint.RuleFixer) => null,
382
+ },
383
+ {
384
+ messageId: 'useJoi',
385
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
386
+ fix: (_fixer: TSESLint.RuleFixer) => null,
387
+ },
388
+ ],
389
+ });
390
+ }
391
+ }
392
+
393
+ function checkObjectPattern(node: TSESTree.ObjectPattern) {
394
+ if (isTestFile) {
395
+ return;
396
+ }
397
+
398
+ // Check destructuring patterns like: const { page, limit } = req.query;
399
+ if (node.parent && node.parent.type === AST_NODE_TYPES.VariableDeclarator && node.parent.init) {
400
+ const init = node.parent.init;
401
+ const initText = sourceCode.getText(init);
402
+
403
+ // If init is a CallExpression, check if it's a validation call
404
+ // If so, the input is being validated, so skip
405
+ if (init.type === AST_NODE_TYPES.CallExpression) {
406
+ const callee = init.callee;
407
+ if (callee.type === AST_NODE_TYPES.MemberExpression && callee.property.type === AST_NODE_TYPES.Identifier) {
408
+ const methodName = callee.property.name.toLowerCase();
409
+ if (['parse', 'validate', 'safeparse', 'parseasync', 'validateasync', 'safe_parse'].includes(methodName)) {
410
+ return; // It's a validation call, skip
411
+ }
412
+ }
413
+ if (callee.type === AST_NODE_TYPES.Identifier) {
414
+ const calleeName = callee.name.toLowerCase();
415
+ if (['validate', 'plaintoclass', 'transform'].includes(calleeName)) {
416
+ return; // It's a validation call, skip
417
+ }
418
+ }
419
+ }
420
+
421
+ // Check if the right side matches unvalidated input patterns
422
+ const matchedPattern = UNVALIDATED_INPUT_PATTERNS.find(p => p.pattern.test(initText));
423
+
424
+ if (matchedPattern) {
425
+ // For CallExpressions, check the arguments to see if they're validated
426
+ // The init itself being a validation call was already checked above
427
+ if (init.type === AST_NODE_TYPES.CallExpression) {
428
+ // Check each argument to see if it's validated
429
+ // If init is a validation call (like schema.validate(req.body)),
430
+ // then req.body is validated, so skip
431
+ const callee = init.callee;
432
+ const isValidationCall =
433
+ (callee.type === AST_NODE_TYPES.MemberExpression && callee.property.type === AST_NODE_TYPES.Identifier &&
434
+ ['parse', 'validate', 'safeparse', 'parseasync', 'validateasync', 'safe_parse'].includes(callee.property.name.toLowerCase())) ||
435
+ (callee.type === AST_NODE_TYPES.Identifier &&
436
+ ['validate', 'plaintoclass', 'transform'].includes(callee.name.toLowerCase()));
437
+
438
+ if (isValidationCall) {
439
+ return; // The init is a validation call, so the input is validated
440
+ }
441
+
442
+ // If init is not a validation call, check if arguments are validated
443
+ const hasValidatedArg = init.arguments.some((arg: TSESTree.CallExpressionArgument) => {
444
+ if (arg.type === AST_NODE_TYPES.MemberExpression || arg.type === AST_NODE_TYPES.Identifier) {
445
+ return isInsideValidationCall(arg, sourceCode, trustedLibraries);
446
+ }
447
+ return false;
448
+ });
449
+ if (hasValidatedArg) {
450
+ return; // At least one argument is validated
451
+ }
452
+ } else {
453
+ // For non-call expressions, check if init itself is inside a validation call
454
+ if (isInsideValidationCall(init, sourceCode, trustedLibraries)) {
455
+ return;
456
+ }
457
+ }
458
+
459
+ // Check if variable name matches ignore pattern
460
+ if (node.parent.id.type === AST_NODE_TYPES.ObjectPattern) {
461
+ const varText = sourceCode.getText(node.parent.id);
462
+ if (matchesIgnorePattern(varText, ignorePatterns)) {
463
+ return;
464
+ }
465
+ }
466
+
467
+ context.report({
468
+ node: init,
469
+ messageId: 'unvalidatedInput',
470
+ data: {
471
+ inputSource: matchedPattern.name,
472
+ validationExample: 'const schema = z.object({ page: z.string(), limit: z.string() }); const { page, limit } = schema.parse(req.query);',
473
+ },
474
+ suggest: [
475
+ {
476
+ messageId: 'useZod',
477
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
478
+ fix: (_fixer: TSESLint.RuleFixer) => null,
479
+ },
480
+ {
481
+ messageId: 'useJoi',
482
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
483
+ fix: (_fixer: TSESLint.RuleFixer) => null,
484
+ },
485
+ ],
486
+ });
487
+ }
488
+ }
489
+ }
490
+
491
+ return {
492
+ MemberExpression: checkMemberExpression,
493
+ Identifier: checkIdentifier,
494
+ ObjectPattern: checkObjectPattern,
495
+ };
496
+ },
497
+ });
498
+