@sikkuumiii/defuse 0.0.0-stage → 0.5.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 (236) hide show
  1. package/LICENSE +235 -0
  2. package/README.md +561 -2
  3. package/dist/src/cli.d.ts +20 -0
  4. package/dist/src/cli.js +619 -0
  5. package/dist/src/cli.js.map +1 -0
  6. package/dist/src/core/analyze.d.ts +178 -0
  7. package/dist/src/core/analyze.js +834 -0
  8. package/dist/src/core/analyze.js.map +1 -0
  9. package/dist/src/core/coverage.d.ts +87 -0
  10. package/dist/src/core/coverage.js +181 -0
  11. package/dist/src/core/coverage.js.map +1 -0
  12. package/dist/src/core/finding.d.ts +196 -0
  13. package/dist/src/core/finding.js +178 -0
  14. package/dist/src/core/finding.js.map +1 -0
  15. package/dist/src/core/licence.d.ts +50 -0
  16. package/dist/src/core/licence.js +56 -0
  17. package/dist/src/core/licence.js.map +1 -0
  18. package/dist/src/core/paths.d.ts +21 -0
  19. package/dist/src/core/paths.js +58 -0
  20. package/dist/src/core/paths.js.map +1 -0
  21. package/dist/src/core/score.d.ts +137 -0
  22. package/dist/src/core/score.js +232 -0
  23. package/dist/src/core/score.js.map +1 -0
  24. package/dist/src/dast/targets.d.ts +30 -0
  25. package/dist/src/dast/targets.js +79 -0
  26. package/dist/src/dast/targets.js.map +1 -0
  27. package/dist/src/dast/zap.d.ts +42 -0
  28. package/dist/src/dast/zap.js +184 -0
  29. package/dist/src/dast/zap.js.map +1 -0
  30. package/dist/src/engine/scan.d.ts +80 -0
  31. package/dist/src/engine/scan.js +129 -0
  32. package/dist/src/engine/scan.js.map +1 -0
  33. package/dist/src/engine/shapes.d.ts +47 -0
  34. package/dist/src/engine/shapes.js +328 -0
  35. package/dist/src/engine/shapes.js.map +1 -0
  36. package/dist/src/engine/walk.d.ts +60 -0
  37. package/dist/src/engine/walk.js +156 -0
  38. package/dist/src/engine/walk.js.map +1 -0
  39. package/dist/src/parse/astDump.d.ts +31 -0
  40. package/dist/src/parse/astDump.js +66 -0
  41. package/dist/src/parse/astDump.js.map +1 -0
  42. package/dist/src/parse/languages.d.ts +70 -0
  43. package/dist/src/parse/languages.js +174 -0
  44. package/dist/src/parse/languages.js.map +1 -0
  45. package/dist/src/parse/location.d.ts +17 -0
  46. package/dist/src/parse/location.js +38 -0
  47. package/dist/src/parse/location.js.map +1 -0
  48. package/dist/src/parse/node-grammars.d.ts +12 -0
  49. package/dist/src/parse/node-grammars.js +35 -0
  50. package/dist/src/parse/node-grammars.js.map +1 -0
  51. package/dist/src/parse/parser.d.ts +126 -0
  52. package/dist/src/parse/parser.js +202 -0
  53. package/dist/src/parse/parser.js.map +1 -0
  54. package/dist/src/parse/tree-store.d.ts +139 -0
  55. package/dist/src/parse/tree-store.js +236 -0
  56. package/dist/src/parse/tree-store.js.map +1 -0
  57. package/dist/src/platform/dependency-rule.d.ts +27 -0
  58. package/dist/src/platform/dependency-rule.js +21 -0
  59. package/dist/src/platform/dependency-rule.js.map +1 -0
  60. package/dist/src/platform/deps.d.ts +86 -0
  61. package/dist/src/platform/deps.js +304 -0
  62. package/dist/src/platform/deps.js.map +1 -0
  63. package/dist/src/platform/php-facts.d.ts +49 -0
  64. package/dist/src/platform/php-facts.js +67 -0
  65. package/dist/src/platform/php-facts.js.map +1 -0
  66. package/dist/src/platform/runtime-version.d.ts +78 -0
  67. package/dist/src/platform/runtime-version.js +573 -0
  68. package/dist/src/platform/runtime-version.js.map +1 -0
  69. package/dist/src/report/colors.d.ts +50 -0
  70. package/dist/src/report/colors.js +97 -0
  71. package/dist/src/report/colors.js.map +1 -0
  72. package/dist/src/report/coverage-table.d.ts +90 -0
  73. package/dist/src/report/coverage-table.js +291 -0
  74. package/dist/src/report/coverage-table.js.map +1 -0
  75. package/dist/src/report/html-report.d.ts +66 -0
  76. package/dist/src/report/html-report.js +489 -0
  77. package/dist/src/report/html-report.js.map +1 -0
  78. package/dist/src/report/human.d.ts +44 -0
  79. package/dist/src/report/human.js +575 -0
  80. package/dist/src/report/human.js.map +1 -0
  81. package/dist/src/report/json.d.ts +24 -0
  82. package/dist/src/report/json.js +178 -0
  83. package/dist/src/report/json.js.map +1 -0
  84. package/dist/src/report/mark.d.ts +17 -0
  85. package/dist/src/report/mark.js +39 -0
  86. package/dist/src/report/mark.js.map +1 -0
  87. package/dist/src/report/pricing.d.ts +33 -0
  88. package/dist/src/report/pricing.js +343 -0
  89. package/dist/src/report/pricing.js.map +1 -0
  90. package/dist/src/report/sarif.d.ts +39 -0
  91. package/dist/src/report/sarif.js +219 -0
  92. package/dist/src/report/sarif.js.map +1 -0
  93. package/dist/src/report/site.d.ts +87 -0
  94. package/dist/src/report/site.js +742 -0
  95. package/dist/src/report/site.js.map +1 -0
  96. package/dist/src/rules/code-injection.d.ts +47 -0
  97. package/dist/src/rules/code-injection.js +326 -0
  98. package/dist/src/rules/code-injection.js.map +1 -0
  99. package/dist/src/rules/command-injection.d.ts +30 -0
  100. package/dist/src/rules/command-injection.js +286 -0
  101. package/dist/src/rules/command-injection.js.map +1 -0
  102. package/dist/src/rules/contract.d.ts +198 -0
  103. package/dist/src/rules/contract.js +39 -0
  104. package/dist/src/rules/contract.js.map +1 -0
  105. package/dist/src/rules/format-string.d.ts +46 -0
  106. package/dist/src/rules/format-string.js +146 -0
  107. package/dist/src/rules/format-string.js.map +1 -0
  108. package/dist/src/rules/hardcoded-secret.d.ts +38 -0
  109. package/dist/src/rules/hardcoded-secret.js +440 -0
  110. package/dist/src/rules/hardcoded-secret.js.map +1 -0
  111. package/dist/src/rules/lib/guards.d.ts +168 -0
  112. package/dist/src/rules/lib/guards.js +1179 -0
  113. package/dist/src/rules/lib/guards.js.map +1 -0
  114. package/dist/src/rules/lib/html-safety.d.ts +75 -0
  115. package/dist/src/rules/lib/html-safety.js +755 -0
  116. package/dist/src/rules/lib/html-safety.js.map +1 -0
  117. package/dist/src/rules/lib/local-build.d.ts +59 -0
  118. package/dist/src/rules/lib/local-build.js +320 -0
  119. package/dist/src/rules/lib/local-build.js.map +1 -0
  120. package/dist/src/rules/lib/strings.d.ts +208 -0
  121. package/dist/src/rules/lib/strings.js +1970 -0
  122. package/dist/src/rules/lib/strings.js.map +1 -0
  123. package/dist/src/rules/path-traversal.d.ts +33 -0
  124. package/dist/src/rules/path-traversal.js +96 -0
  125. package/dist/src/rules/path-traversal.js.map +1 -0
  126. package/dist/src/rules/registry.d.ts +19 -0
  127. package/dist/src/rules/registry.js +77 -0
  128. package/dist/src/rules/registry.js.map +1 -0
  129. package/dist/src/rules/sql-injection.d.ts +36 -0
  130. package/dist/src/rules/sql-injection.js +299 -0
  131. package/dist/src/rules/sql-injection.js.map +1 -0
  132. package/dist/src/rules/ssrf.d.ts +39 -0
  133. package/dist/src/rules/ssrf.js +111 -0
  134. package/dist/src/rules/ssrf.js.map +1 -0
  135. package/dist/src/rules/unbounded-copy.d.ts +37 -0
  136. package/dist/src/rules/unbounded-copy.js +147 -0
  137. package/dist/src/rules/unbounded-copy.js.map +1 -0
  138. package/dist/src/rules/unsafe-deserialization.d.ts +43 -0
  139. package/dist/src/rules/unsafe-deserialization.js +276 -0
  140. package/dist/src/rules/unsafe-deserialization.js.map +1 -0
  141. package/dist/src/rules/weak-hash.d.ts +37 -0
  142. package/dist/src/rules/weak-hash.js +197 -0
  143. package/dist/src/rules/weak-hash.js.map +1 -0
  144. package/dist/src/rules/xss.d.ts +38 -0
  145. package/dist/src/rules/xss.js +527 -0
  146. package/dist/src/rules/xss.js.map +1 -0
  147. package/dist/src/taint/content-type.d.ts +19 -0
  148. package/dist/src/taint/content-type.js +20 -0
  149. package/dist/src/taint/content-type.js.map +1 -0
  150. package/dist/src/taint/dictionaries.d.ts +23 -0
  151. package/dist/src/taint/dictionaries.js +1778 -0
  152. package/dist/src/taint/dictionaries.js.map +1 -0
  153. package/dist/src/taint/fold.d.ts +59 -0
  154. package/dist/src/taint/fold.js +1177 -0
  155. package/dist/src/taint/fold.js.map +1 -0
  156. package/dist/src/taint/java-scope.d.ts +61 -0
  157. package/dist/src/taint/java-scope.js +212 -0
  158. package/dist/src/taint/java-scope.js.map +1 -0
  159. package/dist/src/taint/local-map.d.ts +79 -0
  160. package/dist/src/taint/local-map.js +603 -0
  161. package/dist/src/taint/local-map.js.map +1 -0
  162. package/dist/src/taint/project.d.ts +172 -0
  163. package/dist/src/taint/project.js +617 -0
  164. package/dist/src/taint/project.js.map +1 -0
  165. package/dist/src/taint/tracer.d.ts +265 -0
  166. package/dist/src/taint/tracer.js +3817 -0
  167. package/dist/src/taint/tracer.js.map +1 -0
  168. package/dist/src/taint/types.d.ts +484 -0
  169. package/dist/src/taint/types.js +47 -0
  170. package/dist/src/taint/types.js.map +1 -0
  171. package/dist/src/taint/visibility.d.ts +25 -0
  172. package/dist/src/taint/visibility.js +96 -0
  173. package/dist/src/taint/visibility.js.map +1 -0
  174. package/docs/examples/defuse.json +20 -0
  175. package/docs/examples/dvwa-urls.json +14 -0
  176. package/docs/examples/github-code-scanning.yml +54 -0
  177. package/docs/examples/tiny.js +4 -0
  178. package/package.json +73 -4
  179. package/src/cli.ts +747 -0
  180. package/src/core/analyze.ts +1072 -0
  181. package/src/core/coverage.ts +269 -0
  182. package/src/core/finding.ts +311 -0
  183. package/src/core/licence.ts +61 -0
  184. package/src/core/paths.ts +59 -0
  185. package/src/core/score.ts +353 -0
  186. package/src/dast/targets.ts +121 -0
  187. package/src/dast/zap.ts +246 -0
  188. package/src/engine/scan.ts +200 -0
  189. package/src/engine/shapes.ts +348 -0
  190. package/src/engine/walk.ts +196 -0
  191. package/src/parse/astDump.ts +85 -0
  192. package/src/parse/languages.ts +232 -0
  193. package/src/parse/location.ts +44 -0
  194. package/src/parse/node-grammars.ts +41 -0
  195. package/src/parse/parser.ts +262 -0
  196. package/src/parse/tree-store.ts +301 -0
  197. package/src/platform/dependency-rule.ts +33 -0
  198. package/src/platform/deps.ts +374 -0
  199. package/src/platform/php-facts.ts +85 -0
  200. package/src/platform/runtime-version.ts +710 -0
  201. package/src/report/colors.ts +107 -0
  202. package/src/report/coverage-table.ts +359 -0
  203. package/src/report/html-report.ts +601 -0
  204. package/src/report/human.ts +811 -0
  205. package/src/report/json.ts +189 -0
  206. package/src/report/mark.ts +47 -0
  207. package/src/report/pricing.ts +374 -0
  208. package/src/report/sarif.ts +235 -0
  209. package/src/report/site.ts +760 -0
  210. package/src/rules/code-injection.ts +346 -0
  211. package/src/rules/command-injection.ts +296 -0
  212. package/src/rules/contract.ts +220 -0
  213. package/src/rules/format-string.ts +158 -0
  214. package/src/rules/hardcoded-secret.ts +485 -0
  215. package/src/rules/lib/guards.ts +1235 -0
  216. package/src/rules/lib/html-safety.ts +793 -0
  217. package/src/rules/lib/local-build.ts +329 -0
  218. package/src/rules/lib/strings.ts +2034 -0
  219. package/src/rules/path-traversal.ts +101 -0
  220. package/src/rules/registry.ts +90 -0
  221. package/src/rules/sql-injection.ts +311 -0
  222. package/src/rules/ssrf.ts +118 -0
  223. package/src/rules/unbounded-copy.ts +162 -0
  224. package/src/rules/unsafe-deserialization.ts +291 -0
  225. package/src/rules/weak-hash.ts +226 -0
  226. package/src/rules/xss.ts +572 -0
  227. package/src/taint/content-type.ts +20 -0
  228. package/src/taint/dictionaries.ts +1855 -0
  229. package/src/taint/fold.ts +1206 -0
  230. package/src/taint/java-scope.ts +200 -0
  231. package/src/taint/local-map.ts +594 -0
  232. package/src/taint/project.ts +774 -0
  233. package/src/taint/tracer.ts +4298 -0
  234. package/src/taint/types.ts +511 -0
  235. package/src/taint/visibility.ts +100 -0
  236. package/tsconfig.json +61 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html-safety.js","sourceRoot":"","sources":["../../../../src/rules/lib/html-safety.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * WHERE WAS THIS VARIABLE BUILT?
3
+ * ==============================
4
+ *
5
+ * A signature rule reads the argument of a dangerous call and asks how its text
6
+ * was assembled. That question has an obvious blind spot, and until this file
7
+ * existed the command-injection rule sat squarely in it:
8
+ *
9
+ * os.system("ls " + name) <- the argument IS the build. Reported.
10
+ *
11
+ * cmd = "ls " + name
12
+ * os.system(cmd) <- the argument is a NAME. Silent.
13
+ *
14
+ * Same code, same risk, one line break apart - in every language. In C it was
15
+ * worse than a blind spot: C has no `+` for strings, so a command is ALWAYS
16
+ * formatted into a buffer first and run afterwards, and the signature pass saw
17
+ * `system(buf)` every single time.
18
+ *
19
+ * WHAT THIS DOES, AND ON PURPOSE WHAT IT DOES NOT.
20
+ *
21
+ * Given a bare name at a call site, it looks back through the SAME function for
22
+ * the writes that reach the call, in straight-line code:
23
+ *
24
+ * a RESET replaces the value cmd = ... char cmd[] = ... sprintf(cmd, ...)
25
+ * an EXTEND appends to it cmd += ... strcat(cmd, ...) cmd.append(...)
26
+ *
27
+ * The value at the call is the LAST reset plus every extend after it. That is
28
+ * what makes `cmd = "ls " + name; cmd = "ls -l"; system(cmd)` quiet: the build
29
+ * that spliced `name` in was overwritten before the call ran.
30
+ *
31
+ * It gives up - returns null, which leaves the rule exactly as quiet as it was
32
+ * before - whenever the answer would depend on which way the program went:
33
+ *
34
+ * - any write to the name sits under an if, a loop, a switch or a try;
35
+ * - there is no reset in this function at all (a parameter, a global);
36
+ * - the write is a shape this file has not been taught.
37
+ *
38
+ * Giving up is the safe direction for a SIGNATURE rule in the narrow sense that
39
+ * it cannot add a false finding. It is not free: every one of those is a guess
40
+ * the rule could have made and did not. The coverage notes say so, rather than
41
+ * letting "implemented" imply the conditional case is covered too.
42
+ *
43
+ * It never evaluates anything. It describes how the text was put together,
44
+ * which is all a signature rule is entitled to know.
45
+ */
46
+ import type { Node } from 'web-tree-sitter';
47
+ import type { LanguageId } from '../../parse/languages.js';
48
+ import { type StringExpression } from './strings.js';
49
+ export interface LocalBuild {
50
+ readonly expression: StringExpression;
51
+ /** 1-based line of the write the value at the call starts from. */
52
+ readonly line: number;
53
+ }
54
+ /**
55
+ * Follow the argument of a dangerous call back to how its text was built.
56
+ * Returns null when there is nothing to follow, or when following it would
57
+ * need to know which way the program went.
58
+ */
59
+ export declare function followLocalBuild(arg: Node, language: LanguageId): LocalBuild | null;
@@ -0,0 +1,320 @@
1
+ /**
2
+ * WHERE WAS THIS VARIABLE BUILT?
3
+ * ==============================
4
+ *
5
+ * A signature rule reads the argument of a dangerous call and asks how its text
6
+ * was assembled. That question has an obvious blind spot, and until this file
7
+ * existed the command-injection rule sat squarely in it:
8
+ *
9
+ * os.system("ls " + name) <- the argument IS the build. Reported.
10
+ *
11
+ * cmd = "ls " + name
12
+ * os.system(cmd) <- the argument is a NAME. Silent.
13
+ *
14
+ * Same code, same risk, one line break apart - in every language. In C it was
15
+ * worse than a blind spot: C has no `+` for strings, so a command is ALWAYS
16
+ * formatted into a buffer first and run afterwards, and the signature pass saw
17
+ * `system(buf)` every single time.
18
+ *
19
+ * WHAT THIS DOES, AND ON PURPOSE WHAT IT DOES NOT.
20
+ *
21
+ * Given a bare name at a call site, it looks back through the SAME function for
22
+ * the writes that reach the call, in straight-line code:
23
+ *
24
+ * a RESET replaces the value cmd = ... char cmd[] = ... sprintf(cmd, ...)
25
+ * an EXTEND appends to it cmd += ... strcat(cmd, ...) cmd.append(...)
26
+ *
27
+ * The value at the call is the LAST reset plus every extend after it. That is
28
+ * what makes `cmd = "ls " + name; cmd = "ls -l"; system(cmd)` quiet: the build
29
+ * that spliced `name` in was overwritten before the call ran.
30
+ *
31
+ * It gives up - returns null, which leaves the rule exactly as quiet as it was
32
+ * before - whenever the answer would depend on which way the program went:
33
+ *
34
+ * - any write to the name sits under an if, a loop, a switch or a try;
35
+ * - there is no reset in this function at all (a parameter, a global);
36
+ * - the write is a shape this file has not been taught.
37
+ *
38
+ * Giving up is the safe direction for a SIGNATURE rule in the narrow sense that
39
+ * it cannot add a false finding. It is not free: every one of those is a guess
40
+ * the rule could have made and did not. The coverage notes say so, rather than
41
+ * letting "implemented" imply the conditional case is covered too.
42
+ *
43
+ * It never evaluates anything. It describes how the text was put together,
44
+ * which is all a signature rule is entitled to know.
45
+ */
46
+ import { analyzeStringExpression } from './strings.js';
47
+ /** Where a function's own writes stop. A nested function is a different scope. */
48
+ const FUNCTION_NODES = new Set([
49
+ 'function_declaration', 'function_expression', 'arrow_function', 'method_definition',
50
+ 'function_definition', 'lambda', 'lambda_expression',
51
+ 'method_declaration', 'constructor_declaration',
52
+ 'func_literal', 'anonymous_function_creation_expression',
53
+ ]);
54
+ /*
55
+ * Control flow, matched on the node-type NAME across all eight grammars, because
56
+ * eight grammars spell it eight ways (if_statement, elif_clause,
57
+ * expression_switch_statement, enhanced_for_statement, for_range_loop,
58
+ * switch_block_statement_group, catch_clause, except_clause...). A type this
59
+ * pattern wrongly calls conditional only makes the helper give up - it cannot
60
+ * make it report something it would not otherwise have reported.
61
+ */
62
+ const CONTROL_FLOW = /(^|_)(if|else|elif|switch|case|for|foreach|while|do|try|catch|except|finally|match|conditional|ternary)(_|$)/;
63
+ /* C's output-parameter writers. The destination is always argument 0. */
64
+ const C_FORMAT_WRITERS = {
65
+ sprintf: 1, vsprintf: 1, snprintf: 2, vsnprintf: 2, // value: index of the format string
66
+ };
67
+ const C_COPY_RESETS = new Set(['strcpy', 'strncpy', 'strlcpy']);
68
+ const C_APPENDS = new Set(['strcat', 'strncat', 'strlcat']);
69
+ /* C++ std::string members that replace or extend the receiver. */
70
+ const CPP_MEMBER_RESETS = new Set(['assign']);
71
+ const CPP_MEMBER_APPENDS = new Set(['append']);
72
+ /*
73
+ * `.c_str()` and `.data()` do nothing to the text; they hand a std::string over
74
+ * in the shape a C API wants. std::system() takes a `const char*`, so EVERY C++
75
+ * shell call ends in one of these, and to the signature pass a method call was
76
+ * an opaque value - which is why even the one-line form was silent:
77
+ *
78
+ * std::system(("ls " + name).c_str());
79
+ */
80
+ const TRANSPARENT_METHODS = new Set(['c_str', 'data']);
81
+ const lineOf = (node) => node.startPosition.row + 1;
82
+ const same = (a, b) => a !== null && b !== null && a.startIndex === b.startIndex && a.endIndex === b.endIndex;
83
+ /** The bare name a declarator or assignment target binds: `cmd`, `buf[256]`, `*p`, `$cmd`. */
84
+ function boundName(target) {
85
+ let current = target;
86
+ for (let depth = 0; current && depth < 6; depth++) {
87
+ if (current.type === 'identifier' || current.type === 'variable_name') {
88
+ return (current.text ?? '').replace(/^\$/, '');
89
+ }
90
+ // array_declarator, pointer_declarator, reference_declarator, expression_list
91
+ current = current.childForFieldName('declarator') ?? current.namedChildren[0] ?? null;
92
+ }
93
+ return null;
94
+ }
95
+ /** Strip parentheses and `.c_str()` / `.data()` - wrappers that do not change the text. */
96
+ function unwrap(node) {
97
+ let current = node;
98
+ for (let depth = 0; depth < 6; depth++) {
99
+ if (current.type === 'parenthesized_expression' && current.namedChildren.length === 1) {
100
+ current = current.namedChildren[0] ?? current;
101
+ continue;
102
+ }
103
+ if (current.type === 'call_expression') {
104
+ const fn = current.childForFieldName('function');
105
+ const args = current.childForFieldName('arguments');
106
+ const field = fn?.childForFieldName('field')?.text ?? '';
107
+ const receiver = fn?.childForFieldName('argument') ?? null;
108
+ if (fn?.type === 'field_expression' && TRANSPARENT_METHODS.has(field) && receiver &&
109
+ (args?.namedChildren.length ?? 0) === 0) {
110
+ current = receiver;
111
+ continue;
112
+ }
113
+ }
114
+ break;
115
+ }
116
+ return current;
117
+ }
118
+ /*
119
+ * THE FORMAT STRING IS A TYPE DECLARATION.
120
+ *
121
+ * `%d` can only ever emit digits and a sign, so it cannot carry a semicolon, a
122
+ * pipe or a backtick however hostile the integer is. `%s` and `%c` splice text.
123
+ * So `snprintf(buf, n, "kill -9 %d", pid)` is not a built command in any sense
124
+ * that matters to a shell, and `snprintf(buf, n, "ls %s", name)` is.
125
+ *
126
+ * A format string that is not itself a literal is the worst case of all - the
127
+ * caller controls the shape of the command - and is reported as dynamic.
128
+ */
129
+ const SPECIFIER = /%[-+ #0]*(\*|\d+)?(?:\.(\*|\d+))?(?:hh|h|ll|l|j|z|t|L)?([diouxXeEfFgGaAcspn%])/g;
130
+ function formatPiece(call, language, formatIndex, isVa) {
131
+ const args = (call.childForFieldName('arguments')?.namedChildren ?? []).filter((c) => c !== null);
132
+ const format = args[formatIndex];
133
+ if (!format)
134
+ return { isDynamic: false, mechanism: 'literal', literalText: '', dynamicParts: [] };
135
+ const fmt = analyzeStringExpression(format, language);
136
+ if (fmt.isDynamic) {
137
+ return { isDynamic: true, mechanism: 'format-call', literalText: '', dynamicParts: [format.text ?? ''] };
138
+ }
139
+ const dynamicParts = [];
140
+ let argCursor = formatIndex + 1;
141
+ for (const match of fmt.literalText.matchAll(SPECIFIER)) {
142
+ const [, width, precision, conversion] = match;
143
+ if (conversion === '%')
144
+ continue;
145
+ if (width === '*')
146
+ argCursor++;
147
+ if (precision === '*')
148
+ argCursor++;
149
+ const value = args[argCursor++];
150
+ if (conversion !== 's' && conversion !== 'c')
151
+ continue; // numeric: cannot splice text
152
+ if (isVa) {
153
+ dynamicParts.push('va_list');
154
+ continue;
155
+ }
156
+ if (!value)
157
+ continue;
158
+ const piece = analyzeStringExpression(value, language);
159
+ if (piece.isDynamic)
160
+ dynamicParts.push((value.text ?? '').trim().slice(0, 60));
161
+ }
162
+ return {
163
+ isDynamic: dynamicParts.length > 0,
164
+ mechanism: dynamicParts.length > 0 ? 'format-call' : 'literal',
165
+ literalText: fmt.literalText.replace(SPECIFIER, ''),
166
+ dynamicParts,
167
+ };
168
+ }
169
+ /** Classify one node as a write to `name`, or null if it is not one. */
170
+ function writeTo(node, name, language) {
171
+ const piece = (value) => value ? analyzeStringExpression(unwrap(value), language) : null;
172
+ // Declarations with an initialiser: JS/TS/Java variable_declarator, C/C++ init_declarator, Go var_spec.
173
+ if (node.type === 'variable_declarator' || node.type === 'init_declarator' || node.type === 'var_spec') {
174
+ const target = node.childForFieldName('name') ?? node.childForFieldName('declarator');
175
+ const value = node.childForFieldName('value');
176
+ if (boundName(target) !== name || !value)
177
+ return null;
178
+ const p = piece(value);
179
+ return p ? { kind: 'reset', node, piece: p } : null;
180
+ }
181
+ // Assignment, plain or compound. The operator decides reset versus extend.
182
+ if (node.type === 'assignment' || node.type === 'assignment_expression' ||
183
+ node.type === 'augmented_assignment' || node.type === 'augmented_assignment_expression' ||
184
+ node.type === 'assignment_statement' || node.type === 'short_var_declaration') {
185
+ const target = node.childForFieldName('left');
186
+ const value = node.childForFieldName('right');
187
+ if (!target || !value)
188
+ return null;
189
+ if ((target.text ?? '').trim().replace(/^\$/, '') !== name)
190
+ return null;
191
+ const operator = (node.childForFieldName('operator')?.text ?? '=').trim();
192
+ const p = piece(value);
193
+ if (!p)
194
+ return null;
195
+ if (operator === '=' || operator === ':=')
196
+ return { kind: 'reset', node, piece: p };
197
+ if (operator === '+=' || operator === '.=')
198
+ return { kind: 'extend', node, piece: p };
199
+ return null; // some other compound operator: not a string build this knows
200
+ }
201
+ if (node.type !== 'call_expression')
202
+ return null;
203
+ const fn = node.childForFieldName('function');
204
+ const args = (node.childForFieldName('arguments')?.namedChildren ?? []).filter((c) => c !== null);
205
+ // C++ members on the string itself: cmd.append(x), cmd.assign(x).
206
+ if (fn?.type === 'field_expression') {
207
+ const receiver = fn.childForFieldName('argument');
208
+ const member = fn.childForFieldName('field')?.text ?? '';
209
+ if ((receiver?.text ?? '').trim() !== name)
210
+ return null;
211
+ const p = piece(args[0] ?? null);
212
+ if (!p)
213
+ return null;
214
+ if (CPP_MEMBER_APPENDS.has(member))
215
+ return { kind: 'extend', node, piece: p };
216
+ if (CPP_MEMBER_RESETS.has(member))
217
+ return { kind: 'reset', node, piece: p };
218
+ return null;
219
+ }
220
+ // C's output-parameter idiom: the buffer is argument 0.
221
+ if (language !== 'c' && language !== 'cpp')
222
+ return null;
223
+ const callee = (fn?.text ?? '').split('::').pop() ?? '';
224
+ if ((args[0]?.text ?? '').trim() !== name)
225
+ return null;
226
+ if (callee in C_FORMAT_WRITERS) {
227
+ return {
228
+ kind: 'reset',
229
+ node,
230
+ piece: formatPiece(node, language, C_FORMAT_WRITERS[callee] ?? 1, callee.startsWith('v')),
231
+ };
232
+ }
233
+ const p = piece(args[1] ?? null);
234
+ if (!p)
235
+ return null;
236
+ if (C_COPY_RESETS.has(callee))
237
+ return { kind: 'reset', node, piece: p };
238
+ if (C_APPENDS.has(callee))
239
+ return { kind: 'extend', node, piece: p };
240
+ return null;
241
+ }
242
+ /** Is `node` inside a branch, loop or try between itself and the function body? */
243
+ function underControlFlow(node, body) {
244
+ let current = node.parent;
245
+ while (current && !same(current, body)) {
246
+ if (CONTROL_FLOW.test(current.type))
247
+ return true;
248
+ current = current.parent;
249
+ }
250
+ return false;
251
+ }
252
+ /**
253
+ * Follow the argument of a dangerous call back to how its text was built.
254
+ * Returns null when there is nothing to follow, or when following it would
255
+ * need to know which way the program went.
256
+ */
257
+ export function followLocalBuild(arg, language) {
258
+ const target = unwrap(arg);
259
+ // Unwrapping alone can expose an inline build: std::system(("ls " + x).c_str()).
260
+ if (!same(target, arg) && target.type !== 'identifier') {
261
+ return { expression: analyzeStringExpression(target, language), line: lineOf(target) };
262
+ }
263
+ if (target.type !== 'identifier' && target.type !== 'variable_name')
264
+ return null;
265
+ const name = (target.text ?? '').replace(/^\$/, '');
266
+ let body = arg.parent;
267
+ while (body && !FUNCTION_NODES.has(body.type))
268
+ body = body.parent;
269
+ if (!body)
270
+ return null;
271
+ const writes = [];
272
+ let unsafe = false;
273
+ const visit = (node) => {
274
+ if (unsafe || node.startIndex >= arg.startIndex)
275
+ return;
276
+ if (!same(node, body) && FUNCTION_NODES.has(node.type))
277
+ return; // a nested function
278
+ const write = writeTo(node, name, language);
279
+ if (write) {
280
+ if (underControlFlow(node, body))
281
+ unsafe = true;
282
+ else
283
+ writes.push(write);
284
+ return;
285
+ }
286
+ for (const child of node.namedChildren)
287
+ if (child)
288
+ visit(child);
289
+ };
290
+ visit(body);
291
+ if (unsafe)
292
+ return null;
293
+ let start = -1;
294
+ for (let i = writes.length - 1; i >= 0; i--) {
295
+ if (writes[i]?.kind === 'reset') {
296
+ start = i;
297
+ break;
298
+ }
299
+ }
300
+ if (start < 0)
301
+ return null; // a parameter or a global: nothing here says how it was built
302
+ const pieces = writes.slice(start).map((w) => w.piece);
303
+ const first = writes[start];
304
+ if (pieces.length === 1)
305
+ return { expression: pieces[0], line: lineOf(first.node) };
306
+ const dynamicParts = pieces.flatMap((p) => [...p.dynamicParts]);
307
+ const literalText = pieces.map((p) => p.literalText).join('');
308
+ const mechanism = pieces.some((p) => p.mechanism === 'interpolation')
309
+ ? 'interpolation'
310
+ : pieces.some((p) => p.mechanism === 'format-call')
311
+ ? 'format-call'
312
+ : dynamicParts.length > 0
313
+ ? 'concatenation'
314
+ : 'literal';
315
+ return {
316
+ expression: { isDynamic: mechanism !== 'literal', mechanism, literalText, dynamicParts },
317
+ line: lineOf(first.node),
318
+ };
319
+ }
320
+ //# sourceMappingURL=local-build.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-build.js","sourceRoot":"","sources":["../../../../src/rules/lib/local-build.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,208 @@
1
+ /**
2
+ * STRING BUILDING ANALYSIS
3
+ * ========================
4
+ *
5
+ * Almost every injection bug in this tool's catalogue has the same skeleton:
6
+ * a string was ASSEMBLED at runtime and then handed to something that treats
7
+ * strings as instructions (a database, a shell, a browser).
8
+ *
9
+ * So the one question we ask over and over is: "was this expression a fixed
10
+ * piece of text, or was it stitched together from parts?" This file answers it
11
+ * for all five languages, and it is the piece of shared machinery that lets one
12
+ * rule cover JavaScript, Python, Java and Go at once.
13
+ *
14
+ * VOCABULARY YOU'LL NEED:
15
+ *
16
+ * Sanitisation - cleaning or neutralising untrusted input before use. For SQL
17
+ * the real fix is not cleaning at all but PARAMETERISATION: you hand the
18
+ * database the query and the values separately, so the values can never be
19
+ * read as commands. For HTML it means escaping < > & " so text is displayed
20
+ * rather than executed.
21
+ *
22
+ * Interpolation - languages' built-in "put this value inside this string"
23
+ * syntax: `${x}` in JS, f"{x}" in Python, fmt.Sprintf("%s", x) in Go.
24
+ * To a database or a shell it is identical to concatenation. Feeling
25
+ * modern does not make it safe.
26
+ *
27
+ * PHASE 1 HONESTY NOTE: knowing a string was built dynamically does NOT mean
28
+ * the parts came from an attacker. `"SELECT * FROM " + TABLE_NAME` with a
29
+ * hard-coded constant is fine. We cannot tell the difference without data-flow
30
+ * analysis, which is Phase 3. That is exactly why these findings are labelled
31
+ * signature-based, and why every one of them says so in its `limitations`.
32
+ */
33
+ import type { Node } from 'web-tree-sitter';
34
+ import type { LanguageId } from '../../parse/languages.js';
35
+ import type { StaticMethodLookup } from '../contract.js';
36
+ export type BuildMechanism = 'literal' | 'concatenation' | 'interpolation' | 'format-call' | 'opaque';
37
+ export interface StringExpression {
38
+ /** True when the text is not fully known at write time. */
39
+ readonly isDynamic: boolean;
40
+ readonly mechanism: BuildMechanism;
41
+ /** The fixed parts we could read, joined. Empty when the whole thing is opaque. */
42
+ readonly literalText: string;
43
+ /** The expressions spliced in. Reported so a human can judge them. */
44
+ readonly dynamicParts: readonly string[];
45
+ }
46
+ /**
47
+ * True when this node could plausibly evaluate to a string that was assembled.
48
+ * Object literals, arrays, functions and class bodies return false - they are
49
+ * containers, not strings, even though they contain strings.
50
+ */
51
+ export declare function isStringBuildingExpression(node: Node, language: LanguageId): boolean;
52
+ export declare function isStringLiteral(node: Node, language: LanguageId): boolean;
53
+ /** Remove surrounding quotes, backticks and prefixes (f"", b'', @"", `` ). */
54
+ export declare function unquote(raw: string): string;
55
+ /**
56
+ * Read an expression and describe how its text was assembled.
57
+ *
58
+ * The walk is deliberately shallow (depth-limited) and deliberately simple: it
59
+ * collects three things - fixed text chunks, evidence of splicing, and the
60
+ * spliced expressions - and infers the mechanism from what it found. It does
61
+ * NOT try to evaluate the expression. A scanner that guesses at runtime values
62
+ * is a scanner that lies.
63
+ */
64
+ export declare function analyzeStringExpression(node: Node, language: LanguageId, maxDepth?: number): StringExpression;
65
+ /**
66
+ * SQL needs the SHAPE of a statement, not a scattering of keywords.
67
+ * Conservative on purpose: a fragment we cannot recognise is reported as
68
+ * "not SQL", which loses a finding rather than inventing one.
69
+ */
70
+ export declare function looksLikeSql(text: string): boolean;
71
+ export declare function looksLikeHtml(text: string): boolean;
72
+ /**
73
+ * Shannon entropy: a number for "how random does this look?".
74
+ * Roughly - English prose scores ~2.5-3.5 bits/char, a base64 API key ~4.5-6.
75
+ * It is a hint, never a verdict, and we say so in the finding.
76
+ */
77
+ export declare function shannonEntropy(text: string): number;
78
+ /**
79
+ * Is this value STRUCTURALLY incapable of being a credential, whatever the
80
+ * variable holding it is called?
81
+ *
82
+ * The name-based signal ("the variable is called `token`") never asked this,
83
+ * and VS Code's editor package showed why: 151 of its 163 high-severity secret
84
+ * findings were Monaco's syntax-highlighting tokens.
85
+ *
86
+ * token: 'delimiter.curly'
87
+ * token: 'variable.predefined'
88
+ * token: 'comment'
89
+ *
90
+ * The variable really is called `token`. The value is a theme scope name. No
91
+ * amount of suspicion about the NAME should survive looking at the VALUE.
92
+ *
93
+ * Two shapes, both decidable:
94
+ * - a dotted namespace (`delimiter.curly`, `com.example.thing`) - no key
95
+ * format contains dots, except a JWT, which starts `eyJ`;
96
+ * - a single lowercase dictionary-shaped word (`comment`, `invalid`) - real
97
+ * credentials mix character classes, because they are generated.
98
+ */
99
+ export declare function isStructuralIdentifier(value: string): boolean;
100
+ /**
101
+ * Does this spliced-in expression produce nothing but SQL PLACEHOLDERS?
102
+ *
103
+ * VS Code builds a bulk insert the correct way:
104
+ *
105
+ * `INSERT INTO ItemTable VALUES ${new Array(n).fill('(?,?)').join(',')} ...`
106
+ * stmt.run(keysValuesChunk)
107
+ *
108
+ * The interpolation expands to `(?,?),(?,?),(?,?)`. Not one byte of data is in
109
+ * that string - the values go to the driver separately, which is exactly what
110
+ * parameterisation means. And the rule reported it as SQL injection.
111
+ *
112
+ * That is the worst mistake an injection rule can make. Flagging the CORRECT
113
+ * form teaches people that doing it properly does not help, and this is the
114
+ * third time today the same failure has turned up in a different rule -
115
+ * unserialize with allowed_classes, yaml with a SafeLoader, and now this.
116
+ *
117
+ * The test is narrow on purpose. Every string literal inside the expression
118
+ * must be placeholder punctuation, AND at least one must contain an actual
119
+ * placeholder marker (`?`, `$1`, `%s`). That second half is what stops
120
+ * `rows.map(r => `'${r}'`).join(',')` - which builds real quoted DATA and is a
121
+ * genuine injection - from slipping through on its commas.
122
+ */
123
+ export declare function expandsOnlyPlaceholders(expressionText: string): boolean;
124
+ export declare function isLikelyPlaceholder(text: string): boolean;
125
+ /**
126
+ * "Could this string plausibly BE a credential?" - a structural gate we apply
127
+ * before the entropy heuristic.
128
+ *
129
+ * This function exists because of measurement, not theory. Running the entropy
130
+ * check alone against five real open-source repositories produced 80 findings,
131
+ * and the top offenders were things like:
132
+ *
133
+ * 'application/x-www-form-urlencoded' a MIME type
134
+ * 'abcdefghijklmnopqrstuvwxyz' a literal alphabet
135
+ * 'https://images.opencollective.com/…' a URL
136
+ *
137
+ * All three score high on randomness and none of them is a secret. Real tokens
138
+ * share a shape: no spaces, no slashes, and a MIX of character classes. Testing
139
+ * for that shape first removes the whole category of noise above without
140
+ * weakening detection of anything that actually looks like a key.
141
+ */
142
+ export declare function looksLikeToken(value: string): boolean;
143
+ /**
144
+ * Paths that mean "this is a fixture, not production configuration".
145
+ * A credential in a test file is still a credential in git history, so we do
146
+ * not drop these findings - we lower their severity and say why.
147
+ */
148
+ export declare function isTestPath(filePath: string): boolean;
149
+ /**
150
+ * Is this value just a restatement of the NAME it is stored under?
151
+ *
152
+ * PRIVATE_KEY_KEY = "privateKey" Keycloak, 4,000 Java files
153
+ * KEYSTORE_PASSWORD_KEY = "keystorePassword"
154
+ * MANAGE_OAUTH = "manage_oauth" Mattermost, TypeScript
155
+ * TOKEN_CREATING = "creating"
156
+ * SECTION_TOKENS = "tokens"
157
+ *
158
+ * These are the strings a program uses to LOOK UP a secret in a config map, and
159
+ * they are dense in exactly the codebases that handle credentials for a living
160
+ * - which is why an identity server produced 152 findings and most were this.
161
+ *
162
+ * The test is a subset check on words, which is what makes it safe: a real
163
+ * credential shares no vocabulary with its own variable name. `password =
164
+ * "Tr0ub4dor3xK"`, `SECRET_KEY = "config"` and `password = "configpass"` all
165
+ * survive it, and all three are asserted elsewhere in the suite.
166
+ *
167
+ * Requires at least one word on each side, so an empty or punctuation-only
168
+ * value cannot vacuously qualify.
169
+ */
170
+ export declare function echoesItsOwnName(name: string, value: string): boolean;
171
+ export declare function looksLikeProse(name: string, value: string): boolean;
172
+ /** Well-known credential formats. A hit here is far stronger than entropy alone. */
173
+ export interface KnownSecretFormat {
174
+ readonly label: string;
175
+ readonly pattern: RegExp;
176
+ }
177
+ export declare const KNOWN_SECRET_FORMATS: readonly KnownSecretFormat[];
178
+ /**
179
+ * True when a value matches a vendor key format but is a published,
180
+ * deliberately non-functional documentation example rather than a credential.
181
+ *
182
+ * Pass the MATCHED KEY, not the string it was found in. The first version of
183
+ * this tested the whole enclosing string, so a demo code sample containing
184
+ * `AKIAIOSFODNN7EXAMPLE` in the middle of two hundred other characters never
185
+ * matched the `...EXAMPLE$` anchor and was still reported as a live key. The
186
+ * question is about the credential, so it has to be asked of the credential.
187
+ */
188
+ export declare function isVendorDocExample(matchedKey: string): boolean;
189
+ export declare function matchKnownSecret(text: string): KnownSecretFormat | null;
190
+ /** Why a string built from pieces is still provably fixed - or null when it is not. */
191
+ export interface ConstantProof {
192
+ /**
193
+ * True when the proof needed control-flow reasoning - a branch that cannot
194
+ * run, a condition decided at compile time, a ternary whose every arm is a
195
+ * literal - rather than "every binding is a plain literal". Only reasoned
196
+ * proofs leave a receipt, because only reasoning can be wrong.
197
+ */
198
+ readonly reasoned: boolean;
199
+ /** One sentence per name, written so a reader can check it against the code. */
200
+ readonly reason: string;
201
+ }
202
+ export interface ConstantProofOptions {
203
+ /** RuleContext.staticMethod. Absent: no helper in another file is read. */
204
+ readonly staticMethod?: StaticMethodLookup | undefined;
205
+ /** RuleContext.javaTypeInScan. Absent: every supertype is assumed to be in the scan. */
206
+ readonly javaTypeInScan?: ((simpleName: string) => boolean) | undefined;
207
+ }
208
+ export declare function constantProof(node: Node, dynamicParts: readonly string[], language: LanguageId, options?: ConstantProofOptions): ConstantProof | null;