@trust-assurance-protocol/owaspscan 1.0.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 (221) hide show
  1. package/dist/analysis/ast-analyzer.d.ts +13 -0
  2. package/dist/analysis/ast-analyzer.d.ts.map +1 -0
  3. package/dist/analysis/ast-analyzer.js +58 -0
  4. package/dist/analysis/ast-analyzer.js.map +1 -0
  5. package/dist/analysis/llm-verifier.d.ts +17 -0
  6. package/dist/analysis/llm-verifier.d.ts.map +1 -0
  7. package/dist/analysis/llm-verifier.js +152 -0
  8. package/dist/analysis/llm-verifier.js.map +1 -0
  9. package/dist/analysis/result-cache.d.ts +20 -0
  10. package/dist/analysis/result-cache.d.ts.map +1 -0
  11. package/dist/analysis/result-cache.js +70 -0
  12. package/dist/analysis/result-cache.js.map +1 -0
  13. package/dist/analysis/sinks.d.ts +12 -0
  14. package/dist/analysis/sinks.d.ts.map +1 -0
  15. package/dist/analysis/sinks.js +142 -0
  16. package/dist/analysis/sinks.js.map +1 -0
  17. package/dist/analysis/sources.d.ts +8 -0
  18. package/dist/analysis/sources.d.ts.map +1 -0
  19. package/dist/analysis/sources.js +114 -0
  20. package/dist/analysis/sources.js.map +1 -0
  21. package/dist/analysis/taint-engine.d.ts +5 -0
  22. package/dist/analysis/taint-engine.d.ts.map +1 -0
  23. package/dist/analysis/taint-engine.js +187 -0
  24. package/dist/analysis/taint-engine.js.map +1 -0
  25. package/dist/cli/index.d.ts +3 -0
  26. package/dist/cli/index.d.ts.map +1 -0
  27. package/dist/cli/index.js +227 -0
  28. package/dist/cli/index.js.map +1 -0
  29. package/dist/config/loader.d.ts +10 -0
  30. package/dist/config/loader.d.ts.map +1 -0
  31. package/dist/config/loader.js +81 -0
  32. package/dist/config/loader.js.map +1 -0
  33. package/dist/config/schema.d.ts +23 -0
  34. package/dist/config/schema.d.ts.map +1 -0
  35. package/dist/config/schema.js +17 -0
  36. package/dist/config/schema.js.map +1 -0
  37. package/dist/mcp/server.d.ts +2 -0
  38. package/dist/mcp/server.d.ts.map +1 -0
  39. package/dist/mcp/server.js +250 -0
  40. package/dist/mcp/server.js.map +1 -0
  41. package/dist/parsers/ast-parser.d.ts +38 -0
  42. package/dist/parsers/ast-parser.d.ts.map +1 -0
  43. package/dist/parsers/ast-parser.js +88 -0
  44. package/dist/parsers/ast-parser.js.map +1 -0
  45. package/dist/parsers/ast-queries.d.ts +63 -0
  46. package/dist/parsers/ast-queries.d.ts.map +1 -0
  47. package/dist/parsers/ast-queries.js +580 -0
  48. package/dist/parsers/ast-queries.js.map +1 -0
  49. package/dist/reporter/console.d.ts +8 -0
  50. package/dist/reporter/console.d.ts.map +1 -0
  51. package/dist/reporter/console.js +143 -0
  52. package/dist/reporter/console.js.map +1 -0
  53. package/dist/reporter/json.d.ts +3 -0
  54. package/dist/reporter/json.d.ts.map +1 -0
  55. package/dist/reporter/json.js +7 -0
  56. package/dist/reporter/json.js.map +1 -0
  57. package/dist/reporter/llm.d.ts +3 -0
  58. package/dist/reporter/llm.d.ts.map +1 -0
  59. package/dist/reporter/llm.js +66 -0
  60. package/dist/reporter/llm.js.map +1 -0
  61. package/dist/reporter/sarif.d.ts +3 -0
  62. package/dist/reporter/sarif.d.ts.map +1 -0
  63. package/dist/reporter/sarif.js +110 -0
  64. package/dist/reporter/sarif.js.map +1 -0
  65. package/dist/rules/owasp-a01/idor.d.ts +3 -0
  66. package/dist/rules/owasp-a01/idor.d.ts.map +1 -0
  67. package/dist/rules/owasp-a01/idor.js +48 -0
  68. package/dist/rules/owasp-a01/idor.js.map +1 -0
  69. package/dist/rules/owasp-a01/missing-auth-middleware.d.ts +3 -0
  70. package/dist/rules/owasp-a01/missing-auth-middleware.d.ts.map +1 -0
  71. package/dist/rules/owasp-a01/missing-auth-middleware.js +41 -0
  72. package/dist/rules/owasp-a01/missing-auth-middleware.js.map +1 -0
  73. package/dist/rules/owasp-a01/path-traversal.d.ts +3 -0
  74. package/dist/rules/owasp-a01/path-traversal.d.ts.map +1 -0
  75. package/dist/rules/owasp-a01/path-traversal.js +73 -0
  76. package/dist/rules/owasp-a01/path-traversal.js.map +1 -0
  77. package/dist/rules/owasp-a02/hardcoded-secrets.d.ts +3 -0
  78. package/dist/rules/owasp-a02/hardcoded-secrets.d.ts.map +1 -0
  79. package/dist/rules/owasp-a02/hardcoded-secrets.js +97 -0
  80. package/dist/rules/owasp-a02/hardcoded-secrets.js.map +1 -0
  81. package/dist/rules/owasp-a02/insecure-tls.d.ts +3 -0
  82. package/dist/rules/owasp-a02/insecure-tls.d.ts.map +1 -0
  83. package/dist/rules/owasp-a02/insecure-tls.js +75 -0
  84. package/dist/rules/owasp-a02/insecure-tls.js.map +1 -0
  85. package/dist/rules/owasp-a02/weak-hash.d.ts +3 -0
  86. package/dist/rules/owasp-a02/weak-hash.d.ts.map +1 -0
  87. package/dist/rules/owasp-a02/weak-hash.js +73 -0
  88. package/dist/rules/owasp-a02/weak-hash.js.map +1 -0
  89. package/dist/rules/owasp-a02/weak-random.d.ts +3 -0
  90. package/dist/rules/owasp-a02/weak-random.d.ts.map +1 -0
  91. package/dist/rules/owasp-a02/weak-random.js +70 -0
  92. package/dist/rules/owasp-a02/weak-random.js.map +1 -0
  93. package/dist/rules/owasp-a03/command-injection.d.ts +3 -0
  94. package/dist/rules/owasp-a03/command-injection.d.ts.map +1 -0
  95. package/dist/rules/owasp-a03/command-injection.js +79 -0
  96. package/dist/rules/owasp-a03/command-injection.js.map +1 -0
  97. package/dist/rules/owasp-a03/ldap-injection.d.ts +3 -0
  98. package/dist/rules/owasp-a03/ldap-injection.d.ts.map +1 -0
  99. package/dist/rules/owasp-a03/ldap-injection.js +56 -0
  100. package/dist/rules/owasp-a03/ldap-injection.js.map +1 -0
  101. package/dist/rules/owasp-a03/nosql-injection.d.ts +3 -0
  102. package/dist/rules/owasp-a03/nosql-injection.d.ts.map +1 -0
  103. package/dist/rules/owasp-a03/nosql-injection.js +61 -0
  104. package/dist/rules/owasp-a03/nosql-injection.js.map +1 -0
  105. package/dist/rules/owasp-a03/sql-injection.d.ts +3 -0
  106. package/dist/rules/owasp-a03/sql-injection.d.ts.map +1 -0
  107. package/dist/rules/owasp-a03/sql-injection.js +88 -0
  108. package/dist/rules/owasp-a03/sql-injection.js.map +1 -0
  109. package/dist/rules/owasp-a03/template-injection.d.ts +3 -0
  110. package/dist/rules/owasp-a03/template-injection.d.ts.map +1 -0
  111. package/dist/rules/owasp-a03/template-injection.js +64 -0
  112. package/dist/rules/owasp-a03/template-injection.js.map +1 -0
  113. package/dist/rules/owasp-a03/xss.d.ts +3 -0
  114. package/dist/rules/owasp-a03/xss.d.ts.map +1 -0
  115. package/dist/rules/owasp-a03/xss.js +74 -0
  116. package/dist/rules/owasp-a03/xss.js.map +1 -0
  117. package/dist/rules/owasp-a04/mass-assignment.d.ts +3 -0
  118. package/dist/rules/owasp-a04/mass-assignment.d.ts.map +1 -0
  119. package/dist/rules/owasp-a04/mass-assignment.js +63 -0
  120. package/dist/rules/owasp-a04/mass-assignment.js.map +1 -0
  121. package/dist/rules/owasp-a04/missing-rate-limit.d.ts +3 -0
  122. package/dist/rules/owasp-a04/missing-rate-limit.d.ts.map +1 -0
  123. package/dist/rules/owasp-a04/missing-rate-limit.js +48 -0
  124. package/dist/rules/owasp-a04/missing-rate-limit.js.map +1 -0
  125. package/dist/rules/owasp-a05/cors-wildcard.d.ts +3 -0
  126. package/dist/rules/owasp-a05/cors-wildcard.d.ts.map +1 -0
  127. package/dist/rules/owasp-a05/cors-wildcard.js +79 -0
  128. package/dist/rules/owasp-a05/cors-wildcard.js.map +1 -0
  129. package/dist/rules/owasp-a05/debug-mode.d.ts +3 -0
  130. package/dist/rules/owasp-a05/debug-mode.d.ts.map +1 -0
  131. package/dist/rules/owasp-a05/debug-mode.js +73 -0
  132. package/dist/rules/owasp-a05/debug-mode.js.map +1 -0
  133. package/dist/rules/owasp-a05/default-credentials.d.ts +3 -0
  134. package/dist/rules/owasp-a05/default-credentials.d.ts.map +1 -0
  135. package/dist/rules/owasp-a05/default-credentials.js +52 -0
  136. package/dist/rules/owasp-a05/default-credentials.js.map +1 -0
  137. package/dist/rules/owasp-a05/error-disclosure.d.ts +3 -0
  138. package/dist/rules/owasp-a05/error-disclosure.d.ts.map +1 -0
  139. package/dist/rules/owasp-a05/error-disclosure.js +70 -0
  140. package/dist/rules/owasp-a05/error-disclosure.js.map +1 -0
  141. package/dist/rules/owasp-a06/outdated-packages.d.ts +3 -0
  142. package/dist/rules/owasp-a06/outdated-packages.d.ts.map +1 -0
  143. package/dist/rules/owasp-a06/outdated-packages.js +75 -0
  144. package/dist/rules/owasp-a06/outdated-packages.js.map +1 -0
  145. package/dist/rules/owasp-a07/insecure-cookies.d.ts +3 -0
  146. package/dist/rules/owasp-a07/insecure-cookies.d.ts.map +1 -0
  147. package/dist/rules/owasp-a07/insecure-cookies.js +64 -0
  148. package/dist/rules/owasp-a07/insecure-cookies.js.map +1 -0
  149. package/dist/rules/owasp-a07/jwt-none-alg.d.ts +3 -0
  150. package/dist/rules/owasp-a07/jwt-none-alg.d.ts.map +1 -0
  151. package/dist/rules/owasp-a07/jwt-none-alg.js +81 -0
  152. package/dist/rules/owasp-a07/jwt-none-alg.js.map +1 -0
  153. package/dist/rules/owasp-a07/no-password-hashing.d.ts +3 -0
  154. package/dist/rules/owasp-a07/no-password-hashing.d.ts.map +1 -0
  155. package/dist/rules/owasp-a07/no-password-hashing.js +70 -0
  156. package/dist/rules/owasp-a07/no-password-hashing.js.map +1 -0
  157. package/dist/rules/owasp-a07/weak-session.d.ts +3 -0
  158. package/dist/rules/owasp-a07/weak-session.d.ts.map +1 -0
  159. package/dist/rules/owasp-a07/weak-session.js +64 -0
  160. package/dist/rules/owasp-a07/weak-session.js.map +1 -0
  161. package/dist/rules/owasp-a08/unsafe-deserialization.d.ts +3 -0
  162. package/dist/rules/owasp-a08/unsafe-deserialization.d.ts.map +1 -0
  163. package/dist/rules/owasp-a08/unsafe-deserialization.js +78 -0
  164. package/dist/rules/owasp-a08/unsafe-deserialization.js.map +1 -0
  165. package/dist/rules/owasp-a08/unsafe-eval.d.ts +3 -0
  166. package/dist/rules/owasp-a08/unsafe-eval.d.ts.map +1 -0
  167. package/dist/rules/owasp-a08/unsafe-eval.js +73 -0
  168. package/dist/rules/owasp-a08/unsafe-eval.js.map +1 -0
  169. package/dist/rules/owasp-a09/log-sensitive-data.d.ts +3 -0
  170. package/dist/rules/owasp-a09/log-sensitive-data.d.ts.map +1 -0
  171. package/dist/rules/owasp-a09/log-sensitive-data.js +73 -0
  172. package/dist/rules/owasp-a09/log-sensitive-data.js.map +1 -0
  173. package/dist/rules/owasp-a09/missing-error-handling.d.ts +3 -0
  174. package/dist/rules/owasp-a09/missing-error-handling.d.ts.map +1 -0
  175. package/dist/rules/owasp-a09/missing-error-handling.js +84 -0
  176. package/dist/rules/owasp-a09/missing-error-handling.js.map +1 -0
  177. package/dist/rules/owasp-a10/open-redirect.d.ts +3 -0
  178. package/dist/rules/owasp-a10/open-redirect.d.ts.map +1 -0
  179. package/dist/rules/owasp-a10/open-redirect.js +67 -0
  180. package/dist/rules/owasp-a10/open-redirect.js.map +1 -0
  181. package/dist/rules/owasp-a10/unvalidated-fetch.d.ts +3 -0
  182. package/dist/rules/owasp-a10/unvalidated-fetch.d.ts.map +1 -0
  183. package/dist/rules/owasp-a10/unvalidated-fetch.js +85 -0
  184. package/dist/rules/owasp-a10/unvalidated-fetch.js.map +1 -0
  185. package/dist/rules/registry.d.ts +20 -0
  186. package/dist/rules/registry.d.ts.map +1 -0
  187. package/dist/rules/registry.js +142 -0
  188. package/dist/rules/registry.js.map +1 -0
  189. package/dist/scanner/engine.d.ts +21 -0
  190. package/dist/scanner/engine.d.ts.map +1 -0
  191. package/dist/scanner/engine.js +260 -0
  192. package/dist/scanner/engine.js.map +1 -0
  193. package/dist/scanner/file-walker.d.ts +7 -0
  194. package/dist/scanner/file-walker.d.ts.map +1 -0
  195. package/dist/scanner/file-walker.js +81 -0
  196. package/dist/scanner/file-walker.js.map +1 -0
  197. package/dist/scanner/language-detect.d.ts +5 -0
  198. package/dist/scanner/language-detect.d.ts.map +1 -0
  199. package/dist/scanner/language-detect.js +91 -0
  200. package/dist/scanner/language-detect.js.map +1 -0
  201. package/dist/scanner/sca-scanner.d.ts +38 -0
  202. package/dist/scanner/sca-scanner.d.ts.map +1 -0
  203. package/dist/scanner/sca-scanner.js +223 -0
  204. package/dist/scanner/sca-scanner.js.map +1 -0
  205. package/dist/types/index.d.ts +114 -0
  206. package/dist/types/index.d.ts.map +1 -0
  207. package/dist/types/index.js +25 -0
  208. package/dist/types/index.js.map +1 -0
  209. package/dist/utils/pattern-matcher.d.ts +4 -0
  210. package/dist/utils/pattern-matcher.d.ts.map +1 -0
  211. package/dist/utils/pattern-matcher.js +72 -0
  212. package/dist/utils/pattern-matcher.js.map +1 -0
  213. package/dist/utils/scoring.d.ts +8 -0
  214. package/dist/utils/scoring.d.ts.map +1 -0
  215. package/dist/utils/scoring.js +76 -0
  216. package/dist/utils/scoring.js.map +1 -0
  217. package/dist/utils/suppression.d.ts +3 -0
  218. package/dist/utils/suppression.d.ts.map +1 -0
  219. package/dist/utils/suppression.js +33 -0
  220. package/dist/utils/suppression.js.map +1 -0
  221. package/package.json +94 -0
@@ -0,0 +1,97 @@
1
+ // OWASP A02:2021 — Cryptographic Failures
2
+ // Rule: Hardcoded credentials, API keys, secrets, or tokens in source code
3
+ export const HardcodedSecrets = {
4
+ id: 'OWASP-A02-002',
5
+ name: 'Hardcoded Secret, API Key, or Credential',
6
+ owasp: 'A02:2021',
7
+ cwe: 'CWE-798',
8
+ severity: 'CRITICAL',
9
+ languages: ['all'],
10
+ description: 'Secrets, API keys, passwords, or tokens hardcoded directly in source code. ' +
11
+ 'These are exposed when code is committed to version control and visible to anyone ' +
12
+ 'with repository access. AI tools routinely hardcode example credentials that end up in production.',
13
+ patterns: [
14
+ {
15
+ // Generic: password = "..." (non-empty, not a variable reference)
16
+ pattern: /(?:password|passwd|pwd|pass)\s*[:=]\s*['"`](?!.*process\.env)[^'"`\s]{6,}['"`]/gi,
17
+ suppressIf: /(?:process\.env|os\.environ|getenv|config\.|settings\.|placeholder|example|changeme|your[_-]?password|<password>|\$\{|f['"])/i,
18
+ snippetLines: 1,
19
+ },
20
+ {
21
+ // Generic: secret = "..."
22
+ pattern: /(?:secret|api_secret|client_secret|app_secret)\s*[:=]\s*['"`](?!.*process\.env)[^'"`\s]{8,}['"`]/gi,
23
+ suppressIf: /(?:process\.env|os\.environ|getenv|config\.|settings\.|placeholder|example|changeme|\$\{|f['"])/i,
24
+ snippetLines: 1,
25
+ },
26
+ {
27
+ // Generic: api_key / apiKey = "..."
28
+ pattern: /(?:api[_-]?key|apikey|access[_-]?key|auth[_-]?key)\s*[:=]\s*['"`](?!.*process\.env)[a-zA-Z0-9_\-]{16,}['"`]/gi,
29
+ suppressIf: /(?:process\.env|os\.environ|getenv|config\.|settings\.|placeholder|example|test|fake|dummy|\$\{)/i,
30
+ snippetLines: 1,
31
+ },
32
+ {
33
+ // AWS Access Key ID pattern: AKIA...
34
+ pattern: /['"`]AKIA[0-9A-Z]{16}['"`]/g,
35
+ snippetLines: 1,
36
+ },
37
+ {
38
+ // AWS Secret Access Key: 40-char base64-like string after aws context
39
+ pattern: /(?:aws_secret_access_key|AWS_SECRET_ACCESS_KEY)\s*[:=]\s*['"`][a-zA-Z0-9+/]{40}['"`]/gi,
40
+ snippetLines: 1,
41
+ },
42
+ {
43
+ // Generic token assignment
44
+ pattern: /(?:token|auth_token|access_token|bearer_token|refresh_token)\s*[:=]\s*['"`](?!.*process\.env)[a-zA-Z0-9._\-]{20,}['"`]/gi,
45
+ suppressIf: /(?:process\.env|os\.environ|getenv|config\.|settings\.|placeholder|example|test|fake|\$\{)/i,
46
+ snippetLines: 1,
47
+ },
48
+ {
49
+ // JWT hardcoded (3-part base64url)
50
+ pattern: /['"`]eyJ[a-zA-Z0-9_\-]{10,}\.eyJ[a-zA-Z0-9_\-]{10,}\.[a-zA-Z0-9_\-]{10,}['"`]/g,
51
+ snippetLines: 1,
52
+ },
53
+ {
54
+ // GitHub PAT
55
+ pattern: /['"`]gh[pousr]_[a-zA-Z0-9]{36,}['"`]/g,
56
+ snippetLines: 1,
57
+ },
58
+ {
59
+ // Private key / certificate header
60
+ pattern: /-----BEGIN\s+(?:RSA\s+)?PRIVATE\s+KEY-----/g,
61
+ snippetLines: 1,
62
+ },
63
+ {
64
+ // Stripe secret key
65
+ pattern: /['"`]sk_(?:live|test)_[a-zA-Z0-9]{24,}['"`]/g,
66
+ snippetLines: 1,
67
+ },
68
+ {
69
+ // Slack token
70
+ pattern: /['"`]xox[bpoa]-[a-zA-Z0-9\-]{10,}['"`]/g,
71
+ snippetLines: 1,
72
+ },
73
+ {
74
+ // SendGrid API key
75
+ pattern: /['"`]SG\.[a-zA-Z0-9_\-]{22}\.[a-zA-Z0-9_\-]{43}['"`]/g,
76
+ snippetLines: 1,
77
+ },
78
+ ],
79
+ fix: 'Never hardcode secrets in source code. Use environment variables or a secrets manager.\n\n' +
80
+ '// Bad:\n' +
81
+ 'const apiKey = "sk_live_abc123...";\n\n' +
82
+ '// Good — Node.js:\n' +
83
+ 'const apiKey = process.env.STRIPE_API_KEY;\n' +
84
+ 'if (!apiKey) throw new Error("STRIPE_API_KEY environment variable is required");\n\n' +
85
+ '// Good — Python:\n' +
86
+ 'import os\n' +
87
+ 'api_key = os.environ["STRIPE_API_KEY"]\n\n' +
88
+ 'Use a .env file locally (add .env to .gitignore) and inject via CI/CD secrets.\n' +
89
+ 'Consider HashiCorp Vault, AWS Secrets Manager, or Doppler for production.',
90
+ references: [
91
+ 'https://owasp.org/Top10/A02_2021-Cryptographic_Failures/',
92
+ 'https://cwe.mitre.org/data/definitions/798.html',
93
+ 'https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html',
94
+ ],
95
+ tags: ['secrets', 'credentials', 'api-key', 'hardcoded', 'crypto'],
96
+ };
97
+ //# sourceMappingURL=hardcoded-secrets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hardcoded-secrets.js","sourceRoot":"","sources":["../../../src/rules/owasp-a02/hardcoded-secrets.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,2EAA2E;AAI3E,MAAM,CAAC,MAAM,gBAAgB,GAAS;IACpC,EAAE,EAAE,eAAe;IACnB,IAAI,EAAE,0CAA0C;IAChD,KAAK,EAAE,UAAU;IACjB,GAAG,EAAE,SAAS;IACd,QAAQ,EAAE,UAAU;IACpB,SAAS,EAAE,CAAC,KAAK,CAAC;IAClB,WAAW,EACT,6EAA6E;QAC7E,oFAAoF;QACpF,oGAAoG;IACtG,QAAQ,EAAE;QACR;YACE,kEAAkE;YAClE,OAAO,EACL,kFAAkF;YACpF,UAAU,EACR,+HAA+H;YACjI,YAAY,EAAE,CAAC;SAChB;QACD;YACE,0BAA0B;YAC1B,OAAO,EACL,oGAAoG;YACtG,UAAU,EACR,kGAAkG;YACpG,YAAY,EAAE,CAAC;SAChB;QACD;YACE,oCAAoC;YACpC,OAAO,EACL,+GAA+G;YACjH,UAAU,EACR,mGAAmG;YACrG,YAAY,EAAE,CAAC;SAChB;QACD;YACE,qCAAqC;YACrC,OAAO,EAAE,6BAA6B;YACtC,YAAY,EAAE,CAAC;SAChB;QACD;YACE,sEAAsE;YACtE,OAAO,EACL,wFAAwF;YAC1F,YAAY,EAAE,CAAC;SAChB;QACD;YACE,2BAA2B;YAC3B,OAAO,EACL,0HAA0H;YAC5H,UAAU,EACR,6FAA6F;YAC/F,YAAY,EAAE,CAAC;SAChB;QACD;YACE,mCAAmC;YACnC,OAAO,EAAE,gFAAgF;YACzF,YAAY,EAAE,CAAC;SAChB;QACD;YACE,aAAa;YACb,OAAO,EAAE,uCAAuC;YAChD,YAAY,EAAE,CAAC;SAChB;QACD;YACE,mCAAmC;YACnC,OAAO,EAAE,6CAA6C;YACtD,YAAY,EAAE,CAAC;SAChB;QACD;YACE,oBAAoB;YACpB,OAAO,EAAE,8CAA8C;YACvD,YAAY,EAAE,CAAC;SAChB;QACD;YACE,cAAc;YACd,OAAO,EAAE,yCAAyC;YAClD,YAAY,EAAE,CAAC;SAChB;QACD;YACE,mBAAmB;YACnB,OAAO,EAAE,uDAAuD;YAChE,YAAY,EAAE,CAAC;SAChB;KACF;IACD,GAAG,EACD,4FAA4F;QAC5F,WAAW;QACX,yCAAyC;QACzC,sBAAsB;QACtB,8CAA8C;QAC9C,sFAAsF;QACtF,qBAAqB;QACrB,aAAa;QACb,4CAA4C;QAC5C,kFAAkF;QAClF,2EAA2E;IAC7E,UAAU,EAAE;QACV,0DAA0D;QAC1D,iDAAiD;QACjD,oFAAoF;KACrF;IACD,IAAI,EAAE,CAAC,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,CAAC;CACnE,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Rule } from '../../types/index.js';
2
+ export declare const InsecureTLS: Rule;
3
+ //# sourceMappingURL=insecure-tls.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"insecure-tls.d.ts","sourceRoot":"","sources":["../../../src/rules/owasp-a02/insecure-tls.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAEjD,eAAO,MAAM,WAAW,EAAE,IA0EzB,CAAC"}
@@ -0,0 +1,75 @@
1
+ // OWASP A02:2021 — Cryptographic Failures
2
+ // Rule: Insecure TLS configuration (disabled cert validation, old protocol versions)
3
+ export const InsecureTLS = {
4
+ id: 'OWASP-A02-004',
5
+ name: 'Insecure TLS / SSL Configuration',
6
+ owasp: 'A02:2021',
7
+ cwe: 'CWE-295',
8
+ severity: 'HIGH',
9
+ languages: ['javascript', 'typescript', 'python', 'java', 'go', 'ruby', 'php'],
10
+ description: 'TLS certificate validation disabled or insecure TLS versions allowed. ' +
11
+ 'Disabling cert verification (rejectUnauthorized: false, verify=False) removes ' +
12
+ 'protection against man-in-the-middle attacks. Commonly added by AI when dealing with self-signed certs.',
13
+ patterns: [
14
+ {
15
+ // Node.js: rejectUnauthorized: false
16
+ pattern: /rejectUnauthorized\s*:\s*false/gi,
17
+ snippetLines: 3,
18
+ },
19
+ {
20
+ // Node.js: NODE_TLS_REJECT_UNAUTHORIZED = 0
21
+ pattern: /NODE_TLS_REJECT_UNAUTHORIZED\s*=\s*['"`]?0['"`]?/gi,
22
+ snippetLines: 3,
23
+ },
24
+ {
25
+ // Python requests: verify=False
26
+ pattern: /requests\s*\.\s*(?:get|post|put|patch|delete|head|options|request)\s*\([^)]*verify\s*=\s*False/gi,
27
+ snippetLines: 3,
28
+ },
29
+ {
30
+ // Python ssl: check_hostname = False
31
+ pattern: /(?:context|ctx|ssl_ctx|ssl_context)\s*\.\s*check_hostname\s*=\s*False/gi,
32
+ snippetLines: 3,
33
+ },
34
+ {
35
+ // Python ssl: verify_mode = ssl.CERT_NONE
36
+ pattern: /verify_mode\s*=\s*ssl\.CERT_NONE/gi,
37
+ snippetLines: 3,
38
+ },
39
+ {
40
+ // Java: TrustAllCerts / X509TrustManager that accepts all
41
+ pattern: /new\s+X509TrustManager\s*\(\s*\)|TrustAllCerts|ALLOW_ALL_HOSTNAME_VERIFIER|setHostnameVerifier\s*\(\s*SSLConnectionSocketFactory\.ALLOW_ALL_HOSTNAME_VERIFIER/gi,
42
+ snippetLines: 3,
43
+ },
44
+ {
45
+ // Go: InsecureSkipVerify: true
46
+ pattern: /InsecureSkipVerify\s*:\s*true/gi,
47
+ snippetLines: 3,
48
+ },
49
+ {
50
+ // Ruby: verify_mode = VERIFY_NONE
51
+ pattern: /verify_mode\s*=\s*OpenSSL::SSL::VERIFY_NONE/gi,
52
+ snippetLines: 3,
53
+ },
54
+ ],
55
+ fix: 'Never disable TLS certificate verification in production.\n\n' +
56
+ '// Node.js — use proper CA bundle:\n' +
57
+ 'import https from "https";\n' +
58
+ 'import fs from "fs";\n' +
59
+ 'const agent = new https.Agent({\n' +
60
+ ' ca: fs.readFileSync("./certs/ca-bundle.crt"), // trust your CA\n' +
61
+ ' // rejectUnauthorized: true (default — do NOT set false)\n' +
62
+ '});\n\n' +
63
+ '// Python — specify CA bundle:\n' +
64
+ 'import requests\n' +
65
+ 'requests.get("https://api.example.com", verify="/path/to/ca-bundle.crt")\n\n' +
66
+ '// For development with self-signed certs: add the cert to your system trust store\n' +
67
+ '// or pass verify="/path/to/self-signed.crt" — never use verify=False.',
68
+ references: [
69
+ 'https://owasp.org/Top10/A02_2021-Cryptographic_Failures/',
70
+ 'https://cwe.mitre.org/data/definitions/295.html',
71
+ 'https://cheatsheetseries.owasp.org/cheatsheets/Transport_Layer_Security_Cheat_Sheet.html',
72
+ ],
73
+ tags: ['tls', 'ssl', 'certificate', 'crypto', 'network'],
74
+ };
75
+ //# sourceMappingURL=insecure-tls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"insecure-tls.js","sourceRoot":"","sources":["../../../src/rules/owasp-a02/insecure-tls.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,qFAAqF;AAIrF,MAAM,CAAC,MAAM,WAAW,GAAS;IAC/B,EAAE,EAAE,eAAe;IACnB,IAAI,EAAE,kCAAkC;IACxC,KAAK,EAAE,UAAU;IACjB,GAAG,EAAE,SAAS;IACd,QAAQ,EAAE,MAAM;IAChB,SAAS,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC;IAC9E,WAAW,EACT,wEAAwE;QACxE,gFAAgF;QAChF,yGAAyG;IAC3G,QAAQ,EAAE;QACR;YACE,qCAAqC;YACrC,OAAO,EAAE,kCAAkC;YAC3C,YAAY,EAAE,CAAC;SAChB;QACD;YACE,4CAA4C;YAC5C,OAAO,EAAE,oDAAoD;YAC7D,YAAY,EAAE,CAAC;SAChB;QACD;YACE,gCAAgC;YAChC,OAAO,EAAE,kGAAkG;YAC3G,YAAY,EAAE,CAAC;SAChB;QACD;YACE,qCAAqC;YACrC,OAAO,EAAE,yEAAyE;YAClF,YAAY,EAAE,CAAC;SAChB;QACD;YACE,0CAA0C;YAC1C,OAAO,EAAE,oCAAoC;YAC7C,YAAY,EAAE,CAAC;SAChB;QACD;YACE,0DAA0D;YAC1D,OAAO,EACL,iKAAiK;YACnK,YAAY,EAAE,CAAC;SAChB;QACD;YACE,+BAA+B;YAC/B,OAAO,EAAE,iCAAiC;YAC1C,YAAY,EAAE,CAAC;SAChB;QACD;YACE,kCAAkC;YAClC,OAAO,EAAE,+CAA+C;YACxD,YAAY,EAAE,CAAC;SAChB;KACF;IACD,GAAG,EACD,+DAA+D;QAC/D,sCAAsC;QACtC,8BAA8B;QAC9B,wBAAwB;QACxB,mCAAmC;QACnC,oEAAoE;QACpE,8DAA8D;QAC9D,SAAS;QACT,kCAAkC;QAClC,mBAAmB;QACnB,8EAA8E;QAC9E,sFAAsF;QACtF,wEAAwE;IAC1E,UAAU,EAAE;QACV,0DAA0D;QAC1D,iDAAiD;QACjD,0FAA0F;KAC3F;IACD,IAAI,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,SAAS,CAAC;CACzD,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Rule } from '../../types/index.js';
2
+ export declare const WeakHash: Rule;
3
+ //# sourceMappingURL=weak-hash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"weak-hash.d.ts","sourceRoot":"","sources":["../../../src/rules/owasp-a02/weak-hash.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAEjD,eAAO,MAAM,QAAQ,EAAE,IAyEtB,CAAC"}
@@ -0,0 +1,73 @@
1
+ // OWASP A02:2021 — Cryptographic Failures
2
+ // Rule: Weak or broken hashing algorithms used for passwords or sensitive data
3
+ export const WeakHash = {
4
+ id: 'OWASP-A02-001',
5
+ name: 'Weak Cryptographic Hash Algorithm',
6
+ owasp: 'A02:2021',
7
+ cwe: 'CWE-327',
8
+ severity: 'HIGH',
9
+ languages: ['javascript', 'typescript', 'python', 'php', 'java', 'ruby', 'go', 'csharp'],
10
+ description: 'MD5 and SHA-1 are cryptographically broken hash functions — they are fast and vulnerable ' +
11
+ 'to collision and preimage attacks. They must never be used for passwords, digital signatures, ' +
12
+ 'or integrity verification. AI assistants frequently suggest md5() or SHA1 for "quick hashing".',
13
+ patterns: [
14
+ {
15
+ // Node.js crypto: createHash('md5') or createHash('sha1')
16
+ pattern: /crypto\s*\.\s*createHash\s*\(\s*['"`]\s*(?:md5|sha1|sha-1|MD5|SHA1|SHA-1)\s*['"`]\s*\)/gi,
17
+ snippetLines: 3,
18
+ },
19
+ {
20
+ // Python hashlib: hashlib.md5() / hashlib.sha1()
21
+ pattern: /hashlib\s*\.\s*(?:md5|sha1)\s*\(/gi,
22
+ snippetLines: 3,
23
+ },
24
+ {
25
+ // PHP: md5() / sha1() — especially with password context
26
+ pattern: /\bmd5\s*\(\s*\$(?:password|passwd|pwd|secret|hash)/gi,
27
+ snippetLines: 3,
28
+ },
29
+ {
30
+ pattern: /\bsha1\s*\(\s*\$(?:password|passwd|pwd|secret|hash)/gi,
31
+ snippetLines: 3,
32
+ },
33
+ {
34
+ // Ruby: Digest::MD5 / Digest::SHA1
35
+ pattern: /Digest\s*::\s*(?:MD5|SHA1)\s*\.\s*(?:hexdigest|digest)/gi,
36
+ snippetLines: 3,
37
+ },
38
+ {
39
+ // Java: MessageDigest.getInstance("MD5") / getInstance("SHA-1")
40
+ pattern: /MessageDigest\s*\.\s*getInstance\s*\(\s*['"`]\s*(?:MD5|SHA-1|SHA1)\s*['"`]\s*\)/gi,
41
+ snippetLines: 3,
42
+ },
43
+ {
44
+ // Go: md5.New() / sha1.New()
45
+ pattern: /(?:md5|sha1)\s*\.\s*New\s*\(\s*\)/gi,
46
+ snippetLines: 3,
47
+ },
48
+ {
49
+ // C#: MD5.Create() / SHA1.Create()
50
+ pattern: /(?:MD5|SHA1)\s*\.\s*Create\s*\(\s*\)/gi,
51
+ snippetLines: 3,
52
+ },
53
+ ],
54
+ fix: 'For passwords: use bcrypt, Argon2id, or scrypt (NOT a general-purpose hash).\n' +
55
+ 'For integrity/checksums: use SHA-256 or SHA-3 at minimum.\n\n' +
56
+ '// Node.js password hashing:\n' +
57
+ 'import bcrypt from "bcrypt";\n' +
58
+ 'const hash = await bcrypt.hash(password, 12); // cost factor >= 10\n\n' +
59
+ '// Node.js data integrity:\n' +
60
+ 'const hash = crypto.createHash("sha256").update(data).digest("hex");\n\n' +
61
+ '// Python password hashing:\n' +
62
+ 'from passlib.hash import argon2\n' +
63
+ 'hash = argon2.hash(password)\n\n' +
64
+ '// PHP:\n' +
65
+ '$hash = password_hash($password, PASSWORD_ARGON2ID);',
66
+ references: [
67
+ 'https://owasp.org/Top10/A02_2021-Cryptographic_Failures/',
68
+ 'https://cwe.mitre.org/data/definitions/327.html',
69
+ 'https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html',
70
+ ],
71
+ tags: ['crypto', 'hashing', 'password', 'md5', 'sha1'],
72
+ };
73
+ //# sourceMappingURL=weak-hash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"weak-hash.js","sourceRoot":"","sources":["../../../src/rules/owasp-a02/weak-hash.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,+EAA+E;AAI/E,MAAM,CAAC,MAAM,QAAQ,GAAS;IAC5B,EAAE,EAAE,eAAe;IACnB,IAAI,EAAE,mCAAmC;IACzC,KAAK,EAAE,UAAU;IACjB,GAAG,EAAE,SAAS;IACd,QAAQ,EAAE,MAAM;IAChB,SAAS,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC;IACxF,WAAW,EACT,2FAA2F;QAC3F,gGAAgG;QAChG,gGAAgG;IAClG,QAAQ,EAAE;QACR;YACE,0DAA0D;YAC1D,OAAO,EACL,0FAA0F;YAC5F,YAAY,EAAE,CAAC;SAChB;QACD;YACE,iDAAiD;YACjD,OAAO,EAAE,oCAAoC;YAC7C,YAAY,EAAE,CAAC;SAChB;QACD;YACE,yDAAyD;YACzD,OAAO,EAAE,sDAAsD;YAC/D,YAAY,EAAE,CAAC;SAChB;QACD;YACE,OAAO,EAAE,uDAAuD;YAChE,YAAY,EAAE,CAAC;SAChB;QACD;YACE,mCAAmC;YACnC,OAAO,EAAE,0DAA0D;YACnE,YAAY,EAAE,CAAC;SAChB;QACD;YACE,gEAAgE;YAChE,OAAO,EACL,mFAAmF;YACrF,YAAY,EAAE,CAAC;SAChB;QACD;YACE,6BAA6B;YAC7B,OAAO,EAAE,qCAAqC;YAC9C,YAAY,EAAE,CAAC;SAChB;QACD;YACE,mCAAmC;YACnC,OAAO,EAAE,wCAAwC;YACjD,YAAY,EAAE,CAAC;SAChB;KACF;IACD,GAAG,EACD,gFAAgF;QAChF,+DAA+D;QAC/D,gCAAgC;QAChC,gCAAgC;QAChC,wEAAwE;QACxE,8BAA8B;QAC9B,0EAA0E;QAC1E,+BAA+B;QAC/B,mCAAmC;QACnC,kCAAkC;QAClC,WAAW;QACX,sDAAsD;IACxD,UAAU,EAAE;QACV,0DAA0D;QAC1D,iDAAiD;QACjD,kFAAkF;KACnF;IACD,IAAI,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,CAAC;CACvD,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Rule } from '../../types/index.js';
2
+ export declare const WeakRandom: Rule;
3
+ //# sourceMappingURL=weak-random.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"weak-random.d.ts","sourceRoot":"","sources":["../../../src/rules/owasp-a02/weak-random.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAEjD,eAAO,MAAM,UAAU,EAAE,IAyExB,CAAC"}
@@ -0,0 +1,70 @@
1
+ // OWASP A02:2021 — Cryptographic Failures
2
+ // Rule: Cryptographically weak random number generator used for security-sensitive context
3
+ export const WeakRandom = {
4
+ id: 'OWASP-A02-003',
5
+ name: 'Cryptographically Weak Random Number Generator',
6
+ owasp: 'A02:2021',
7
+ cwe: 'CWE-338',
8
+ severity: 'HIGH',
9
+ languages: ['javascript', 'typescript', 'python', 'php', 'java', 'ruby'],
10
+ description: 'Math.random() (JS) and random.random() (Python) are NOT cryptographically secure — ' +
11
+ 'their output is predictable. Using them to generate tokens, passwords, OTPs, CSRF tokens, ' +
12
+ 'session IDs, or nonces creates guessable values that attackers can brute-force.',
13
+ patterns: [
14
+ {
15
+ // JS: Math.random() near token/password/secret/nonce context
16
+ pattern: /Math\s*\.\s*random\s*\(\s*\)/gi,
17
+ requiresContext: /(?:token|password|secret|nonce|salt|otp|csrf|session|id|key|pin|code|random|generate|uuid|hex|bytes)/i,
18
+ snippetLines: 3,
19
+ },
20
+ {
21
+ // Python: random.random() / random.randint() / random.choice()
22
+ pattern: /\brandom\s*\.\s*(?:random|randint|choice|randrange|shuffle|sample)\s*\(/gi,
23
+ requiresContext: /(?:token|password|secret|nonce|salt|otp|csrf|session|key|pin|code)/i,
24
+ suppressIf: /secrets\s*\.|os\.urandom/i,
25
+ snippetLines: 3,
26
+ },
27
+ {
28
+ // PHP: rand() / mt_rand()
29
+ pattern: /\b(?:rand|mt_rand)\s*\(/gi,
30
+ requiresContext: /(?:token|password|secret|nonce|salt|otp|csrf|session|key|pin|code)/i,
31
+ snippetLines: 3,
32
+ },
33
+ {
34
+ // Java: new Random() — not SecureRandom
35
+ pattern: /new\s+Random\s*\(\s*\)/g,
36
+ requiresContext: /(?:token|password|secret|nonce|salt|otp|csrf|session|key|pin|code)/i,
37
+ suppressIf: /SecureRandom/i,
38
+ snippetLines: 3,
39
+ },
40
+ {
41
+ // Ruby: rand() in security context
42
+ pattern: /\brand\s*\(/gi,
43
+ requiresContext: /(?:token|password|secret|nonce|salt|otp|csrf|session|key|pin|code)/i,
44
+ suppressIf: /SecureRandom/i,
45
+ snippetLines: 3,
46
+ },
47
+ ],
48
+ fix: 'Use a cryptographically secure random number generator (CSPRNG) for all security-sensitive values.\n\n' +
49
+ '// Node.js — generate a secure token:\n' +
50
+ 'import crypto from "crypto";\n' +
51
+ 'const token = crypto.randomBytes(32).toString("hex"); // 256-bit secure token\n' +
52
+ 'const uuid = crypto.randomUUID(); // cryptographically secure UUID\n\n' +
53
+ '// Python:\n' +
54
+ 'import secrets\n' +
55
+ 'token = secrets.token_hex(32) # 64-char hex token\n' +
56
+ 'otp = secrets.randbelow(1000000) # 6-digit OTP\n\n' +
57
+ '// PHP:\n' +
58
+ '$token = bin2hex(random_bytes(32)); // uses CSPRNG\n\n' +
59
+ '// Java:\n' +
60
+ 'SecureRandom sr = new SecureRandom();\n' +
61
+ 'byte[] token = new byte[32];\n' +
62
+ 'sr.nextBytes(token);',
63
+ references: [
64
+ 'https://owasp.org/Top10/A02_2021-Cryptographic_Failures/',
65
+ 'https://cwe.mitre.org/data/definitions/338.html',
66
+ 'https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html',
67
+ ],
68
+ tags: ['crypto', 'random', 'token-generation', 'prng'],
69
+ };
70
+ //# sourceMappingURL=weak-random.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"weak-random.js","sourceRoot":"","sources":["../../../src/rules/owasp-a02/weak-random.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,2FAA2F;AAI3F,MAAM,CAAC,MAAM,UAAU,GAAS;IAC9B,EAAE,EAAE,eAAe;IACnB,IAAI,EAAE,gDAAgD;IACtD,KAAK,EAAE,UAAU;IACjB,GAAG,EAAE,SAAS;IACd,QAAQ,EAAE,MAAM;IAChB,SAAS,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC;IACxE,WAAW,EACT,qFAAqF;QACrF,4FAA4F;QAC5F,iFAAiF;IACnF,QAAQ,EAAE;QACR;YACE,6DAA6D;YAC7D,OAAO,EAAE,gCAAgC;YACzC,eAAe,EACb,uGAAuG;YACzG,YAAY,EAAE,CAAC;SAChB;QACD;YACE,+DAA+D;YAC/D,OAAO,EAAE,2EAA2E;YACpF,eAAe,EACb,qEAAqE;YACvE,UAAU,EAAE,2BAA2B;YACvC,YAAY,EAAE,CAAC;SAChB;QACD;YACE,0BAA0B;YAC1B,OAAO,EAAE,2BAA2B;YACpC,eAAe,EACb,qEAAqE;YACvE,YAAY,EAAE,CAAC;SAChB;QACD;YACE,wCAAwC;YACxC,OAAO,EAAE,yBAAyB;YAClC,eAAe,EACb,qEAAqE;YACvE,UAAU,EAAE,eAAe;YAC3B,YAAY,EAAE,CAAC;SAChB;QACD;YACE,mCAAmC;YACnC,OAAO,EAAE,eAAe;YACxB,eAAe,EACb,qEAAqE;YACvE,UAAU,EAAE,eAAe;YAC3B,YAAY,EAAE,CAAC;SAChB;KACF;IACD,GAAG,EACD,wGAAwG;QACxG,yCAAyC;QACzC,gCAAgC;QAChC,iFAAiF;QACjF,wEAAwE;QACxE,cAAc;QACd,kBAAkB;QAClB,sDAAsD;QACtD,qDAAqD;QACrD,WAAW;QACX,wDAAwD;QACxD,YAAY;QACZ,yCAAyC;QACzC,gCAAgC;QAChC,sBAAsB;IACxB,UAAU,EAAE;QACV,0DAA0D;QAC1D,iDAAiD;QACjD,uFAAuF;KACxF;IACD,IAAI,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,CAAC;CACvD,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Rule } from '../../types/index.js';
2
+ export declare const CommandInjection: Rule;
3
+ //# sourceMappingURL=command-injection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-injection.d.ts","sourceRoot":"","sources":["../../../src/rules/owasp-a03/command-injection.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAEjD,eAAO,MAAM,gBAAgB,EAAE,IAsF9B,CAAC"}
@@ -0,0 +1,79 @@
1
+ // OWASP A03:2021 — Injection
2
+ // Rule: OS Command Injection via user-controlled input
3
+ export const CommandInjection = {
4
+ id: 'OWASP-A03-002',
5
+ name: 'OS Command Injection via User-Controlled Input',
6
+ owasp: 'A03:2021',
7
+ cwe: 'CWE-78',
8
+ severity: 'CRITICAL',
9
+ languages: ['javascript', 'typescript', 'python', 'php', 'ruby', 'go', 'java'],
10
+ description: 'Shell commands constructed using unsanitized user input allow attackers to execute ' +
11
+ 'arbitrary system commands. A single semicolon or pipe character can break out of the ' +
12
+ 'intended command. AI tools often reach for exec() when a safer API exists.',
13
+ patterns: [
14
+ {
15
+ // Node.js: exec/execSync with user input via string concat
16
+ pattern: /(?:exec|execSync)\s*\(\s*(?:['"`][^'"`]*['"`]\s*\+|`[^`]*\$\{[^}]*(?:req\.|request\.|params\.|query\.|body\.))/gi,
17
+ snippetLines: 3,
18
+ },
19
+ {
20
+ // Node.js: exec/execSync with req.* directly
21
+ pattern: /(?:exec|execSync)\s*\([^)]*(?:req\.|request\.)(?:body|params|query|headers)/gi,
22
+ snippetLines: 3,
23
+ },
24
+ {
25
+ // Node.js: child_process.exec/spawn with user input
26
+ pattern: /child_process\s*\.\s*(?:exec|execSync|spawn|spawnSync)\s*\([^)]*(?:req\.|request\.)/gi,
27
+ snippetLines: 3,
28
+ },
29
+ {
30
+ // Python: os.system / os.popen with user input or f-string interpolation
31
+ pattern: /os\s*\.\s*(?:system|popen|execv?p?e?)\s*\(\s*(?:f['"`]|['"`][^'"`]*['"`]\s*%|(?:request\.|req\.)(?:args|form|json|data|params))/gi,
32
+ snippetLines: 3,
33
+ },
34
+ {
35
+ // Python: subprocess.call/run/Popen with shell=True + user input
36
+ pattern: /subprocess\s*\.\s*(?:call|run|Popen|check_output|check_call)\s*\([^)]*(?:request\.|req\.)(?:args|form|json|data)/gi,
37
+ snippetLines: 3,
38
+ },
39
+ {
40
+ // Python: subprocess with shell=True (always risky with dynamic args)
41
+ pattern: /subprocess\s*\.\s*(?:call|run|Popen)\s*\([^)]*shell\s*=\s*True[^)]*(?:request\.|req\.)/gi,
42
+ snippetLines: 3,
43
+ },
44
+ {
45
+ // PHP: exec/system/shell_exec/passthru with $_GET/$_POST
46
+ pattern: /(?:\bexec\b|system|shell_exec|passthru|popen)\s*\([^)]*\$_(?:GET|POST|REQUEST|SERVER)/gi,
47
+ snippetLines: 3,
48
+ },
49
+ {
50
+ // Ruby: backtick execution / system with user input
51
+ pattern: /(?:system|exec|IO\.popen|Open3\.popen)\s*\([^)]*(?:params|request\.)/gi,
52
+ snippetLines: 3,
53
+ },
54
+ {
55
+ // Go: exec.Command with user-provided args directly
56
+ pattern: /exec\s*\.\s*Command\s*\([^)]*(?:r\.(?:URL\.Query|FormValue|PostForm)|req\.)/gi,
57
+ snippetLines: 3,
58
+ },
59
+ ],
60
+ fix: 'Avoid shell commands when possible. Use language-native APIs.\n' +
61
+ 'If shell is necessary, use argument arrays (never strings) and whitelist inputs.\n\n' +
62
+ '// Node.js — BAD:\n' +
63
+ 'exec(`convert ${req.body.file} output.pdf`);\n\n' +
64
+ '// Node.js — GOOD (use spawn with arg array, no shell):\n' +
65
+ 'import { spawn } from "child_process";\n' +
66
+ 'const safe = spawn("convert", [req.body.file, "output.pdf"], { shell: false });\n\n' +
67
+ '// Python — GOOD (list of args, shell=False):\n' +
68
+ 'import subprocess\n' +
69
+ 'subprocess.run(["convert", user_file, "output.pdf"], shell=False, check=True)\n\n' +
70
+ '// Validate and whitelist input before use:\n' +
71
+ 'if (!/^[a-zA-Z0-9._-]+$/.test(filename)) throw new Error("Invalid filename");',
72
+ references: [
73
+ 'https://owasp.org/Top10/A03_2021-Injection/',
74
+ 'https://cwe.mitre.org/data/definitions/78.html',
75
+ 'https://cheatsheetseries.owasp.org/cheatsheets/OS_Command_Injection_Defense_Cheat_Sheet.html',
76
+ ],
77
+ tags: ['injection', 'command-injection', 'rce', 'shell', 'os'],
78
+ };
79
+ //# sourceMappingURL=command-injection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-injection.js","sourceRoot":"","sources":["../../../src/rules/owasp-a03/command-injection.ts"],"names":[],"mappings":"AAAA,6BAA6B;AAC7B,uDAAuD;AAIvD,MAAM,CAAC,MAAM,gBAAgB,GAAS;IACpC,EAAE,EAAE,eAAe;IACnB,IAAI,EAAE,gDAAgD;IACtD,KAAK,EAAE,UAAU;IACjB,GAAG,EAAE,QAAQ;IACb,QAAQ,EAAE,UAAU;IACpB,SAAS,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC;IAC9E,WAAW,EACT,qFAAqF;QACrF,uFAAuF;QACvF,4EAA4E;IAC9E,QAAQ,EAAE;QACR;YACE,2DAA2D;YAC3D,OAAO,EACL,kHAAkH;YACpH,YAAY,EAAE,CAAC;SAChB;QACD;YACE,6CAA6C;YAC7C,OAAO,EACL,+EAA+E;YACjF,YAAY,EAAE,CAAC;SAChB;QACD;YACE,oDAAoD;YACpD,OAAO,EACL,uFAAuF;YACzF,YAAY,EAAE,CAAC;SAChB;QACD;YACE,yEAAyE;YACzE,OAAO,EACL,mIAAmI;YACrI,YAAY,EAAE,CAAC;SAChB;QACD;YACE,iEAAiE;YACjE,OAAO,EACL,oHAAoH;YACtH,YAAY,EAAE,CAAC;SAChB;QACD;YACE,sEAAsE;YACtE,OAAO,EACL,0FAA0F;YAC5F,YAAY,EAAE,CAAC;SAChB;QACD;YACE,yDAAyD;YACzD,OAAO,EACL,yFAAyF;YAC3F,YAAY,EAAE,CAAC;SAChB;QACD;YACE,oDAAoD;YACpD,OAAO,EACL,wEAAwE;YAC1E,YAAY,EAAE,CAAC;SAChB;QACD;YACE,oDAAoD;YACpD,OAAO,EACL,+EAA+E;YACjF,YAAY,EAAE,CAAC;SAChB;KACF;IACD,GAAG,EACD,iEAAiE;QACjE,sFAAsF;QACtF,qBAAqB;QACrB,kDAAkD;QAClD,2DAA2D;QAC3D,0CAA0C;QAC1C,qFAAqF;QACrF,iDAAiD;QACjD,qBAAqB;QACrB,mFAAmF;QACnF,+CAA+C;QAC/C,+EAA+E;IACjF,UAAU,EAAE;QACV,6CAA6C;QAC7C,gDAAgD;QAChD,8FAA8F;KAC/F;IACD,IAAI,EAAE,CAAC,WAAW,EAAE,mBAAmB,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC;CAC/D,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Rule } from '../../types/index.js';
2
+ export declare const LdapInjection: Rule;
3
+ //# sourceMappingURL=ldap-injection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ldap-injection.d.ts","sourceRoot":"","sources":["../../../src/rules/owasp-a03/ldap-injection.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAEjD,eAAO,MAAM,aAAa,EAAE,IA0D3B,CAAC"}
@@ -0,0 +1,56 @@
1
+ // OWASP A03:2021 — Injection
2
+ // Rule: LDAP Injection via unsanitized user input
3
+ export const LdapInjection = {
4
+ id: 'OWASP-A03-006',
5
+ name: 'LDAP Injection via Unsanitized User Input',
6
+ owasp: 'A03:2021',
7
+ cwe: 'CWE-90',
8
+ severity: 'HIGH',
9
+ languages: ['javascript', 'typescript', 'python', 'java', 'php'],
10
+ description: 'LDAP queries constructed with unescaped user input allow attackers to manipulate ' +
11
+ 'directory queries, bypass authentication, or enumerate LDAP directory information. ' +
12
+ 'Special characters like *, (, ), \\, NUL have meaning in LDAP filter syntax.',
13
+ patterns: [
14
+ {
15
+ // Node.js ldapjs: search/bind with user input in filter string
16
+ pattern: /(?:ldap|client)\s*\.\s*(?:search|bind|compare|modify|add|del)\s*\([^)]*(?:req\.|request\.)(?:body|params|query)/gi,
17
+ snippetLines: 3,
18
+ },
19
+ {
20
+ // LDAP filter string with user input concatenation
21
+ pattern: /['"`]\s*(?:\(&|\(\||\(!)?\s*\(\s*\w+\s*=\s*['"`]\s*\+\s*(?:req\.|request\.)/gi,
22
+ snippetLines: 3,
23
+ },
24
+ {
25
+ // Python python-ldap: search_s with user input
26
+ pattern: /(?:conn|ldap_conn|lc)\s*\.\s*search_s\s*\([^)]*(?:request\.|req\.)(?:args|form|json|data)/gi,
27
+ snippetLines: 3,
28
+ },
29
+ {
30
+ // Java: NamingEnumeration with DirContext.search() + user input
31
+ pattern: /ctx\s*\.\s*search\s*\([^)]*\+\s*(?:request\.|req\.|username|input|filter)/gi,
32
+ snippetLines: 3,
33
+ },
34
+ ],
35
+ fix: 'Escape all special LDAP characters in user input before using in filters.\n\n' +
36
+ '// Node.js — use ldapjs escaping:\n' +
37
+ 'import { Client } from "ldapts";\n' +
38
+ '// Whitelist: only allow alphanumeric usernames\n' +
39
+ 'if (!/^[a-zA-Z0-9@._-]{1,64}$/.test(username)) {\n' +
40
+ ' throw new Error("Invalid username format");\n' +
41
+ '}\n' +
42
+ 'const result = await client.search(baseDN, {\n' +
43
+ ' filter: `(uid=${username})`, // now safe after whitelist validation\n' +
44
+ '});\n\n' +
45
+ '// Python — use ldap3 with proper escaping:\n' +
46
+ 'from ldap3.utils.conv import escape_filter_chars\n' +
47
+ 'safe_user = escape_filter_chars(username)\n' +
48
+ 'conn.search(base_dn, f"(uid={safe_user})")',
49
+ references: [
50
+ 'https://owasp.org/Top10/A03_2021-Injection/',
51
+ 'https://cwe.mitre.org/data/definitions/90.html',
52
+ 'https://cheatsheetseries.owasp.org/cheatsheets/LDAP_Injection_Prevention_Cheat_Sheet.html',
53
+ ],
54
+ tags: ['injection', 'ldap', 'directory'],
55
+ };
56
+ //# sourceMappingURL=ldap-injection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ldap-injection.js","sourceRoot":"","sources":["../../../src/rules/owasp-a03/ldap-injection.ts"],"names":[],"mappings":"AAAA,6BAA6B;AAC7B,kDAAkD;AAIlD,MAAM,CAAC,MAAM,aAAa,GAAS;IACjC,EAAE,EAAE,eAAe;IACnB,IAAI,EAAE,2CAA2C;IACjD,KAAK,EAAE,UAAU;IACjB,GAAG,EAAE,QAAQ;IACb,QAAQ,EAAE,MAAM;IAChB,SAAS,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC;IAChE,WAAW,EACT,mFAAmF;QACnF,qFAAqF;QACrF,8EAA8E;IAChF,QAAQ,EAAE;QACR;YACE,+DAA+D;YAC/D,OAAO,EACL,mHAAmH;YACrH,YAAY,EAAE,CAAC;SAChB;QACD;YACE,mDAAmD;YACnD,OAAO,EACL,+EAA+E;YACjF,YAAY,EAAE,CAAC;SAChB;QACD;YACE,+CAA+C;YAC/C,OAAO,EACL,6FAA6F;YAC/F,YAAY,EAAE,CAAC;SAChB;QACD;YACE,gEAAgE;YAChE,OAAO,EACL,6EAA6E;YAC/E,YAAY,EAAE,CAAC;SAChB;KACF;IACD,GAAG,EACD,+EAA+E;QAC/E,qCAAqC;QACrC,oCAAoC;QACpC,mDAAmD;QACnD,oDAAoD;QACpD,iDAAiD;QACjD,KAAK;QACL,gDAAgD;QAChD,yEAAyE;QACzE,SAAS;QACT,+CAA+C;QAC/C,oDAAoD;QACpD,6CAA6C;QAC7C,4CAA4C;IAC9C,UAAU,EAAE;QACV,6CAA6C;QAC7C,gDAAgD;QAChD,2FAA2F;KAC5F;IACD,IAAI,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,CAAC;CACzC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Rule } from '../../types/index.js';
2
+ export declare const NoSqlInjection: Rule;
3
+ //# sourceMappingURL=nosql-injection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nosql-injection.d.ts","sourceRoot":"","sources":["../../../src/rules/owasp-a03/nosql-injection.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAEjD,eAAO,MAAM,cAAc,EAAE,IA8D5B,CAAC"}
@@ -0,0 +1,61 @@
1
+ // OWASP A03:2021 — Injection
2
+ // Rule: NoSQL Injection (MongoDB operator injection)
3
+ export const NoSqlInjection = {
4
+ id: 'OWASP-A03-003',
5
+ name: 'NoSQL Injection via Unsanitized Query Operator',
6
+ owasp: 'A03:2021',
7
+ cwe: 'CWE-943',
8
+ severity: 'CRITICAL',
9
+ languages: ['javascript', 'typescript', 'python'],
10
+ description: 'MongoDB and other NoSQL databases support special query operators ($where, $gt, $ne, $regex). ' +
11
+ 'When user input is passed directly as a query object, attackers can inject operators to bypass ' +
12
+ 'authentication or exfiltrate data. A classic example: { password: { $ne: null } } bypasses login.',
13
+ patterns: [
14
+ {
15
+ // Mongoose/MongoDB: find/findOne with req.body spread or direct assignment
16
+ pattern: /(?:find|findOne|findMany|findById|updateOne|updateMany|deleteOne|deleteMany)\s*\(\s*(?:req\.body|request\.body|req\.query|request\.query)\s*(?:\)|,)/gi,
17
+ snippetLines: 3,
18
+ },
19
+ {
20
+ // Spreading req.body into a Mongoose query
21
+ pattern: /(?:find|findOne|findMany)\s*\(\s*\{\s*\.\.\.\s*(?:req\.body|request\.body)/gi,
22
+ snippetLines: 3,
23
+ },
24
+ {
25
+ // Python PyMongo: collection.find(request.json)
26
+ pattern: /collection\s*\.\s*(?:find|find_one|update_one|update_many|delete_one|delete_many|count_documents)\s*\(\s*(?:request\.json|request\.get_json|data|body)\s*(?:\)|,)/gi,
27
+ snippetLines: 3,
28
+ },
29
+ {
30
+ // $where operator usage (always dangerous — executes JS server-side)
31
+ pattern: /['"`]\$where['"`]\s*:/gi,
32
+ snippetLines: 3,
33
+ },
34
+ {
35
+ // mapReduce — can execute arbitrary JS server-side
36
+ pattern: /\.\s*mapReduce\s*\(/gi,
37
+ requiresContext: /(?:req\.|request\.|input|user|body|query)/i,
38
+ snippetLines: 3,
39
+ },
40
+ ],
41
+ fix: 'Never pass raw request body/query objects to MongoDB queries.\n' +
42
+ 'Explicitly extract and validate each field.\n\n' +
43
+ '// BAD — susceptible to operator injection:\n' +
44
+ 'const user = await User.findOne(req.body); // body could be { "$ne": null }\n\n' +
45
+ '// GOOD — explicit field extraction:\n' +
46
+ 'const { username, password } = req.body;\n' +
47
+ 'if (typeof username !== "string" || typeof password !== "string") {\n' +
48
+ ' return res.status(400).json({ error: "Invalid input" });\n' +
49
+ '}\n' +
50
+ 'const user = await User.findOne({ username }); // exact match\n\n' +
51
+ '// Additional protection: use mongoose-sanitize or express-mongo-sanitize:\n' +
52
+ 'import mongoSanitize from "express-mongo-sanitize";\n' +
53
+ 'app.use(mongoSanitize()); // strips $ and . from keys',
54
+ references: [
55
+ 'https://owasp.org/Top10/A03_2021-Injection/',
56
+ 'https://cwe.mitre.org/data/definitions/943.html',
57
+ 'https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/07-Input_Validation_Testing/05.6-Testing_for_NoSQL_Injection',
58
+ ],
59
+ tags: ['injection', 'nosql', 'mongodb', 'database'],
60
+ };
61
+ //# sourceMappingURL=nosql-injection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nosql-injection.js","sourceRoot":"","sources":["../../../src/rules/owasp-a03/nosql-injection.ts"],"names":[],"mappings":"AAAA,6BAA6B;AAC7B,qDAAqD;AAIrD,MAAM,CAAC,MAAM,cAAc,GAAS;IAClC,EAAE,EAAE,eAAe;IACnB,IAAI,EAAE,gDAAgD;IACtD,KAAK,EAAE,UAAU;IACjB,GAAG,EAAE,SAAS;IACd,QAAQ,EAAE,UAAU;IACpB,SAAS,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,QAAQ,CAAC;IACjD,WAAW,EACT,gGAAgG;QAChG,iGAAiG;QACjG,mGAAmG;IACrG,QAAQ,EAAE;QACR;YACE,2EAA2E;YAC3E,OAAO,EACL,wJAAwJ;YAC1J,YAAY,EAAE,CAAC;SAChB;QACD;YACE,2CAA2C;YAC3C,OAAO,EACL,8EAA8E;YAChF,YAAY,EAAE,CAAC;SAChB;QACD;YACE,gDAAgD;YAChD,OAAO,EACL,qKAAqK;YACvK,YAAY,EAAE,CAAC;SAChB;QACD;YACE,qEAAqE;YACrE,OAAO,EAAE,yBAAyB;YAClC,YAAY,EAAE,CAAC;SAChB;QACD;YACE,mDAAmD;YACnD,OAAO,EAAE,uBAAuB;YAChC,eAAe,EAAE,4CAA4C;YAC7D,YAAY,EAAE,CAAC;SAChB;KACF;IACD,GAAG,EACD,iEAAiE;QACjE,iDAAiD;QACjD,+CAA+C;QAC/C,iFAAiF;QACjF,wCAAwC;QACxC,4CAA4C;QAC5C,uEAAuE;QACvE,8DAA8D;QAC9D,KAAK;QACL,mEAAmE;QACnE,8EAA8E;QAC9E,uDAAuD;QACvD,uDAAuD;IACzD,UAAU,EAAE;QACV,6CAA6C;QAC7C,iDAAiD;QACjD,iKAAiK;KAClK;IACD,IAAI,EAAE,CAAC,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,CAAC;CACpD,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Rule } from '../../types/index.js';
2
+ export declare const SqlInjection: Rule;
3
+ //# sourceMappingURL=sql-injection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql-injection.d.ts","sourceRoot":"","sources":["../../../src/rules/owasp-a03/sql-injection.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAEjD,eAAO,MAAM,YAAY,EAAE,IA+F1B,CAAC"}