insa-check-core 0.1.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 (258) hide show
  1. package/LICENSE +24 -0
  2. package/dist/annex-b.d.ts +6 -0
  3. package/dist/annex-b.d.ts.map +1 -0
  4. package/dist/annex-b.js +152 -0
  5. package/dist/annex-b.js.map +1 -0
  6. package/dist/checks/content/page.d.ts +7 -0
  7. package/dist/checks/content/page.d.ts.map +1 -0
  8. package/dist/checks/content/page.js +133 -0
  9. package/dist/checks/content/page.js.map +1 -0
  10. package/dist/checks/cookies/cookie-flags.d.ts +3 -0
  11. package/dist/checks/cookies/cookie-flags.d.ts.map +1 -0
  12. package/dist/checks/cookies/cookie-flags.js +41 -0
  13. package/dist/checks/cookies/cookie-flags.js.map +1 -0
  14. package/dist/checks/cookies/cookie-scope.d.ts +6 -0
  15. package/dist/checks/cookies/cookie-scope.d.ts.map +1 -0
  16. package/dist/checks/cookies/cookie-scope.js +60 -0
  17. package/dist/checks/cookies/cookie-scope.js.map +1 -0
  18. package/dist/checks/deployment/server-banner.d.ts +4 -0
  19. package/dist/checks/deployment/server-banner.d.ts.map +1 -0
  20. package/dist/checks/deployment/server-banner.js +60 -0
  21. package/dist/checks/deployment/server-banner.js.map +1 -0
  22. package/dist/checks/deployment/trace.d.ts +3 -0
  23. package/dist/checks/deployment/trace.d.ts.map +1 -0
  24. package/dist/checks/deployment/trace.js +30 -0
  25. package/dist/checks/deployment/trace.js.map +1 -0
  26. package/dist/checks/headers/clickjacking.d.ts +5 -0
  27. package/dist/checks/headers/clickjacking.d.ts.map +1 -0
  28. package/dist/checks/headers/clickjacking.js +57 -0
  29. package/dist/checks/headers/clickjacking.js.map +1 -0
  30. package/dist/checks/headers/content-type-options.d.ts +3 -0
  31. package/dist/checks/headers/content-type-options.d.ts.map +1 -0
  32. package/dist/checks/headers/content-type-options.js +17 -0
  33. package/dist/checks/headers/content-type-options.js.map +1 -0
  34. package/dist/checks/headers/cors.d.ts +4 -0
  35. package/dist/checks/headers/cors.d.ts.map +1 -0
  36. package/dist/checks/headers/cors.js +38 -0
  37. package/dist/checks/headers/cors.js.map +1 -0
  38. package/dist/checks/html.d.ts +11 -0
  39. package/dist/checks/html.d.ts.map +1 -0
  40. package/dist/checks/html.js +30 -0
  41. package/dist/checks/html.js.map +1 -0
  42. package/dist/checks/index.d.ts +7 -0
  43. package/dist/checks/index.d.ts.map +1 -0
  44. package/dist/checks/index.js +48 -0
  45. package/dist/checks/index.js.map +1 -0
  46. package/dist/checks/info-disclosure/directory-listing.d.ts +6 -0
  47. package/dist/checks/info-disclosure/directory-listing.d.ts.map +1 -0
  48. package/dist/checks/info-disclosure/directory-listing.js +60 -0
  49. package/dist/checks/info-disclosure/directory-listing.js.map +1 -0
  50. package/dist/checks/info-disclosure/exposed-files.d.ts +4 -0
  51. package/dist/checks/info-disclosure/exposed-files.d.ts.map +1 -0
  52. package/dist/checks/info-disclosure/exposed-files.js +56 -0
  53. package/dist/checks/info-disclosure/exposed-files.js.map +1 -0
  54. package/dist/checks/info-disclosure/more.d.ts +8 -0
  55. package/dist/checks/info-disclosure/more.d.ts.map +1 -0
  56. package/dist/checks/info-disclosure/more.js +186 -0
  57. package/dist/checks/info-disclosure/more.js.map +1 -0
  58. package/dist/checks/tls/certificate.d.ts +3 -0
  59. package/dist/checks/tls/certificate.d.ts.map +1 -0
  60. package/dist/checks/tls/certificate.js +49 -0
  61. package/dist/checks/tls/certificate.js.map +1 -0
  62. package/dist/checks/tls/hsts.d.ts +5 -0
  63. package/dist/checks/tls/hsts.d.ts.map +1 -0
  64. package/dist/checks/tls/hsts.js +35 -0
  65. package/dist/checks/tls/hsts.js.map +1 -0
  66. package/dist/checks/tls/https-redirect.d.ts +3 -0
  67. package/dist/checks/tls/https-redirect.d.ts.map +1 -0
  68. package/dist/checks/tls/https-redirect.js +46 -0
  69. package/dist/checks/tls/https-redirect.js.map +1 -0
  70. package/dist/checks/tls/legacy-protocols.d.ts +3 -0
  71. package/dist/checks/tls/legacy-protocols.d.ts.map +1 -0
  72. package/dist/checks/tls/legacy-protocols.js +27 -0
  73. package/dist/checks/tls/legacy-protocols.js.map +1 -0
  74. package/dist/checks/util.d.ts +22 -0
  75. package/dist/checks/util.d.ts.map +1 -0
  76. package/dist/checks/util.js +63 -0
  77. package/dist/checks/util.js.map +1 -0
  78. package/dist/code/checks/crypto.d.ts +5 -0
  79. package/dist/code/checks/crypto.d.ts.map +1 -0
  80. package/dist/code/checks/crypto.js +100 -0
  81. package/dist/code/checks/crypto.js.map +1 -0
  82. package/dist/code/checks/django.d.ts +14 -0
  83. package/dist/code/checks/django.d.ts.map +1 -0
  84. package/dist/code/checks/django.js +313 -0
  85. package/dist/code/checks/django.js.map +1 -0
  86. package/dist/code/checks/flask.d.ts +6 -0
  87. package/dist/code/checks/flask.d.ts.map +1 -0
  88. package/dist/code/checks/flask.js +100 -0
  89. package/dist/code/checks/flask.js.map +1 -0
  90. package/dist/code/checks/index.d.ts +9 -0
  91. package/dist/code/checks/index.d.ts.map +1 -0
  92. package/dist/code/checks/index.js +126 -0
  93. package/dist/code/checks/index.js.map +1 -0
  94. package/dist/code/checks/injection.d.ts +27 -0
  95. package/dist/code/checks/injection.d.ts.map +1 -0
  96. package/dist/code/checks/injection.js +189 -0
  97. package/dist/code/checks/injection.js.map +1 -0
  98. package/dist/code/checks/javascript-config.d.ts +14 -0
  99. package/dist/code/checks/javascript-config.d.ts.map +1 -0
  100. package/dist/code/checks/javascript-config.js +251 -0
  101. package/dist/code/checks/javascript-config.js.map +1 -0
  102. package/dist/code/checks/javascript.d.ts +34 -0
  103. package/dist/code/checks/javascript.d.ts.map +1 -0
  104. package/dist/code/checks/javascript.js +333 -0
  105. package/dist/code/checks/javascript.js.map +1 -0
  106. package/dist/code/checks/php.d.ts +27 -0
  107. package/dist/code/checks/php.d.ts.map +1 -0
  108. package/dist/code/checks/php.js +433 -0
  109. package/dist/code/checks/php.js.map +1 -0
  110. package/dist/code/checks/secrets.d.ts +10 -0
  111. package/dist/code/checks/secrets.d.ts.map +1 -0
  112. package/dist/code/checks/secrets.js +140 -0
  113. package/dist/code/checks/secrets.js.map +1 -0
  114. package/dist/code/checks/shared.d.ts +25 -0
  115. package/dist/code/checks/shared.d.ts.map +1 -0
  116. package/dist/code/checks/shared.js +57 -0
  117. package/dist/code/checks/shared.js.map +1 -0
  118. package/dist/code/checks/treesitter.d.ts +15 -0
  119. package/dist/code/checks/treesitter.d.ts.map +1 -0
  120. package/dist/code/checks/treesitter.js +322 -0
  121. package/dist/code/checks/treesitter.js.map +1 -0
  122. package/dist/code/checks/xml.d.ts +9 -0
  123. package/dist/code/checks/xml.d.ts.map +1 -0
  124. package/dist/code/checks/xml.js +78 -0
  125. package/dist/code/checks/xml.js.map +1 -0
  126. package/dist/code/context.d.ts +6 -0
  127. package/dist/code/context.d.ts.map +1 -0
  128. package/dist/code/context.js +92 -0
  129. package/dist/code/context.js.map +1 -0
  130. package/dist/code/detect.d.ts +3 -0
  131. package/dist/code/detect.d.ts.map +1 -0
  132. package/dist/code/detect.js +118 -0
  133. package/dist/code/detect.js.map +1 -0
  134. package/dist/code/django/settings.d.ts +46 -0
  135. package/dist/code/django/settings.d.ts.map +1 -0
  136. package/dist/code/django/settings.js +154 -0
  137. package/dist/code/django/settings.js.map +1 -0
  138. package/dist/code/findings.d.ts +18 -0
  139. package/dist/code/findings.d.ts.map +1 -0
  140. package/dist/code/findings.js +63 -0
  141. package/dist/code/findings.js.map +1 -0
  142. package/dist/code/javascript/ast.d.ts +46 -0
  143. package/dist/code/javascript/ast.d.ts.map +1 -0
  144. package/dist/code/javascript/ast.js +166 -0
  145. package/dist/code/javascript/ast.js.map +1 -0
  146. package/dist/code/javascript/index.d.ts +3 -0
  147. package/dist/code/javascript/index.d.ts.map +1 -0
  148. package/dist/code/javascript/index.js +3 -0
  149. package/dist/code/javascript/index.js.map +1 -0
  150. package/dist/code/javascript/module.d.ts +59 -0
  151. package/dist/code/javascript/module.d.ts.map +1 -0
  152. package/dist/code/javascript/module.js +250 -0
  153. package/dist/code/javascript/module.js.map +1 -0
  154. package/dist/code/php/index.d.ts +92 -0
  155. package/dist/code/php/index.d.ts.map +1 -0
  156. package/dist/code/php/index.js +316 -0
  157. package/dist/code/php/index.js.map +1 -0
  158. package/dist/code/project.d.ts +13 -0
  159. package/dist/code/project.d.ts.map +1 -0
  160. package/dist/code/project.js +69 -0
  161. package/dist/code/project.js.map +1 -0
  162. package/dist/code/python/ast.d.ts +47 -0
  163. package/dist/code/python/ast.d.ts.map +1 -0
  164. package/dist/code/python/ast.js +193 -0
  165. package/dist/code/python/ast.js.map +1 -0
  166. package/dist/code/python/index.d.ts +3 -0
  167. package/dist/code/python/index.d.ts.map +1 -0
  168. package/dist/code/python/index.js +3 -0
  169. package/dist/code/python/index.js.map +1 -0
  170. package/dist/code/python/module.d.ts +55 -0
  171. package/dist/code/python/module.d.ts.map +1 -0
  172. package/dist/code/python/module.js +215 -0
  173. package/dist/code/python/module.js.map +1 -0
  174. package/dist/code/scan.d.ts +24 -0
  175. package/dist/code/scan.d.ts.map +1 -0
  176. package/dist/code/scan.js +159 -0
  177. package/dist/code/scan.js.map +1 -0
  178. package/dist/code/treesitter/index.d.ts +83 -0
  179. package/dist/code/treesitter/index.d.ts.map +1 -0
  180. package/dist/code/treesitter/index.js +243 -0
  181. package/dist/code/treesitter/index.js.map +1 -0
  182. package/dist/code/types.d.ts +48 -0
  183. package/dist/code/types.d.ts.map +1 -0
  184. package/dist/code/types.js +2 -0
  185. package/dist/code/types.js.map +1 -0
  186. package/dist/content/en.d.ts +3 -0
  187. package/dist/content/en.d.ts.map +1 -0
  188. package/dist/content/en.js +722 -0
  189. package/dist/content/en.js.map +1 -0
  190. package/dist/content/index.d.ts +15 -0
  191. package/dist/content/index.d.ts.map +1 -0
  192. package/dist/content/index.js +21 -0
  193. package/dist/content/index.js.map +1 -0
  194. package/dist/content/types.d.ts +87 -0
  195. package/dist/content/types.d.ts.map +1 -0
  196. package/dist/content/types.js +2 -0
  197. package/dist/content/types.js.map +1 -0
  198. package/dist/engine.d.ts +52 -0
  199. package/dist/engine.d.ts.map +1 -0
  200. package/dist/engine.js +120 -0
  201. package/dist/engine.js.map +1 -0
  202. package/dist/index.d.ts +12 -0
  203. package/dist/index.d.ts.map +1 -0
  204. package/dist/index.js +11 -0
  205. package/dist/index.js.map +1 -0
  206. package/dist/meta.d.ts +4 -0
  207. package/dist/meta.d.ts.map +1 -0
  208. package/dist/meta.js +4 -0
  209. package/dist/meta.js.map +1 -0
  210. package/dist/net/context.d.ts +9 -0
  211. package/dist/net/context.d.ts.map +1 -0
  212. package/dist/net/context.js +62 -0
  213. package/dist/net/context.js.map +1 -0
  214. package/dist/net/guard.d.ts +16 -0
  215. package/dist/net/guard.d.ts.map +1 -0
  216. package/dist/net/guard.js +70 -0
  217. package/dist/net/guard.js.map +1 -0
  218. package/dist/net/http.d.ts +22 -0
  219. package/dist/net/http.d.ts.map +1 -0
  220. package/dist/net/http.js +114 -0
  221. package/dist/net/http.js.map +1 -0
  222. package/dist/net/tls.d.ts +15 -0
  223. package/dist/net/tls.d.ts.map +1 -0
  224. package/dist/net/tls.js +103 -0
  225. package/dist/net/tls.js.map +1 -0
  226. package/dist/report/html.d.ts +14 -0
  227. package/dist/report/html.d.ts.map +1 -0
  228. package/dist/report/html.js +210 -0
  229. package/dist/report/html.js.map +1 -0
  230. package/dist/report/index.d.ts +10 -0
  231. package/dist/report/index.d.ts.map +1 -0
  232. package/dist/report/index.js +10 -0
  233. package/dist/report/index.js.map +1 -0
  234. package/dist/report/manual.d.ts +62 -0
  235. package/dist/report/manual.d.ts.map +1 -0
  236. package/dist/report/manual.js +190 -0
  237. package/dist/report/manual.js.map +1 -0
  238. package/dist/report/merge.d.ts +8 -0
  239. package/dist/report/merge.d.ts.map +1 -0
  240. package/dist/report/merge.js +135 -0
  241. package/dist/report/merge.js.map +1 -0
  242. package/dist/report/summary.d.ts +10 -0
  243. package/dist/report/summary.d.ts.map +1 -0
  244. package/dist/report/summary.js +27 -0
  245. package/dist/report/summary.js.map +1 -0
  246. package/dist/report/validate.d.ts +3 -0
  247. package/dist/report/validate.d.ts.map +1 -0
  248. package/dist/report/validate.js +78 -0
  249. package/dist/report/validate.js.map +1 -0
  250. package/dist/types.d.ts +244 -0
  251. package/dist/types.d.ts.map +1 -0
  252. package/dist/types.js +2 -0
  253. package/dist/types.js.map +1 -0
  254. package/dist/validate.d.ts +4 -0
  255. package/dist/validate.d.ts.map +1 -0
  256. package/dist/validate.js +24 -0
  257. package/dist/validate.js.map +1 -0
  258. package/package.json +40 -0
@@ -0,0 +1,159 @@
1
+ import { stat } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { ANNEX_B, STANDARD } from "../annex-b.js";
4
+ import { evaluateRegistry, TOOL_NAME, TOOL_VERSION } from "../engine.js";
5
+ import { summarize } from "../report/summary.js";
6
+ import { CODE_CHECKS } from "./checks/index.js";
7
+ import { createCodeContext } from "./context.js";
8
+ import { detectProject } from "./detect.js";
9
+ import { discoverFiles } from "./project.js";
10
+ import { PythonUnavailableError } from "./python/index.js";
11
+ export class CodeScanError extends Error {
12
+ name = "CodeScanError";
13
+ }
14
+ /** Frameworks with their own rule set (see code/checks). Others are detected and reported; language rules still run. */
15
+ const SUPPORTED_FRAMEWORKS = ["django", "flask", "fastapi", "express", "koa", "fastify", "next", "nestjs", "laravel"];
16
+ /** Languages with a parser and rules. */
17
+ const SUPPORTED_LANGUAGES = ["python", "javascript", "php", "java", "csharp", "ruby", "go"];
18
+ const LABEL = {
19
+ python: "Python", javascript: "JavaScript/TypeScript", php: "PHP", java: "Java", csharp: "C#", ruby: "Ruby", go: "Go",
20
+ django: "Django", flask: "Flask", laravel: "Laravel", express: "Node server",
21
+ };
22
+ const SEVERITY = ["fail", "error", "manual", "pass"];
23
+ /**
24
+ * Several checks can decide one Annex item (one per language). Their results are combined:
25
+ * the worst status wins (fail > error > manual > pass) and findings are merged.
26
+ */
27
+ function combineOutcomes(parts) {
28
+ const status = SEVERITY.find((s) => parts.some((p) => p.outcome.status === s)) ?? "manual";
29
+ const label = (c) => (c.key.startsWith("ts-") ? "Java/C#/Ruby/Go" : (LABEL[c.appliesTo[0] ?? ""] ?? c.appliesTo[0] ?? c.key));
30
+ const findings = parts.flatMap((p) => p.outcome.findings ?? []);
31
+ const evidence = parts.flatMap((p) => p.outcome.evidence ?? []);
32
+ return {
33
+ status,
34
+ detail: parts.map((p) => `${label(p.check)}: ${p.outcome.detail}`).join(" | "),
35
+ ...(findings.length ? { findings } : {}),
36
+ ...(evidence.length ? { evidence } : {}),
37
+ };
38
+ }
39
+ /**
40
+ * Tier 2: statically analyse a local project directory. Source code is read from disk
41
+ * and parsed locally; nothing is sent anywhere. Returns the same 102-row Report as runScan().
42
+ */
43
+ export async function runCodeScan(dir, options = {}) {
44
+ const root = path.resolve(dir);
45
+ const info = await stat(root).catch(() => undefined);
46
+ if (!info?.isDirectory())
47
+ throw new CodeScanError(`Not a directory: ${dir}`);
48
+ const startedAt = new Date().toISOString();
49
+ const discovery = await discoverFiles(root, {
50
+ maxFiles: options.maxFiles ?? 20_000,
51
+ maxFileBytes: options.maxFileBytes ?? 1_000_000,
52
+ });
53
+ const ctx0 = createCodeContext(root, discovery.files, { language: null, languages: [], frameworks: [], evidence: [] });
54
+ const project = await detectProject(discovery.files, ctx0.read);
55
+ if (options.framework && !project.frameworks.includes(options.framework)) {
56
+ project.frameworks.unshift(options.framework);
57
+ project.evidence.push(`--framework ${options.framework} (forced)`);
58
+ if (options.framework === "django" || options.framework === "flask") {
59
+ project.language = "python";
60
+ if (!project.languages.includes("python"))
61
+ project.languages.unshift("python");
62
+ }
63
+ }
64
+ const ctx = { ...ctx0, project };
65
+ const notes = [];
66
+ let parseErrors = [];
67
+ if (project.languages.includes("python")) {
68
+ try {
69
+ parseErrors = (await ctx.python()).parseErrors;
70
+ }
71
+ catch (err) {
72
+ if (err instanceof PythonUnavailableError)
73
+ throw new CodeScanError(err.message);
74
+ throw err;
75
+ }
76
+ }
77
+ if (project.languages.includes("javascript"))
78
+ parseErrors = [...parseErrors, ...(await ctx.javascript()).parseErrors];
79
+ if (project.languages.includes("php"))
80
+ parseErrors = [...parseErrors, ...(await ctx.php()).parseErrors];
81
+ if (project.languages.some((l) => ["java", "csharp", "ruby", "go"].includes(l)))
82
+ parseErrors = [...parseErrors, ...(await ctx.treeSitter()).parseErrors];
83
+ const analysed = project.languages.filter((l) => SUPPORTED_LANGUAGES.includes(l));
84
+ const notAnalysed = project.languages.filter((l) => !SUPPORTED_LANGUAGES.includes(l));
85
+ const unsupported = project.frameworks.filter((f) => !SUPPORTED_FRAMEWORKS.includes(f));
86
+ if (analysed.length === 0)
87
+ notes.push("No supported source language found (Python, JavaScript/TypeScript, PHP, Java, C#, Ruby, Go); all code-based items are reported as manual.");
88
+ else
89
+ notes.push(`Analysed: ${analysed.map((l) => LABEL[l]).join(", ")}${project.frameworks.length ? ` (frameworks: ${project.frameworks.join(", ")})` : ""}.`);
90
+ if (notAnalysed.length)
91
+ notes.push(`${notAnalysed.map((l) => LABEL[l] ?? l).join(", ")} code is present but has no rules yet; it was not analysed.`);
92
+ if (analysed.includes("python") && !project.frameworks.some((f) => ["django", "flask", "fastapi"].includes(f))) {
93
+ notes.push("No Python web framework detected (Django, Flask, FastAPI); generic Python rules ran, framework-specific items are manual. Use --framework django to force Django.");
94
+ }
95
+ if (unsupported.length)
96
+ notes.push(`Detected ${unsupported.join(", ")}, which has no framework-specific rules yet; language rules still ran.`);
97
+ if (parseErrors.length)
98
+ notes.push(`${parseErrors.length} file(s) could not be parsed and were not analysed (see sources.code.parseErrors).`);
99
+ if (discovery.truncated)
100
+ notes.push(`File limit reached; only the first ${discovery.files.length} files were analysed.`);
101
+ notes.push("Static analysis reports patterns, not proven vulnerabilities. Review each finding; 'Pass' means no risky pattern was found.");
102
+ const checks = options.checks ?? CODE_CHECKS;
103
+ const kinds = [...project.languages, ...project.frameworks];
104
+ // Each check runs once per scan, even when used alone for one item and combined for another.
105
+ const runs = new Map();
106
+ const runOnce = (check) => {
107
+ let pending = runs.get(check.key);
108
+ if (!pending) {
109
+ pending = check.run(ctx).catch((err) => ({ status: "error", detail: `Could not complete: ${err.message}` }));
110
+ runs.set(check.key, pending);
111
+ }
112
+ return pending;
113
+ };
114
+ const results = await evaluateRegistry({
115
+ registry: options.registry ?? ANNEX_B,
116
+ kind: "code",
117
+ ctx,
118
+ checkTimeoutMs: options.checkTimeoutMs ?? 60_000,
119
+ resolve: (item) => {
120
+ const all = [item.checks?.code ?? []].flat().map((k) => checks.get(k)).filter((c) => !!c);
121
+ if (all.length === 0)
122
+ return undefined;
123
+ const applicable = all.filter((c) => c.appliesTo.some((a) => kinds.includes(a)));
124
+ if (applicable.length === 0) {
125
+ return `No code rule for this item applies to this project (${kinds.join(", ") || "unknown type"}). ${item.manualNote}`;
126
+ }
127
+ return {
128
+ key: applicable.map((c) => c.key).join("+"),
129
+ run: async () => {
130
+ const parts = await Promise.all(applicable.map(async (check) => ({ check, outcome: await runOnce(check) })));
131
+ return parts.length === 1 ? parts[0].outcome : combineOutcomes(parts);
132
+ },
133
+ };
134
+ },
135
+ onResult: options.onResult,
136
+ });
137
+ return {
138
+ tool: { name: TOOL_NAME, version: TOOL_VERSION },
139
+ standard: STANDARD,
140
+ target: `code: ${ctx.name}`,
141
+ sources: {
142
+ code: {
143
+ name: ctx.name,
144
+ language: project.language,
145
+ languages: project.languages,
146
+ frameworks: project.frameworks,
147
+ filesAnalyzed: discovery.files.length,
148
+ filesSkipped: discovery.skipped,
149
+ parseErrors,
150
+ },
151
+ },
152
+ notes,
153
+ startedAt,
154
+ finishedAt: new Date().toISOString(),
155
+ summary: summarize(results),
156
+ results,
157
+ };
158
+ }
159
+ //# sourceMappingURL=scan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan.js","sourceRoot":"","sources":["../../src/code/scan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAiB3D,MAAM,OAAO,aAAc,SAAQ,KAAK;IAC7B,IAAI,GAAG,eAAe,CAAC;CACjC;AAED,wHAAwH;AACxH,MAAM,oBAAoB,GAA2B,CAAC,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;AAC9I,yCAAyC;AACzC,MAAM,mBAAmB,GAAwB,CAAC,QAAQ,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;AACjH,MAAM,KAAK,GAA2B;IACpC,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,uBAAuB,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI;IACrH,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,aAAa;CAC7E,CAAC;AAEF,MAAM,QAAQ,GAAa,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;AAE/D;;;GAGG;AACH,SAAS,eAAe,CAAC,KAAoD;IAC3E,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC;IAC3F,MAAM,KAAK,GAAG,CAAC,CAAY,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACzI,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;IAChE,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;IAChE,OAAO;QACL,MAAM;QACN,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;QAC9E,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACxC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACzC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,GAAW,EAAE,OAAO,GAAoB,EAAE;IAC1E,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC/B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IACrD,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE;QAAE,MAAM,IAAI,aAAa,CAAC,oBAAoB,GAAG,EAAE,CAAC,CAAC;IAE7E,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC3C,MAAM,SAAS,GAAG,MAAM,aAAa,CAAC,IAAI,EAAE;QAC1C,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,MAAM;QACpC,YAAY,EAAE,OAAO,CAAC,YAAY,IAAI,SAAS;KAChD,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,iBAAiB,CAAC,IAAI,EAAE,SAAS,CAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;IACvH,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IAChE,IAAI,OAAO,CAAC,SAAS,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QACzE,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAC9C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,eAAe,OAAO,CAAC,SAAS,WAAW,CAAC,CAAC;QACnE,IAAI,OAAO,CAAC,SAAS,KAAK,QAAQ,IAAI,OAAO,CAAC,SAAS,KAAK,OAAO,EAAE,CAAC;YACpE,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC;YAC5B,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBAAE,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACjF,CAAC;IACH,CAAC;IACD,MAAM,GAAG,GAAgB,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,CAAC;IAE9C,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,WAAW,GAAsC,EAAE,CAAC;IACxD,IAAI,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzC,IAAI,CAAC;YACH,WAAW,GAAG,CAAC,MAAM,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,WAAW,CAAC;QACjD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,sBAAsB;gBAAE,MAAM,IAAI,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAChF,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IACD,IAAI,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC;QAAE,WAAW,GAAG,CAAC,GAAG,WAAW,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC;IACtH,IAAI,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,WAAW,GAAG,CAAC,GAAG,WAAW,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC;IACxG,IAAI,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QAAE,WAAW,GAAG,CAAC,GAAG,WAAW,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC;IAEzJ,MAAM,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAClF,MAAM,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IACtF,MAAM,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IACxF,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,2IAA2I,CAAC,CAAC;;QAC9K,KAAK,CAAC,IAAI,CAAC,aAAa,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,iBAAiB,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC/J,IAAI,WAAW,CAAC,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,6DAA6D,CAAC,CAAC;IACrJ,IAAI,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/G,KAAK,CAAC,IAAI,CAAC,mKAAmK,CAAC,CAAC;IAClL,CAAC;IACD,IAAI,WAAW,CAAC,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,YAAY,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,wEAAwE,CAAC,CAAC;IAC/I,IAAI,WAAW,CAAC,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,MAAM,oFAAoF,CAAC,CAAC;IAC9I,IAAI,SAAS,CAAC,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,sCAAsC,SAAS,CAAC,KAAK,CAAC,MAAM,uBAAuB,CAAC,CAAC;IACzH,KAAK,CAAC,IAAI,CAAC,6HAA6H,CAAC,CAAC;IAE1I,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,WAAW,CAAC;IAC7C,MAAM,KAAK,GAAa,CAAC,GAAG,OAAO,CAAC,SAAS,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACtE,6FAA6F;IAC7F,MAAM,IAAI,GAAG,IAAI,GAAG,EAAiC,CAAC;IACtD,MAAM,OAAO,GAAG,CAAC,KAAgB,EAAyB,EAAE;QAC1D,IAAI,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,GAAU,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,OAAgB,EAAE,MAAM,EAAE,uBAAuB,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;YAC7H,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAC/B,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC,CAAC;IACF,MAAM,OAAO,GAAG,MAAM,gBAAgB,CAAC;QACrC,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,OAAO;QACrC,IAAI,EAAE,MAAM;QACZ,GAAG;QACH,cAAc,EAAE,OAAO,CAAC,cAAc,IAAI,MAAM;QAChD,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YAChB,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAkB,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC1G,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,SAAS,CAAC;YACvC,MAAM,UAAU,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACjF,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC5B,OAAO,uDAAuD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,cAAc,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;YAC1H,CAAC;YACD,OAAO;gBACL,GAAG,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;gBAC3C,GAAG,EAAE,KAAK,IAAI,EAAE;oBACd,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;oBAC7G,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;gBACzE,CAAC;aACF,CAAC;QACJ,CAAC;QACD,QAAQ,EAAE,OAAO,CAAC,QAAQ;KAC3B,CAAC,CAAC;IAEH,OAAO;QACL,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,YAAY,EAAE;QAChD,QAAQ,EAAE,QAAQ;QAClB,MAAM,EAAE,SAAS,GAAG,CAAC,IAAI,EAAE;QAC3B,OAAO,EAAE;YACP,IAAI,EAAE;gBACJ,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,aAAa,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM;gBACrC,YAAY,EAAE,SAAS,CAAC,OAAO;gBAC/B,WAAW;aACZ;SACF;QACD,KAAK;QACL,SAAS;QACT,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACpC,OAAO,EAAE,SAAS,CAAC,OAAO,CAAC;QAC3B,OAAO;KACR,CAAC;AACJ,CAAC"}
@@ -0,0 +1,83 @@
1
+ import Parser from "web-tree-sitter";
2
+ /**
3
+ * Java, C#, Ruby and Go are parsed with tree-sitter (WebAssembly grammars from tree-sitter-wasms).
4
+ * One generic layer serves all four; each language is described by a small spec: what a call
5
+ * looks like, what counts as a string, and where client-controlled data comes from.
6
+ */
7
+ export type TsNode = Parser.SyntaxNode;
8
+ export type TsLang = "java" | "csharp" | "ruby" | "go";
9
+ export interface LangSpec {
10
+ label: string;
11
+ wasm: string;
12
+ ext: RegExp;
13
+ callTypes: string[];
14
+ functionTypes: string[];
15
+ stringTypes: string[];
16
+ /** Child node types that make a string literal dynamic. */
17
+ interpolationTypes: string[];
18
+ /** Callee of string-formatting functions (their result is a built string). */
19
+ formatCall: RegExp;
20
+ assignTypes: string[];
21
+ identifierTypes: string[];
22
+ /** Client-controlled request data, matched against expression text. */
23
+ requestData: RegExp;
24
+ /** Normalised callee: "obj.method", "new Type", "Module::Class.method", "pkg.Func". */
25
+ callee(n: TsNode): string;
26
+ /** Names of parameters that carry client input (framework annotations / controller actions). */
27
+ taintedParams?(fn: TsNode): string[];
28
+ }
29
+ export declare const SPECS: Record<TsLang, LangSpec>;
30
+ export interface TsScope {
31
+ tainted: Set<string>;
32
+ dynamicStrings: Set<string>;
33
+ }
34
+ export interface TsCallSite {
35
+ module: TsModule;
36
+ node: TsNode;
37
+ callee: string;
38
+ args: TsNode[];
39
+ fn: TsNode | null;
40
+ }
41
+ export declare class TsModule {
42
+ readonly lang: TsLang;
43
+ readonly path: string;
44
+ readonly root: TsNode;
45
+ readonly source: string;
46
+ readonly lines: string[];
47
+ readonly spec: LangSpec;
48
+ private readonly scopes;
49
+ private calls?;
50
+ constructor(lang: TsLang, path: string, root: TsNode, source: string);
51
+ lineOf(node: TsNode): number;
52
+ line(n: number): string;
53
+ isStringLiteral(n: TsNode): boolean;
54
+ isLiteral(n: TsNode): boolean;
55
+ /** Text of a plain string literal without its quotes. */
56
+ stringValue(n: TsNode | undefined): string | undefined;
57
+ /** Interpolated string, "+" concatenation involving a string, or a string-format call. */
58
+ isDynamicString(n: TsNode): boolean;
59
+ identifiers(n: TsNode): string[];
60
+ enclosingFunction(n: TsNode): TsNode | null;
61
+ /** Lightweight intra-procedural taint: request data, bound parameters, and names assigned from them. */
62
+ scope(fn: TsNode | null): TsScope;
63
+ isRequestDerived(n: TsNode, scope?: TsScope): boolean;
64
+ callSites(): TsCallSite[];
65
+ }
66
+ export declare class TsIndex {
67
+ readonly modules: TsModule[];
68
+ readonly parseErrors: {
69
+ file: string;
70
+ error: string;
71
+ }[];
72
+ constructor(modules: TsModule[], parseErrors: {
73
+ file: string;
74
+ error: string;
75
+ }[]);
76
+ byLang(lang: TsLang): TsModule[];
77
+ calls(): TsCallSite[];
78
+ mentions(lang: TsLang, pattern: RegExp): boolean;
79
+ }
80
+ export declare function langOfFile(path: string): TsLang | undefined;
81
+ /** Parses one file. tree-sitter is error-tolerant, so a file with syntax errors still yields a (partial) tree. */
82
+ export declare function parseTs(lang: TsLang, path: string, source: string): Promise<TsModule>;
83
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/code/treesitter/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,243 @@
1
+ import { createRequire } from "node:module";
2
+ import Parser from "web-tree-sitter";
3
+ const squash = (s) => s.replace(/\s+/g, "");
4
+ const field = (n, name) => n.childForFieldName(name);
5
+ export const SPECS = {
6
+ java: {
7
+ label: "Java",
8
+ wasm: "java",
9
+ ext: /\.java$/,
10
+ callTypes: ["method_invocation", "object_creation_expression"],
11
+ functionTypes: ["method_declaration", "constructor_declaration", "lambda_expression"],
12
+ stringTypes: ["string_literal"],
13
+ interpolationTypes: [],
14
+ formatCall: /^(String\.format|MessageFormat\.format)$|\.formatted$/,
15
+ assignTypes: ["variable_declarator", "assignment_expression"],
16
+ identifierTypes: ["identifier"],
17
+ requestData: /\b(?:request|req|httpRequest)\.(?:getParameter|getParameterValues|getParameterMap|getHeader|getQueryString|getCookies|getInputStream|getReader|getRequestURI|getPathInfo)\b/,
18
+ callee(n) {
19
+ if (n.type === "object_creation_expression")
20
+ return `new ${squash(field(n, "type")?.text ?? "").replace(/<.*>$/, "")}`;
21
+ const obj = field(n, "object");
22
+ return squash(`${obj ? `${obj.text}.` : ""}${field(n, "name")?.text ?? ""}`);
23
+ },
24
+ taintedParams(fn) {
25
+ // Spring MVC: parameters bound from the request.
26
+ return (field(fn, "parameters")?.namedChildren ?? [])
27
+ .filter((p) => /@(RequestParam|PathVariable|RequestBody|RequestHeader|CookieValue|ModelAttribute)\b/.test(p.text))
28
+ .map((p) => field(p, "name")?.text ?? "")
29
+ .filter(Boolean);
30
+ },
31
+ },
32
+ csharp: {
33
+ label: "C#",
34
+ wasm: "c_sharp",
35
+ ext: /\.cs$/,
36
+ callTypes: ["invocation_expression", "object_creation_expression"],
37
+ functionTypes: ["method_declaration", "constructor_declaration", "lambda_expression", "local_function_statement"],
38
+ stringTypes: ["string_literal", "verbatim_string_literal", "interpolated_string_expression", "raw_string_literal"],
39
+ interpolationTypes: ["interpolation"],
40
+ formatCall: /^(string|String)\.Format$/,
41
+ assignTypes: ["variable_declarator", "assignment_expression"],
42
+ identifierTypes: ["identifier"],
43
+ requestData: /\b(?:Request|HttpContext\.Request)\.(?:Query|Form|Headers|Cookies|Body|QueryString|Params|Path|RouteValues)\b/,
44
+ callee(n) {
45
+ if (n.type === "object_creation_expression")
46
+ return `new ${squash(field(n, "type")?.text ?? "").replace(/<.*>$/, "")}`;
47
+ return squash(field(n, "function")?.text ?? "");
48
+ },
49
+ taintedParams(fn) {
50
+ // ASP.NET model binding: action parameters of controllers, or parameters marked [FromQuery] etc.
51
+ let cls = fn.parent;
52
+ while (cls && cls.type !== "class_declaration")
53
+ cls = cls.parent;
54
+ const inController = !!cls && /:\s*[\w.,\s]*Controller(Base)?\b/.test(cls.text.slice(0, 300));
55
+ return (field(fn, "parameters")?.namedChildren ?? [])
56
+ .filter((p) => inController || /\[From(Query|Body|Route|Form|Header)\b/.test(p.text))
57
+ .map((p) => field(p, "name")?.text ?? "")
58
+ .filter(Boolean);
59
+ },
60
+ },
61
+ ruby: {
62
+ label: "Ruby",
63
+ wasm: "ruby",
64
+ ext: /\.rb$/,
65
+ callTypes: ["call"],
66
+ functionTypes: ["method", "singleton_method", "block", "do_block", "lambda"],
67
+ stringTypes: ["string"],
68
+ interpolationTypes: ["interpolation"],
69
+ formatCall: /^(format|sprintf)$/,
70
+ assignTypes: ["assignment"],
71
+ identifierTypes: ["identifier", "instance_variable"],
72
+ requestData: /\bparams\b|\brequest\.(?:headers|body|query_parameters|request_parameters|raw_post|cookies|query_string)\b|\bcookies\[/,
73
+ callee(n) {
74
+ const receiver = field(n, "receiver");
75
+ return squash(`${receiver ? `${receiver.text}.` : ""}${field(n, "method")?.text ?? ""}`);
76
+ },
77
+ },
78
+ go: {
79
+ label: "Go",
80
+ wasm: "go",
81
+ ext: /\.go$/,
82
+ callTypes: ["call_expression"],
83
+ functionTypes: ["function_declaration", "method_declaration", "func_literal"],
84
+ stringTypes: ["interpreted_string_literal", "raw_string_literal"],
85
+ interpolationTypes: [],
86
+ formatCall: /^fmt\.Sprintf$/,
87
+ assignTypes: ["short_var_declaration", "assignment_statement", "var_spec"],
88
+ identifierTypes: ["identifier"],
89
+ requestData: /\b\w+\.(?:URL\.Query\(\)|URL\.Path|URL\.RawQuery|FormValue\(|PostFormValue\(|Form\b|PostForm\b|Header\.Get\(|Body\b|Cookie\()|\b\w+\.(?:Query|Param|PostForm|DefaultQuery|DefaultPostForm|GetHeader|QueryParam|FormValue|GetRawData)\(|\bmux\.Vars\(|\bchi\.URLParam\(/,
90
+ callee(n) {
91
+ return squash(field(n, "function")?.text ?? "");
92
+ },
93
+ },
94
+ };
95
+ const LITERAL_TYPES = /^(decimal_integer_literal|hex_integer_literal|integer_literal|integer|int_literal|float_literal|real_literal|decimal_floating_point_literal|float|true|false|boolean_literal|null_literal|nil|null|character_literal|simple_symbol|rune_literal)$/;
96
+ export class TsModule {
97
+ lang;
98
+ path;
99
+ root;
100
+ source;
101
+ lines;
102
+ spec;
103
+ scopes = new Map();
104
+ calls;
105
+ constructor(lang, path, root, source) {
106
+ this.lang = lang;
107
+ this.path = path;
108
+ this.root = root;
109
+ this.source = source;
110
+ this.lines = source.split(/\r?\n/);
111
+ this.spec = SPECS[lang];
112
+ }
113
+ lineOf(node) {
114
+ return node.startPosition.row + 1;
115
+ }
116
+ line(n) {
117
+ return this.lines[n - 1] ?? "";
118
+ }
119
+ isStringLiteral(n) {
120
+ return this.spec.stringTypes.includes(n.type) && (this.spec.interpolationTypes.length === 0 || n.descendantsOfType(this.spec.interpolationTypes).length === 0);
121
+ }
122
+ isLiteral(n) {
123
+ return this.isStringLiteral(n) || LITERAL_TYPES.test(n.type);
124
+ }
125
+ /** Text of a plain string literal without its quotes. */
126
+ stringValue(n) {
127
+ if (!n || !this.isStringLiteral(n))
128
+ return undefined;
129
+ return n.text.replace(/^[@$]*("""|'''|"|'|`)/, "").replace(/("""|'''|"|'|`)$/, "");
130
+ }
131
+ /** Interpolated string, "+" concatenation involving a string, or a string-format call. */
132
+ isDynamicString(n) {
133
+ const s = this.spec;
134
+ if (s.stringTypes.includes(n.type))
135
+ return !this.isStringLiteral(n);
136
+ if (n.type === "binary_expression" || n.type === "binary") {
137
+ const op = n.childForFieldName("operator")?.text ?? (n.text.includes("+") ? "+" : "");
138
+ if (op !== "+")
139
+ return false;
140
+ const parts = n.namedChildren;
141
+ const stringy = (x) => s.stringTypes.includes(x.type) || this.isDynamicString(x);
142
+ return parts.some(stringy) && !parts.every((x) => this.isStringLiteral(x));
143
+ }
144
+ if (s.callTypes.includes(n.type))
145
+ return s.formatCall.test(s.callee(n));
146
+ return false;
147
+ }
148
+ identifiers(n) {
149
+ const own = this.spec.identifierTypes.includes(n.type) ? [n.text] : [];
150
+ return [...own, ...n.descendantsOfType(this.spec.identifierTypes).map((x) => x.text)];
151
+ }
152
+ enclosingFunction(n) {
153
+ let p = n.parent;
154
+ while (p && !this.spec.functionTypes.includes(p.type))
155
+ p = p.parent;
156
+ return p;
157
+ }
158
+ /** Lightweight intra-procedural taint: request data, bound parameters, and names assigned from them. */
159
+ scope(fn) {
160
+ const root = fn ?? this.root;
161
+ let scope = this.scopes.get(root.id);
162
+ if (scope)
163
+ return scope;
164
+ scope = { tainted: new Set(fn ? (this.spec.taintedParams?.(fn) ?? []) : []), dynamicStrings: new Set() };
165
+ this.scopes.set(root.id, scope);
166
+ const assigns = root.descendantsOfType(this.spec.assignTypes);
167
+ for (let pass = 0; pass < 2; pass++) {
168
+ for (const a of assigns) {
169
+ const left = a.childForFieldName("left") ?? a.childForFieldName("name") ?? a.namedChildren[0];
170
+ const right = a.childForFieldName("right") ?? a.childForFieldName("value") ?? a.namedChildren.at(-1);
171
+ if (!left || !right || left.id === right.id)
172
+ continue;
173
+ const names = this.identifiers(left);
174
+ if (this.isRequestDerived(right, scope))
175
+ names.forEach((x) => scope.tainted.add(x));
176
+ const value = right.type === "equals_value_clause" || right.type === "expression_list" ? (right.namedChildren[0] ?? right) : right;
177
+ if (this.isDynamicString(value))
178
+ names.forEach((x) => scope.dynamicStrings.add(x));
179
+ }
180
+ }
181
+ return scope;
182
+ }
183
+ isRequestDerived(n, scope) {
184
+ if (this.spec.requestData.test(n.text))
185
+ return true;
186
+ return !!scope && this.identifiers(n).some((i) => scope.tainted.has(i));
187
+ }
188
+ callSites() {
189
+ if (this.calls)
190
+ return this.calls;
191
+ this.calls = this.root.descendantsOfType(this.spec.callTypes).map((node) => {
192
+ let args = node.childForFieldName("arguments")?.namedChildren ?? [];
193
+ // C# wraps each argument; unwrap to the expression (also skips the name in "name: value").
194
+ args = args.map((a) => (a.type === "argument" ? (a.namedChildren.at(-1) ?? a) : a));
195
+ return { module: this, node, callee: this.spec.callee(node), args, fn: this.enclosingFunction(node) };
196
+ });
197
+ return this.calls;
198
+ }
199
+ }
200
+ export class TsIndex {
201
+ modules;
202
+ parseErrors;
203
+ constructor(modules, parseErrors) {
204
+ this.modules = modules;
205
+ this.parseErrors = parseErrors;
206
+ }
207
+ byLang(lang) {
208
+ return this.modules.filter((m) => m.lang === lang);
209
+ }
210
+ calls() {
211
+ return this.modules.flatMap((m) => m.callSites());
212
+ }
213
+ mentions(lang, pattern) {
214
+ return this.byLang(lang).some((m) => pattern.test(m.source));
215
+ }
216
+ }
217
+ export function langOfFile(path) {
218
+ return Object.keys(SPECS).find((l) => SPECS[l].ext.test(path));
219
+ }
220
+ const require = createRequire(import.meta.url);
221
+ let ready;
222
+ const parsers = new Map();
223
+ function parserFor(lang) {
224
+ let pending = parsers.get(lang);
225
+ if (!pending) {
226
+ pending = (async () => {
227
+ ready ??= Parser.init();
228
+ await ready;
229
+ const language = await Parser.Language.load(require.resolve(`tree-sitter-wasms/out/tree-sitter-${SPECS[lang].wasm}.wasm`));
230
+ const parser = new Parser();
231
+ parser.setLanguage(language);
232
+ return parser;
233
+ })();
234
+ parsers.set(lang, pending);
235
+ }
236
+ return pending;
237
+ }
238
+ /** Parses one file. tree-sitter is error-tolerant, so a file with syntax errors still yields a (partial) tree. */
239
+ export async function parseTs(lang, path, source) {
240
+ const parser = await parserFor(lang);
241
+ return new TsModule(lang, path, parser.parse(source).rootNode, source);
242
+ }
243
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/code/treesitter/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ import type { CheckOutcome } from "../types.js";
2
+ import type { JsIndex } from "./javascript/index.js";
3
+ import type { PhpIndex } from "./php/index.js";
4
+ import type { PythonIndex } from "./python/index.js";
5
+ import type { TsIndex } from "./treesitter/index.js";
6
+ export type Language = "python" | "javascript" | "php" | "java" | "csharp" | "ruby" | "go";
7
+ /** Frameworks we can recognise. Only those with a rule set get code checks; others are reported as detected. */
8
+ export type FrameworkId = "django" | "flask" | "fastapi" | "express" | "koa" | "fastify" | "next" | "nestjs" | "laravel" | "spring" | "aspnet" | "rails" | "gin";
9
+ export interface SourceFile {
10
+ /** Relative to the project root, "/" separators. */
11
+ path: string;
12
+ size: number;
13
+ }
14
+ export interface ProjectInfo {
15
+ /** Primary language (most source files, weighted by detected frameworks). */
16
+ language: Language | null;
17
+ /** Every language with source files in the project. */
18
+ languages: Language[];
19
+ frameworks: FrameworkId[];
20
+ /** Why we think so, e.g. "requirements.txt lists Django". */
21
+ evidence: string[];
22
+ }
23
+ export interface CodeContext {
24
+ /** Project directory name, for messages. Never the absolute path. */
25
+ name: string;
26
+ project: ProjectInfo;
27
+ files: readonly SourceFile[];
28
+ /** Read a project file by relative path (cached). */
29
+ read(path: string): Promise<string>;
30
+ /** Parsed Python modules (cached; parsed once per scan). */
31
+ python(): Promise<PythonIndex>;
32
+ /** Parsed JavaScript / TypeScript modules (cached; parsed once per scan). */
33
+ javascript(): Promise<JsIndex>;
34
+ /** Parsed PHP files (cached; parsed once per scan). */
35
+ php(): Promise<PhpIndex>;
36
+ /** Parsed Java, C#, Ruby and Go files (tree-sitter; cached, parsed once per scan). */
37
+ treeSitter(): Promise<TsIndex>;
38
+ }
39
+ /** A static-analysis check (Tier 2). */
40
+ export interface CodeCheck {
41
+ kind: "code";
42
+ /** Stable identifier, referenced from AnnexItem.checks.code. */
43
+ key: string;
44
+ /** The check runs only when the project's language or one of its frameworks is listed. */
45
+ appliesTo: readonly (Language | FrameworkId)[];
46
+ run(ctx: CodeContext): Promise<CheckOutcome>;
47
+ }
48
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/code/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAErD,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,YAAY,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,GAAG,IAAI,CAAC;AAE3F,gHAAgH;AAChH,MAAM,MAAM,WAAW,GACnB,QAAQ,GAAG,OAAO,GAAG,SAAS,GAC9B,SAAS,GAAG,KAAK,GAAG,SAAS,GAAG,MAAM,GAAG,QAAQ,GACjD,SAAS,GACT,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,KAAK,CAAC;AAE1C,MAAM,WAAW,UAAU;IACzB,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,6EAA6E;IAC7E,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC1B,uDAAuD;IACvD,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,UAAU,EAAE,WAAW,EAAE,CAAC;IAC1B,6DAA6D;IAC7D,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,qEAAqE;IACrE,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,WAAW,CAAC;IACrB,KAAK,EAAE,SAAS,UAAU,EAAE,CAAC;IAC7B,qDAAqD;IACrD,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACpC,4DAA4D;IAC5D,MAAM,IAAI,OAAO,CAAC,WAAW,CAAC,CAAC;IAC/B,6EAA6E;IAC7E,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/B,uDAAuD;IACvD,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC;IACzB,sFAAsF;IACtF,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CAChC;AAED,wCAAwC;AACxC,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,GAAG,EAAE,MAAM,CAAC;IACZ,0FAA0F;IAC1F,SAAS,EAAE,SAAS,CAAC,QAAQ,GAAG,WAAW,CAAC,EAAE,CAAC;IAC/C,GAAG,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CAC9C"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/code/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ import type { GuidanceCatalog } from "./types.js";
2
+ export declare const EN: GuidanceCatalog;
3
+ //# sourceMappingURL=en.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"en.d.ts","sourceRoot":"","sources":["../../src/content/en.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAelD,eAAO,MAAM,EAAE,EAAE,eA2sBhB,CAAC"}