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.
- package/LICENSE +24 -0
- package/dist/annex-b.d.ts +6 -0
- package/dist/annex-b.d.ts.map +1 -0
- package/dist/annex-b.js +152 -0
- package/dist/annex-b.js.map +1 -0
- package/dist/checks/content/page.d.ts +7 -0
- package/dist/checks/content/page.d.ts.map +1 -0
- package/dist/checks/content/page.js +133 -0
- package/dist/checks/content/page.js.map +1 -0
- package/dist/checks/cookies/cookie-flags.d.ts +3 -0
- package/dist/checks/cookies/cookie-flags.d.ts.map +1 -0
- package/dist/checks/cookies/cookie-flags.js +41 -0
- package/dist/checks/cookies/cookie-flags.js.map +1 -0
- package/dist/checks/cookies/cookie-scope.d.ts +6 -0
- package/dist/checks/cookies/cookie-scope.d.ts.map +1 -0
- package/dist/checks/cookies/cookie-scope.js +60 -0
- package/dist/checks/cookies/cookie-scope.js.map +1 -0
- package/dist/checks/deployment/server-banner.d.ts +4 -0
- package/dist/checks/deployment/server-banner.d.ts.map +1 -0
- package/dist/checks/deployment/server-banner.js +60 -0
- package/dist/checks/deployment/server-banner.js.map +1 -0
- package/dist/checks/deployment/trace.d.ts +3 -0
- package/dist/checks/deployment/trace.d.ts.map +1 -0
- package/dist/checks/deployment/trace.js +30 -0
- package/dist/checks/deployment/trace.js.map +1 -0
- package/dist/checks/headers/clickjacking.d.ts +5 -0
- package/dist/checks/headers/clickjacking.d.ts.map +1 -0
- package/dist/checks/headers/clickjacking.js +57 -0
- package/dist/checks/headers/clickjacking.js.map +1 -0
- package/dist/checks/headers/content-type-options.d.ts +3 -0
- package/dist/checks/headers/content-type-options.d.ts.map +1 -0
- package/dist/checks/headers/content-type-options.js +17 -0
- package/dist/checks/headers/content-type-options.js.map +1 -0
- package/dist/checks/headers/cors.d.ts +4 -0
- package/dist/checks/headers/cors.d.ts.map +1 -0
- package/dist/checks/headers/cors.js +38 -0
- package/dist/checks/headers/cors.js.map +1 -0
- package/dist/checks/html.d.ts +11 -0
- package/dist/checks/html.d.ts.map +1 -0
- package/dist/checks/html.js +30 -0
- package/dist/checks/html.js.map +1 -0
- package/dist/checks/index.d.ts +7 -0
- package/dist/checks/index.d.ts.map +1 -0
- package/dist/checks/index.js +48 -0
- package/dist/checks/index.js.map +1 -0
- package/dist/checks/info-disclosure/directory-listing.d.ts +6 -0
- package/dist/checks/info-disclosure/directory-listing.d.ts.map +1 -0
- package/dist/checks/info-disclosure/directory-listing.js +60 -0
- package/dist/checks/info-disclosure/directory-listing.js.map +1 -0
- package/dist/checks/info-disclosure/exposed-files.d.ts +4 -0
- package/dist/checks/info-disclosure/exposed-files.d.ts.map +1 -0
- package/dist/checks/info-disclosure/exposed-files.js +56 -0
- package/dist/checks/info-disclosure/exposed-files.js.map +1 -0
- package/dist/checks/info-disclosure/more.d.ts +8 -0
- package/dist/checks/info-disclosure/more.d.ts.map +1 -0
- package/dist/checks/info-disclosure/more.js +186 -0
- package/dist/checks/info-disclosure/more.js.map +1 -0
- package/dist/checks/tls/certificate.d.ts +3 -0
- package/dist/checks/tls/certificate.d.ts.map +1 -0
- package/dist/checks/tls/certificate.js +49 -0
- package/dist/checks/tls/certificate.js.map +1 -0
- package/dist/checks/tls/hsts.d.ts +5 -0
- package/dist/checks/tls/hsts.d.ts.map +1 -0
- package/dist/checks/tls/hsts.js +35 -0
- package/dist/checks/tls/hsts.js.map +1 -0
- package/dist/checks/tls/https-redirect.d.ts +3 -0
- package/dist/checks/tls/https-redirect.d.ts.map +1 -0
- package/dist/checks/tls/https-redirect.js +46 -0
- package/dist/checks/tls/https-redirect.js.map +1 -0
- package/dist/checks/tls/legacy-protocols.d.ts +3 -0
- package/dist/checks/tls/legacy-protocols.d.ts.map +1 -0
- package/dist/checks/tls/legacy-protocols.js +27 -0
- package/dist/checks/tls/legacy-protocols.js.map +1 -0
- package/dist/checks/util.d.ts +22 -0
- package/dist/checks/util.d.ts.map +1 -0
- package/dist/checks/util.js +63 -0
- package/dist/checks/util.js.map +1 -0
- package/dist/code/checks/crypto.d.ts +5 -0
- package/dist/code/checks/crypto.d.ts.map +1 -0
- package/dist/code/checks/crypto.js +100 -0
- package/dist/code/checks/crypto.js.map +1 -0
- package/dist/code/checks/django.d.ts +14 -0
- package/dist/code/checks/django.d.ts.map +1 -0
- package/dist/code/checks/django.js +313 -0
- package/dist/code/checks/django.js.map +1 -0
- package/dist/code/checks/flask.d.ts +6 -0
- package/dist/code/checks/flask.d.ts.map +1 -0
- package/dist/code/checks/flask.js +100 -0
- package/dist/code/checks/flask.js.map +1 -0
- package/dist/code/checks/index.d.ts +9 -0
- package/dist/code/checks/index.d.ts.map +1 -0
- package/dist/code/checks/index.js +126 -0
- package/dist/code/checks/index.js.map +1 -0
- package/dist/code/checks/injection.d.ts +27 -0
- package/dist/code/checks/injection.d.ts.map +1 -0
- package/dist/code/checks/injection.js +189 -0
- package/dist/code/checks/injection.js.map +1 -0
- package/dist/code/checks/javascript-config.d.ts +14 -0
- package/dist/code/checks/javascript-config.d.ts.map +1 -0
- package/dist/code/checks/javascript-config.js +251 -0
- package/dist/code/checks/javascript-config.js.map +1 -0
- package/dist/code/checks/javascript.d.ts +34 -0
- package/dist/code/checks/javascript.d.ts.map +1 -0
- package/dist/code/checks/javascript.js +333 -0
- package/dist/code/checks/javascript.js.map +1 -0
- package/dist/code/checks/php.d.ts +27 -0
- package/dist/code/checks/php.d.ts.map +1 -0
- package/dist/code/checks/php.js +433 -0
- package/dist/code/checks/php.js.map +1 -0
- package/dist/code/checks/secrets.d.ts +10 -0
- package/dist/code/checks/secrets.d.ts.map +1 -0
- package/dist/code/checks/secrets.js +140 -0
- package/dist/code/checks/secrets.js.map +1 -0
- package/dist/code/checks/shared.d.ts +25 -0
- package/dist/code/checks/shared.d.ts.map +1 -0
- package/dist/code/checks/shared.js +57 -0
- package/dist/code/checks/shared.js.map +1 -0
- package/dist/code/checks/treesitter.d.ts +15 -0
- package/dist/code/checks/treesitter.d.ts.map +1 -0
- package/dist/code/checks/treesitter.js +322 -0
- package/dist/code/checks/treesitter.js.map +1 -0
- package/dist/code/checks/xml.d.ts +9 -0
- package/dist/code/checks/xml.d.ts.map +1 -0
- package/dist/code/checks/xml.js +78 -0
- package/dist/code/checks/xml.js.map +1 -0
- package/dist/code/context.d.ts +6 -0
- package/dist/code/context.d.ts.map +1 -0
- package/dist/code/context.js +92 -0
- package/dist/code/context.js.map +1 -0
- package/dist/code/detect.d.ts +3 -0
- package/dist/code/detect.d.ts.map +1 -0
- package/dist/code/detect.js +118 -0
- package/dist/code/detect.js.map +1 -0
- package/dist/code/django/settings.d.ts +46 -0
- package/dist/code/django/settings.d.ts.map +1 -0
- package/dist/code/django/settings.js +154 -0
- package/dist/code/django/settings.js.map +1 -0
- package/dist/code/findings.d.ts +18 -0
- package/dist/code/findings.d.ts.map +1 -0
- package/dist/code/findings.js +63 -0
- package/dist/code/findings.js.map +1 -0
- package/dist/code/javascript/ast.d.ts +46 -0
- package/dist/code/javascript/ast.d.ts.map +1 -0
- package/dist/code/javascript/ast.js +166 -0
- package/dist/code/javascript/ast.js.map +1 -0
- package/dist/code/javascript/index.d.ts +3 -0
- package/dist/code/javascript/index.d.ts.map +1 -0
- package/dist/code/javascript/index.js +3 -0
- package/dist/code/javascript/index.js.map +1 -0
- package/dist/code/javascript/module.d.ts +59 -0
- package/dist/code/javascript/module.d.ts.map +1 -0
- package/dist/code/javascript/module.js +250 -0
- package/dist/code/javascript/module.js.map +1 -0
- package/dist/code/php/index.d.ts +92 -0
- package/dist/code/php/index.d.ts.map +1 -0
- package/dist/code/php/index.js +316 -0
- package/dist/code/php/index.js.map +1 -0
- package/dist/code/project.d.ts +13 -0
- package/dist/code/project.d.ts.map +1 -0
- package/dist/code/project.js +69 -0
- package/dist/code/project.js.map +1 -0
- package/dist/code/python/ast.d.ts +47 -0
- package/dist/code/python/ast.d.ts.map +1 -0
- package/dist/code/python/ast.js +193 -0
- package/dist/code/python/ast.js.map +1 -0
- package/dist/code/python/index.d.ts +3 -0
- package/dist/code/python/index.d.ts.map +1 -0
- package/dist/code/python/index.js +3 -0
- package/dist/code/python/index.js.map +1 -0
- package/dist/code/python/module.d.ts +55 -0
- package/dist/code/python/module.d.ts.map +1 -0
- package/dist/code/python/module.js +215 -0
- package/dist/code/python/module.js.map +1 -0
- package/dist/code/scan.d.ts +24 -0
- package/dist/code/scan.d.ts.map +1 -0
- package/dist/code/scan.js +159 -0
- package/dist/code/scan.js.map +1 -0
- package/dist/code/treesitter/index.d.ts +83 -0
- package/dist/code/treesitter/index.d.ts.map +1 -0
- package/dist/code/treesitter/index.js +243 -0
- package/dist/code/treesitter/index.js.map +1 -0
- package/dist/code/types.d.ts +48 -0
- package/dist/code/types.d.ts.map +1 -0
- package/dist/code/types.js +2 -0
- package/dist/code/types.js.map +1 -0
- package/dist/content/en.d.ts +3 -0
- package/dist/content/en.d.ts.map +1 -0
- package/dist/content/en.js +722 -0
- package/dist/content/en.js.map +1 -0
- package/dist/content/index.d.ts +15 -0
- package/dist/content/index.d.ts.map +1 -0
- package/dist/content/index.js +21 -0
- package/dist/content/index.js.map +1 -0
- package/dist/content/types.d.ts +87 -0
- package/dist/content/types.d.ts.map +1 -0
- package/dist/content/types.js +2 -0
- package/dist/content/types.js.map +1 -0
- package/dist/engine.d.ts +52 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +120 -0
- package/dist/engine.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/meta.d.ts +4 -0
- package/dist/meta.d.ts.map +1 -0
- package/dist/meta.js +4 -0
- package/dist/meta.js.map +1 -0
- package/dist/net/context.d.ts +9 -0
- package/dist/net/context.d.ts.map +1 -0
- package/dist/net/context.js +62 -0
- package/dist/net/context.js.map +1 -0
- package/dist/net/guard.d.ts +16 -0
- package/dist/net/guard.d.ts.map +1 -0
- package/dist/net/guard.js +70 -0
- package/dist/net/guard.js.map +1 -0
- package/dist/net/http.d.ts +22 -0
- package/dist/net/http.d.ts.map +1 -0
- package/dist/net/http.js +114 -0
- package/dist/net/http.js.map +1 -0
- package/dist/net/tls.d.ts +15 -0
- package/dist/net/tls.d.ts.map +1 -0
- package/dist/net/tls.js +103 -0
- package/dist/net/tls.js.map +1 -0
- package/dist/report/html.d.ts +14 -0
- package/dist/report/html.d.ts.map +1 -0
- package/dist/report/html.js +210 -0
- package/dist/report/html.js.map +1 -0
- package/dist/report/index.d.ts +10 -0
- package/dist/report/index.d.ts.map +1 -0
- package/dist/report/index.js +10 -0
- package/dist/report/index.js.map +1 -0
- package/dist/report/manual.d.ts +62 -0
- package/dist/report/manual.d.ts.map +1 -0
- package/dist/report/manual.js +190 -0
- package/dist/report/manual.js.map +1 -0
- package/dist/report/merge.d.ts +8 -0
- package/dist/report/merge.d.ts.map +1 -0
- package/dist/report/merge.js +135 -0
- package/dist/report/merge.js.map +1 -0
- package/dist/report/summary.d.ts +10 -0
- package/dist/report/summary.d.ts.map +1 -0
- package/dist/report/summary.js +27 -0
- package/dist/report/summary.js.map +1 -0
- package/dist/report/validate.d.ts +3 -0
- package/dist/report/validate.d.ts.map +1 -0
- package/dist/report/validate.js +78 -0
- package/dist/report/validate.js.map +1 -0
- package/dist/types.d.ts +244 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/validate.d.ts +4 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +24 -0
- package/dist/validate.js.map +1 -0
- 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":"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"}
|
|
@@ -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 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/code/types.ts"],"names":[],"mappings":""}
|
|
@@ -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"}
|