@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,580 @@
1
+ // ============================================================
2
+ // AST Queries — structural sink/source detection + AST-based taint
3
+ //
4
+ // Two detection modes:
5
+ //
6
+ // 1. Direct detection: user input appears directly in a sink arg
7
+ // `db.query("SELECT..." + req.query.id)`
8
+ // `exec(\`ping ${req.query.host}\`)`
9
+ //
10
+ // 2. AST taint propagation: user input assigned to variable, used in sink
11
+ // `const userId = req.query.id;` ← source node: variable_declarator
12
+ // `const query = "SELECT..." + userId;` ← propagation: binary_expression
13
+ // `db.query(query);` ← sink arg is a tainted identifier
14
+ //
15
+ // Both use tree-sitter AST nodes — no regex string matching for variable tracking.
16
+ // This eliminates false positives from comment lines and string contents.
17
+ // ============================================================
18
+ import { findAllNodes } from './ast-parser.js';
19
+ // ---- Source patterns ----
20
+ // These match the TEXT of AST nodes that represent user-controlled input.
21
+ const JS_SOURCE_RE = /\breq(?:uest)?\.(?:query|body|params)\b|\bevent\.target\.value\b|\bprocess\.argv\b|\blocalStorage\.getItem\b|\bsessionStorage\.getItem\b|\bsearchParams\.get\b/;
22
+ const PY_SOURCE_RE = /\brequest\.(?:args|form|json|values|data|files)\b|\brequest\.(?:GET|POST|body)\b|\binput\s*\(|\bsys\.argv\b/;
23
+ function hasUserInput(node, language) {
24
+ const re = language === 'python' ? PY_SOURCE_RE : JS_SOURCE_RE;
25
+ return re.test(node.text);
26
+ }
27
+ // ---- Cross-file taint source collection ----
28
+ /**
29
+ * Scan a single file's AST and collect the names of exported functions/variables
30
+ * whose bodies contain direct user-input sources.
31
+ *
32
+ * Used for cross-file taint tracking: if file A exports `getUserId(req)` which
33
+ * reads `req.query.id`, and file B calls `getUserId(req)`, the return value in
34
+ * file B should be treated as tainted.
35
+ */
36
+ export function collectExportedTaintSources(rootNode, language) {
37
+ const sources = new Map();
38
+ for (const exportStmt of findAllNodes(rootNode, 'export_statement')) {
39
+ // export function NAME(req, ...) { ... req.query ... }
40
+ for (const funcDecl of findAllNodes(exportStmt, 'function_declaration')) {
41
+ const nameNode = funcDecl.childForFieldName('name');
42
+ const bodyNode = funcDecl.childForFieldName('body');
43
+ if (nameNode && bodyNode && hasUserInput(bodyNode, language)) {
44
+ sources.set(nameNode.text, `exported fn '${nameNode.text}' reads user input`);
45
+ }
46
+ }
47
+ // export const NAME = (req) => req.body.x OR export const NAME = function(req) { ... }
48
+ for (const varDecl of findAllNodes(exportStmt, 'variable_declarator')) {
49
+ const nameNode = varDecl.childForFieldName('name');
50
+ const valueNode = varDecl.childForFieldName('value');
51
+ if (!nameNode || !valueNode || nameNode.type !== 'identifier')
52
+ continue;
53
+ if ((valueNode.type === 'arrow_function' || valueNode.type === 'function') &&
54
+ hasUserInput(valueNode, language)) {
55
+ sources.set(nameNode.text, `exported arrow fn '${nameNode.text}' reads user input`);
56
+ }
57
+ }
58
+ }
59
+ // Also: module.exports.NAME = function(req) { ... } (CommonJS)
60
+ for (const assign of findAllNodes(rootNode, 'assignment_expression')) {
61
+ const left = assign.childForFieldName('left');
62
+ const right = assign.childForFieldName('right');
63
+ if (!left || !right)
64
+ continue;
65
+ // left must be `module.exports.NAME` or `exports.NAME`
66
+ if (left.type !== 'member_expression')
67
+ continue;
68
+ const leftText = left.text;
69
+ if (!/\b(?:module\.exports|exports)\.\w+/.test(leftText))
70
+ continue;
71
+ const propName = left.childForFieldName('property')?.text;
72
+ if (!propName)
73
+ continue;
74
+ if ((right.type === 'function' || right.type === 'arrow_function') &&
75
+ hasUserInput(right, language)) {
76
+ sources.set(propName, `module.exports.${propName} reads user input`);
77
+ }
78
+ }
79
+ return sources;
80
+ }
81
+ /**
82
+ * Walk all variable declarations and assignments in the AST.
83
+ * When the right-hand side is/contains a user input source, mark the
84
+ * left-hand variable name(s) as tainted.
85
+ *
86
+ * crossFileSources: optional map of function names from other files that return
87
+ * tainted data (built by collectExportedTaintSources in the pre-pass).
88
+ *
89
+ * Returns the initial (un-propagated) taint map.
90
+ */
91
+ export function buildInitialTaintMap(rootNode, language, crossFileSources) {
92
+ const tainted = new Map();
93
+ if (language === 'javascript' || language === 'typescript') {
94
+ // --- variable_declarator: `const/let/var NAME = VALUE` ---
95
+ for (const decl of findAllNodes(rootNode, 'variable_declarator')) {
96
+ const nameNode = decl.childForFieldName('name');
97
+ const valueNode = decl.childForFieldName('value');
98
+ if (!nameNode || !valueNode)
99
+ continue;
100
+ // Cross-file taint must be checked BEFORE the hasUserInput guard,
101
+ // because `getUserId(req)` doesn't contain req.query directly.
102
+ if (crossFileSources && nameNode.type === 'identifier' && valueNode.type === 'call_expression') {
103
+ const callFuncNode = valueNode.childForFieldName('function');
104
+ if (callFuncNode) {
105
+ const calleeName = callFuncNode.type === 'member_expression'
106
+ ? (callFuncNode.childForFieldName('property')?.text ?? '')
107
+ : callFuncNode.text;
108
+ if (crossFileSources.has(calleeName)) {
109
+ tainted.set(nameNode.text, `return value of cross-file fn '${calleeName}' (${crossFileSources.get(calleeName)})`);
110
+ continue;
111
+ }
112
+ }
113
+ }
114
+ if (!hasUserInput(valueNode, language))
115
+ continue;
116
+ // Simple identifier: const userId = req.query.id
117
+ if (nameNode.type === 'identifier') {
118
+ tainted.set(nameNode.text, `assigned from ${valueNode.text.slice(0, 60)}`);
119
+ }
120
+ // Destructuring: const { id, name } = req.query
121
+ if (nameNode.type === 'object_pattern') {
122
+ for (const prop of findAllNodes(nameNode, 'shorthand_property_identifier_pattern')) {
123
+ tainted.set(prop.text, `destructured from ${valueNode.text.slice(0, 40)}`);
124
+ }
125
+ // Also handle: const { id: userId } = req.query
126
+ for (const prop of findAllNodes(nameNode, 'pair_pattern')) {
127
+ const val = prop.childForFieldName('value');
128
+ if (val?.type === 'identifier') {
129
+ tainted.set(val.text, `destructured from ${valueNode.text.slice(0, 40)}`);
130
+ }
131
+ }
132
+ }
133
+ // Array destructuring: const [a, b] = req.body.items
134
+ if (nameNode.type === 'array_pattern') {
135
+ for (const elem of nameNode.namedChildren) {
136
+ if (elem.type === 'identifier') {
137
+ tainted.set(elem.text, `array-destructured from ${valueNode.text.slice(0, 40)}`);
138
+ }
139
+ }
140
+ }
141
+ }
142
+ // --- assignment_expression: `NAME = VALUE` (reassignment) ---
143
+ for (const assign of findAllNodes(rootNode, 'assignment_expression')) {
144
+ const left = assign.childForFieldName('left');
145
+ const right = assign.childForFieldName('right');
146
+ if (!left || !right)
147
+ continue;
148
+ if (left.type !== 'identifier')
149
+ continue;
150
+ if (hasUserInput(right, language)) {
151
+ tainted.set(left.text, `reassigned from ${right.text.slice(0, 60)}`);
152
+ continue;
153
+ }
154
+ // Cross-file: taintedVar = crossFileFn(...)
155
+ if (crossFileSources && right.type === 'call_expression') {
156
+ const callFuncNode = right.childForFieldName('function');
157
+ if (callFuncNode) {
158
+ const calleeName = callFuncNode.type === 'member_expression'
159
+ ? (callFuncNode.childForFieldName('property')?.text ?? '')
160
+ : callFuncNode.text;
161
+ if (crossFileSources.has(calleeName)) {
162
+ tainted.set(left.text, `reassigned from cross-file fn '${calleeName}'`);
163
+ }
164
+ }
165
+ }
166
+ }
167
+ }
168
+ if (language === 'python') {
169
+ // Python: `assignment` node → identifier = value
170
+ for (const assign of findAllNodes(rootNode, 'assignment')) {
171
+ const left = assign.namedChildren[0];
172
+ const right = assign.namedChildren[assign.namedChildren.length - 1];
173
+ if (!left || !right || left === right)
174
+ continue;
175
+ if (left.type !== 'identifier')
176
+ continue;
177
+ if (!hasUserInput(right, language))
178
+ continue;
179
+ tainted.set(left.text, `assigned from ${right.text.slice(0, 60)}`);
180
+ }
181
+ }
182
+ return tainted;
183
+ }
184
+ /**
185
+ * Fixed-point propagation: if the RHS of an assignment contains a tainted
186
+ * identifier, the LHS variable becomes tainted too.
187
+ *
188
+ * Mutates `tainted` in place. Runs until no new taints are added (max 10 passes).
189
+ */
190
+ export function propagateTaint(rootNode, tainted, language) {
191
+ function rhsContainsTainted(valueNode) {
192
+ for (const identNode of findAllNodes(valueNode, 'identifier')) {
193
+ if (tainted.has(identNode.text))
194
+ return identNode.text;
195
+ }
196
+ // Template substitutions: `${taintedVar}`
197
+ for (const sub of findAllNodes(valueNode, 'template_substitution')) {
198
+ for (const identNode of findAllNodes(sub, 'identifier')) {
199
+ if (tainted.has(identNode.text))
200
+ return identNode.text;
201
+ }
202
+ }
203
+ return null;
204
+ }
205
+ let changed = true;
206
+ let passes = 0;
207
+ while (changed && passes < 10) {
208
+ changed = false;
209
+ passes++;
210
+ if (language === 'javascript' || language === 'typescript') {
211
+ for (const decl of findAllNodes(rootNode, 'variable_declarator')) {
212
+ const nameNode = decl.childForFieldName('name');
213
+ const valueNode = decl.childForFieldName('value');
214
+ if (!nameNode || !valueNode)
215
+ continue;
216
+ if (nameNode.type !== 'identifier')
217
+ continue;
218
+ if (tainted.has(nameNode.text))
219
+ continue;
220
+ const fromVar = rhsContainsTainted(valueNode);
221
+ if (fromVar) {
222
+ tainted.set(nameNode.text, `derived from tainted '${fromVar}'`);
223
+ changed = true;
224
+ }
225
+ }
226
+ for (const assign of findAllNodes(rootNode, 'assignment_expression')) {
227
+ const left = assign.childForFieldName('left');
228
+ const right = assign.childForFieldName('right');
229
+ if (!left || !right)
230
+ continue;
231
+ if (left.type !== 'identifier')
232
+ continue;
233
+ if (tainted.has(left.text))
234
+ continue;
235
+ const fromVar = rhsContainsTainted(right);
236
+ if (fromVar) {
237
+ tainted.set(left.text, `derived from tainted '${fromVar}'`);
238
+ changed = true;
239
+ }
240
+ }
241
+ }
242
+ if (language === 'python') {
243
+ for (const assign of findAllNodes(rootNode, 'assignment')) {
244
+ const left = assign.namedChildren[0];
245
+ const right = assign.namedChildren[assign.namedChildren.length - 1];
246
+ if (!left || !right || left === right)
247
+ continue;
248
+ if (left.type !== 'identifier')
249
+ continue;
250
+ if (tainted.has(left.text))
251
+ continue;
252
+ const fromVar = rhsContainsTainted(right);
253
+ if (fromVar) {
254
+ tainted.set(left.text, `derived from tainted '${fromVar}'`);
255
+ changed = true;
256
+ }
257
+ }
258
+ }
259
+ }
260
+ }
261
+ /**
262
+ * Build the full taint map: initial sources + propagated chains.
263
+ * crossFileSources: optional function names from other files that return tainted data.
264
+ */
265
+ export function buildTaintMap(rootNode, language, crossFileSources) {
266
+ const tainted = buildInitialTaintMap(rootNode, language, crossFileSources);
267
+ if (tainted.size > 0) {
268
+ propagateTaint(rootNode, tainted, language);
269
+ }
270
+ return tainted;
271
+ }
272
+ // ---- Taint-aware argument checking ----
273
+ /**
274
+ * Check if a call argument is or contains a tainted identifier from the taint map.
275
+ * Returns the tainted variable name if found, null otherwise.
276
+ */
277
+ function argIsTainted(argNode, tainted) {
278
+ // Direct identifier: db.query(taintedVar)
279
+ if (argNode.type === 'identifier' && tainted.has(argNode.text)) {
280
+ return argNode.text;
281
+ }
282
+ // Any identifier within the arg expression
283
+ for (const identNode of findAllNodes(argNode, 'identifier')) {
284
+ if (tainted.has(identNode.text))
285
+ return identNode.text;
286
+ }
287
+ // Template substitution: `...${taintedVar}...`
288
+ for (const sub of findAllNodes(argNode, 'template_substitution')) {
289
+ for (const identNode of findAllNodes(sub, 'identifier')) {
290
+ if (tainted.has(identNode.text))
291
+ return identNode.text;
292
+ }
293
+ }
294
+ return null;
295
+ }
296
+ const SINK_RULES = [
297
+ {
298
+ ruleId: 'OWASP-A03-001',
299
+ owasp: 'A03:2021',
300
+ severity: 'CRITICAL',
301
+ description: 'Direct user input in SQL query function',
302
+ jsMethods: new Set(['query', 'execute', 'raw', 'run', 'queryRawUnsafe', 'executemany']),
303
+ pyFunctionRe: /\b(?:execute|executemany|raw)\b/,
304
+ // Only check arg[0] (the SQL string). arg[1] is the parameter bindings array — safe by design.
305
+ taintArgIndex: 0,
306
+ },
307
+ {
308
+ ruleId: 'OWASP-A03-002',
309
+ owasp: 'A03:2021',
310
+ severity: 'CRITICAL',
311
+ description: 'Direct user input in shell execution function',
312
+ jsMethods: new Set(['exec', 'execSync', 'execFile', 'execFileSync', 'spawnSync']),
313
+ jsFunctions: new Set(['exec', 'execSync', 'execFile', 'spawnSync']),
314
+ pyFunctionRe: /\b(?:os\.system|subprocess\.(?:run|call|Popen|check_output|check_call)|commands\.getoutput)\b/,
315
+ },
316
+ {
317
+ ruleId: 'OWASP-A10-001',
318
+ owasp: 'A10:2021',
319
+ severity: 'HIGH',
320
+ description: 'Direct user input in HTTP fetch call (SSRF)',
321
+ jsFunctions: new Set(['fetch']),
322
+ jsMethods: new Set(['get', 'post', 'put', 'patch', 'delete', 'request']),
323
+ // Only match real HTTP clients — NOT Express/Koa router.get('/path', handler)
324
+ jsObjectFilter: /^(axios|http|https|got|superagent|agent|nodeFetch|node-fetch|ky|request|urllib)\b/i,
325
+ // Only check arg[0] (the URL). Without this, handler function bodies with `req` get flagged.
326
+ taintArgIndex: 0,
327
+ pyFunctionRe: /\b(?:requests\.(?:get|post|put|delete|request|head)|urllib\.request\.urlopen|urlopen)\b/,
328
+ },
329
+ {
330
+ ruleId: 'OWASP-A08-001',
331
+ owasp: 'A08:2021',
332
+ severity: 'CRITICAL',
333
+ description: 'Direct user input in eval() (code injection)',
334
+ jsFunctions: new Set(['eval']),
335
+ pyFunctionRe: /\b(?:eval|exec)\b/,
336
+ },
337
+ {
338
+ ruleId: 'OWASP-A03-005',
339
+ owasp: 'A03:2021',
340
+ severity: 'HIGH',
341
+ description: 'Direct user input in template render (SSTI)',
342
+ jsMethods: new Set(['render']),
343
+ pyFunctionRe: /\b(?:render_template_string|Template)\b/,
344
+ },
345
+ {
346
+ ruleId: 'OWASP-A01-002',
347
+ owasp: 'A01:2021',
348
+ severity: 'HIGH',
349
+ description: 'Direct user input used as file path (path traversal)',
350
+ jsMethods: new Set(['readFile', 'writeFile', 'readFileSync', 'writeFileSync', 'unlink', 'stat', 'open']),
351
+ pyFunctionRe: /\b(?:open|os\.path\.join|pathlib\.Path)\b/,
352
+ },
353
+ ];
354
+ // ---- JS/TS call expression analysis ----
355
+ function analyzeJSCall(callNode, sourceLines, results, language, tainted) {
356
+ const funcNode = callNode.childForFieldName('function');
357
+ const argsNode = callNode.childForFieldName('arguments');
358
+ if (!funcNode || !argsNode)
359
+ return;
360
+ // Determine sink name
361
+ let sinkName = '';
362
+ let matchedSink;
363
+ if (funcNode.type === 'member_expression') {
364
+ const propNode = funcNode.childForFieldName('property') ??
365
+ funcNode.namedChild(funcNode.namedChildCount - 1);
366
+ if (propNode) {
367
+ sinkName = propNode.text;
368
+ matchedSink = SINK_RULES.find((r) => r.jsMethods?.has(sinkName));
369
+ }
370
+ }
371
+ else if (funcNode.type === 'identifier') {
372
+ sinkName = funcNode.text;
373
+ matchedSink = SINK_RULES.find((r) => r.jsFunctions?.has(sinkName));
374
+ }
375
+ if (!matchedSink)
376
+ return;
377
+ // If the sink requires the callee object to match a specific pattern (e.g. SSRF: only real
378
+ // HTTP clients, not Express router.get(path, handler)), enforce it here.
379
+ if (matchedSink.jsObjectFilter && funcNode.type === 'member_expression') {
380
+ const objectNode = funcNode.childForFieldName('object');
381
+ if (!objectNode || !matchedSink.jsObjectFilter.test(objectNode.text))
382
+ return;
383
+ }
384
+ // Check each argument: direct user input OR tainted variable
385
+ // For sinks with taintArgIndex, only check that specific argument (e.g. SQL: arg[0] only)
386
+ const argsToCheck = matchedSink.taintArgIndex !== undefined
387
+ ? [argsNode.namedChildren[matchedSink.taintArgIndex]].filter(Boolean)
388
+ : argsNode.namedChildren;
389
+ for (const arg of argsToCheck) {
390
+ const directHit = argContainsUserInput(arg, language);
391
+ const taintedVar = !directHit ? argIsTainted(arg, tainted) : null;
392
+ if (directHit || taintedVar) {
393
+ const line = callNode.startPosition.row + 1;
394
+ const taintInfo = taintedVar
395
+ ? ` (tainted via '${taintedVar}': ${tainted.get(taintedVar).slice(0, 60)})`
396
+ : '';
397
+ results.push({
398
+ ruleId: matchedSink.ruleId,
399
+ owasp: matchedSink.owasp,
400
+ severity: matchedSink.severity,
401
+ description: matchedSink.description + taintInfo,
402
+ line,
403
+ column: callNode.startPosition.column + 1,
404
+ snippet: (sourceLines[line - 1] ?? callNode.text.slice(0, 120)).trim(),
405
+ argText: arg.text.slice(0, 120),
406
+ sinkName,
407
+ taintPath: taintedVar
408
+ ? [`Source: '${taintedVar}' — ${tainted.get(taintedVar)}`, `Sink: ${sinkName}(${arg.text.slice(0, 60)})`]
409
+ : undefined,
410
+ });
411
+ break; // One finding per call
412
+ }
413
+ }
414
+ }
415
+ // Check if an argument node contains user input, structurally
416
+ function argContainsUserInput(argNode, language) {
417
+ // Direct user input reference (req.query.id, request.args.get('id'), etc.)
418
+ if (hasUserInput(argNode, language))
419
+ return true;
420
+ // String concatenation: "SELECT..." + req.query.id
421
+ if (argNode.type === 'binary_expression') {
422
+ for (const child of argNode.namedChildren) {
423
+ if (argContainsUserInput(child, language))
424
+ return true;
425
+ }
426
+ }
427
+ // Template literal: `SELECT... ${req.query.id}`
428
+ if (argNode.type === 'template_string') {
429
+ for (const sub of findAllNodes(argNode, 'template_substitution')) {
430
+ if (hasUserInput(sub, language))
431
+ return true;
432
+ }
433
+ }
434
+ // Python: f-string or binary operator
435
+ if (argNode.type === 'binary_operator' || argNode.type === 'concatenated_string') {
436
+ for (const child of argNode.namedChildren) {
437
+ if (argContainsUserInput(child, language))
438
+ return true;
439
+ }
440
+ }
441
+ // Python: formatted string (f-string) — represented as `string` with interpolation nodes
442
+ if (argNode.type === 'string' && argNode.text.startsWith('f')) {
443
+ if (hasUserInput(argNode, language))
444
+ return true;
445
+ }
446
+ return false;
447
+ }
448
+ // ---- Python call expression analysis ----
449
+ function analyzePythonCall(callNode, sourceLines, results, tainted) {
450
+ const funcNode = callNode.childForFieldName('function');
451
+ const argsNode = callNode.childForFieldName('arguments');
452
+ if (!funcNode || !argsNode)
453
+ return;
454
+ const funcText = funcNode.text;
455
+ const matchedSink = SINK_RULES.find((r) => r.pyFunctionRe && r.pyFunctionRe.test(funcText));
456
+ if (!matchedSink)
457
+ return;
458
+ // Check arguments: direct user input OR tainted variable
459
+ // For sinks with taintArgIndex, only check that specific argument
460
+ const pyArgTarget = matchedSink.taintArgIndex !== undefined
461
+ ? (argsNode.namedChildren[matchedSink.taintArgIndex] ?? argsNode)
462
+ : argsNode;
463
+ const directHit = argContainsUserInput(pyArgTarget, 'python');
464
+ const taintedVar = !directHit ? argIsTainted(pyArgTarget, tainted) : null;
465
+ if (directHit || taintedVar) {
466
+ const line = callNode.startPosition.row + 1;
467
+ const taintInfo = taintedVar
468
+ ? ` (tainted via '${taintedVar}': ${tainted.get(taintedVar).slice(0, 60)})`
469
+ : '';
470
+ results.push({
471
+ ruleId: matchedSink.ruleId,
472
+ owasp: matchedSink.owasp,
473
+ severity: matchedSink.severity,
474
+ description: matchedSink.description + taintInfo,
475
+ line,
476
+ column: callNode.startPosition.column + 1,
477
+ snippet: (sourceLines[line - 1] ?? callNode.text.slice(0, 120)).trim(),
478
+ argText: argsNode.text.slice(0, 120),
479
+ sinkName: funcText,
480
+ taintPath: taintedVar
481
+ ? [`Source: '${taintedVar}' — ${tainted.get(taintedVar)}`, `Sink: ${funcText}(${argsNode.text.slice(0, 60)})`]
482
+ : undefined,
483
+ });
484
+ }
485
+ }
486
+ // ---- Middleware-aware suppression ----
487
+ // Names that strongly suggest input validation/sanitization middleware
488
+ const VALIDATION_MIDDLEWARE_RE = /\b(?:validate|sanitize|check|verif(?:y|ied)|authenti(?:cat|c)|authori[sz]|protect|guard|permit|restrict|rateLimit|rateLimiter|helmet|csrf|xss|escape|clean(?:se|er)|strip|purif|dompurif)\w*\b/i;
489
+ /**
490
+ * Collect line numbers of route handler functions that are protected by
491
+ * a validation/auth middleware in their Express/Koa route definition.
492
+ *
493
+ * e.g.: router.get('/users', authenticate, validateInput, handler)
494
+ * → handler's body line numbers are "protected"
495
+ *
496
+ * Returns a Set of line numbers (1-based) that are inside protected handlers.
497
+ */
498
+ function collectProtectedLines(rootNode) {
499
+ const protected_ = new Set();
500
+ for (const call of findAllNodes(rootNode, 'call_expression')) {
501
+ const func = call.childForFieldName('function');
502
+ const args = call.childForFieldName('arguments');
503
+ if (!func || !args)
504
+ continue;
505
+ // Match: router.get / app.post / router.use etc.
506
+ if (func.type !== 'member_expression')
507
+ continue;
508
+ const method = func.childForFieldName('property')?.text ?? '';
509
+ if (!/^(get|post|put|patch|delete|use|all)$/.test(method))
510
+ continue;
511
+ const argChildren = args.namedChildren;
512
+ if (argChildren.length < 2)
513
+ continue;
514
+ // Check if any non-last argument contains a validation middleware name
515
+ const middlewares = argChildren.slice(0, -1);
516
+ const hasValidationMiddleware = middlewares.some((m) => VALIDATION_MIDDLEWARE_RE.test(m.text));
517
+ if (!hasValidationMiddleware)
518
+ continue;
519
+ // The last argument is the route handler — mark all its lines as protected
520
+ const handler = argChildren[argChildren.length - 1];
521
+ if (!handler)
522
+ continue;
523
+ const startLine = handler.startPosition.row + 1;
524
+ const endLine = handler.endPosition.row + 1;
525
+ for (let ln = startLine; ln <= endLine; ln++) {
526
+ protected_.add(ln);
527
+ }
528
+ }
529
+ return protected_;
530
+ }
531
+ // ---- Main export ----
532
+ /**
533
+ * Scan a parsed AST for vulnerabilities.
534
+ * Combines two detection modes:
535
+ * 1. Direct: user input appears directly in a sink argument
536
+ * 2. Taint: user input was assigned to a variable that reaches the sink
537
+ *
538
+ * The taint map is built via AST node traversal (not regex), so it is
539
+ * precise — handles destructuring, reassignment, template literals.
540
+ * Middleware-aware: handlers guarded by validate/auth middleware get LOW confidence.
541
+ *
542
+ * crossFileSources: optional map of function names from other scanned files that
543
+ * return tainted data (populated by the two-pass scanDirectory pre-pass).
544
+ */
545
+ export function findVulnerableCalls(rootNode, language, sourceLines, crossFileSources) {
546
+ const results = [];
547
+ // Build AST-based taint map (sources + fixed-point propagation + cross-file sources)
548
+ const tainted = buildTaintMap(rootNode, language, crossFileSources);
549
+ // Collect lines inside middleware-protected route handlers (JS/TS only)
550
+ const protectedLines = (language === 'javascript' || language === 'typescript')
551
+ ? collectProtectedLines(rootNode)
552
+ : new Set();
553
+ if (language === 'javascript' || language === 'typescript') {
554
+ for (const callNode of findAllNodes(rootNode, 'call_expression')) {
555
+ analyzeJSCall(callNode, sourceLines, results, language, tainted);
556
+ }
557
+ }
558
+ else if (language === 'python') {
559
+ for (const callNode of findAllNodes(rootNode, 'call')) {
560
+ analyzePythonCall(callNode, sourceLines, results, tainted);
561
+ }
562
+ }
563
+ // Downgrade confidence for findings inside middleware-protected handlers
564
+ for (const finding of results) {
565
+ if (protectedLines.has(finding.line)) {
566
+ finding.suppressedByMiddleware = true;
567
+ finding.description = finding.description + ' [middleware may sanitize this input]';
568
+ }
569
+ }
570
+ // Deduplicate by line + ruleId
571
+ const seen = new Set();
572
+ return results.filter((r) => {
573
+ const key = `${r.ruleId}:${r.line}`;
574
+ if (seen.has(key))
575
+ return false;
576
+ seen.add(key);
577
+ return true;
578
+ });
579
+ }
580
+ //# sourceMappingURL=ast-queries.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ast-queries.js","sourceRoot":"","sources":["../../src/parsers/ast-queries.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { ScanResult } from '../types/index.js';
2
+ export interface ConsoleReporterOptions {
3
+ verbose: boolean;
4
+ noColor: boolean;
5
+ showFix: boolean;
6
+ }
7
+ export declare function reportConsole(result: ScanResult, options: ConsoleReporterOptions): void;
8
+ //# sourceMappingURL=console.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"console.d.ts","sourceRoot":"","sources":["../../src/reporter/console.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAqB,MAAM,mBAAmB,CAAC;AA+HvE,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,sBAAsB,GAAG,IAAI,CAuCvF"}