blitzstrike 1.0.33 → 1.0.35
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/CHANGELOG.md +27 -0
- package/dist/index.js +759 -30
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,33 @@ All notable changes to Blitz Strike are documented here.
|
|
|
5
5
|
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
7
7
|
|
|
8
|
+
## [1.0.35] — 2026-09-13
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **Phase 2 — EAGLE-EYE 2.0** (`src/callgraph.ts` + `src/eagle2.ts`):
|
|
13
|
+
- **Call graph** — sound (over-approximate) function/method resolution on a
|
|
14
|
+
PHP AST: name calls, `$this->m()`, static calls, and Class Hierarchy
|
|
15
|
+
Analysis (CHA) for `$obj->m()`.
|
|
16
|
+
- **Whole-program interprocedural taint** — call-graph worklist propagates
|
|
17
|
+
taint transitively across function boundaries (`outer -> inner -> sink`).
|
|
18
|
+
- **Return propagation** — `$x = helper($tainted)` taints `$x` iff the helper
|
|
19
|
+
returns a value derived from its parameter.
|
|
20
|
+
- **By-reference alias tracking** — `&$out` output params that write a source
|
|
21
|
+
taint the caller's variable.
|
|
22
|
+
- **Conditional flow** — ternary (`retif`) + if/else branches are merged
|
|
23
|
+
(sources unioned, sanitizers intersected — sound).
|
|
24
|
+
- **Authorization flow** — sinks guarded by a capability/nonce check are
|
|
25
|
+
flagged `auth_gated` with the *specific* gate name.
|
|
26
|
+
- New MCP tool `eagle_eye2` — prefer over `taint_scan` for accurate
|
|
27
|
+
cross-function reachability.
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
|
|
31
|
+
- Sink classification false positives: bare function-name sinks (`system(`, `exec(`, …)
|
|
32
|
+
now use `\b` word boundaries, so `outer_exec(...)` is no longer misclassified
|
|
33
|
+
as command execution.
|
|
34
|
+
|
|
8
35
|
## [1.0.33] — 2026-09-13
|
|
9
36
|
|
|
10
37
|
### Added
|
package/dist/index.js
CHANGED
|
@@ -14820,7 +14820,7 @@ var require_src = __commonJS(function(exports, module) {
|
|
|
14820
14820
|
});
|
|
14821
14821
|
|
|
14822
14822
|
// src/sync.ts
|
|
14823
|
-
import { mkdirSync as mkdirSync3, writeFileSync as writeFileSync3, readFileSync as
|
|
14823
|
+
import { mkdirSync as mkdirSync3, writeFileSync as writeFileSync3, readFileSync as readFileSync14, readdirSync as readdirSync5, statSync as statSync3, rmSync as rmSync2 } from "node:fs";
|
|
14824
14824
|
import { join as join10 } from "node:path";
|
|
14825
14825
|
import { homedir as homedir4 } from "node:os";
|
|
14826
14826
|
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
@@ -14916,7 +14916,7 @@ function manualCopy(src, dst) {
|
|
|
14916
14916
|
if (e.isDirectory())
|
|
14917
14917
|
manualCopy(s, d);
|
|
14918
14918
|
else
|
|
14919
|
-
writeFileSync3(d,
|
|
14919
|
+
writeFileSync3(d, readFileSync14(s));
|
|
14920
14920
|
}
|
|
14921
14921
|
}
|
|
14922
14922
|
var ROOT5, DATA_ROOT2, GITHUB_REPO = "https://github.com/shinthink/blitzstrike.git";
|
|
@@ -29985,11 +29985,7 @@ function redactSecrets(text) {
|
|
|
29985
29985
|
return out;
|
|
29986
29986
|
}
|
|
29987
29987
|
function hasSecrets(text) {
|
|
29988
|
-
|
|
29989
|
-
if (re.test(text))
|
|
29990
|
-
return true;
|
|
29991
|
-
}
|
|
29992
|
-
return false;
|
|
29988
|
+
return redactSecrets(text) !== text;
|
|
29993
29989
|
}
|
|
29994
29990
|
function redactObject(value) {
|
|
29995
29991
|
if (typeof value === "string")
|
|
@@ -30181,6 +30177,7 @@ function transition(finding, to) {
|
|
|
30181
30177
|
if (!canTransition(finding.status, to)) {
|
|
30182
30178
|
throw new Error(`illegal transition ${finding.status} -> ${to}`);
|
|
30183
30179
|
}
|
|
30180
|
+
recordAudit("finding_updated", { tool: "blitzstrike", target: finding.target.host ?? finding.target.endpoint, result: `${finding.status} -> ${to}`, correlationId: finding.id });
|
|
30184
30181
|
const updated = { ...finding, status: to, timestamps: { ...finding.timestamps, updated: new Date().toISOString() } };
|
|
30185
30182
|
return updated;
|
|
30186
30183
|
}
|
|
@@ -31070,16 +31067,16 @@ function classifySource(line) {
|
|
|
31070
31067
|
}
|
|
31071
31068
|
var SINK_CLASS_MAP = [
|
|
31072
31069
|
[/->query\(|\$wpdb->query|\$wpdb->get_var|\$wpdb->get_results|->whereRaw|->selectRaw/, { id: "sql_execution", category: "SQL execution", cwe: "CWE-89" }],
|
|
31073
|
-
[
|
|
31074
|
-
[
|
|
31075
|
-
[
|
|
31076
|
-
[
|
|
31077
|
-
[
|
|
31078
|
-
[
|
|
31079
|
-
[
|
|
31080
|
-
[/echo\s|print\s
|
|
31081
|
-
[
|
|
31082
|
-
[
|
|
31070
|
+
[/\beval\(|\bassert\(|\bcreate_function\(|\bcall_user_func\(|\bpreg_replace\(/, { id: "code_execution", category: "Dynamic evaluation / code execution", cwe: "CWE-94" }],
|
|
31071
|
+
[/\bsystem\(|\bexec\(|\bshell_exec\(|\bpassthru\(|\bproc_open\(|\bpopen\(/, { id: "command_execution", category: "Command execution", cwe: "CWE-78" }],
|
|
31072
|
+
[/\bmove_uploaded_file\(|\bfile_put_contents\(|\bfwrite\(|\bfopen\(|\bunlink\(/, { id: "file_operations", category: "File operations", cwe: "CWE-434" }],
|
|
31073
|
+
[/\binclude\(|\brequire\(|\binclude_once\(|\brequire_once\(/, { id: "file_inclusion", category: "File inclusion", cwe: "CWE-98" }],
|
|
31074
|
+
[/\bunserialize\(|\bmaybe_unserialize\(/, { id: "deserialization", category: "Deserialization", cwe: "CWE-502" }],
|
|
31075
|
+
[/\bwp_remote_get\(|\bwp_remote_post\(|\bfile_get_contents\(|\bcurl_exec\(/, { id: "http_request", category: "HTTP request (SSRF)", cwe: "CWE-918" }],
|
|
31076
|
+
[/\bheader\(|\bwp_redirect\(|\bwp_safe_redirect\(/, { id: "redirect", category: "Redirect handling", cwe: "CWE-601" }],
|
|
31077
|
+
[/echo\s|print\s|\bprintf\(/, { id: "html_render", category: "HTML rendering (XSS)", cwe: "CWE-79" }],
|
|
31078
|
+
[/\bsimplexml_load_string\(|new SimpleXMLElement|DOMDocument/, { id: "xml_processing", category: "XML processing (XXE)", cwe: "CWE-611" }],
|
|
31079
|
+
[/\bZipArchive|\bPharData|->extractTo\(/, { id: "archive_extraction", category: "Archive extraction (zip slip)", cwe: "CWE-22" }]
|
|
31083
31080
|
];
|
|
31084
31081
|
function classifySink2(sink) {
|
|
31085
31082
|
for (const [re, cls] of SINK_CLASS_MAP) {
|
|
@@ -31596,6 +31593,706 @@ function taintTree(root, maxFiles = 2000) {
|
|
|
31596
31593
|
return files.map((f) => analyzeTaint(f));
|
|
31597
31594
|
}
|
|
31598
31595
|
|
|
31596
|
+
// src/eagle2.ts
|
|
31597
|
+
var import_php_parser3 = __toESM(require_src(), 1);
|
|
31598
|
+
import { readFileSync as readFileSync12 } from "node:fs";
|
|
31599
|
+
init_scanner();
|
|
31600
|
+
|
|
31601
|
+
// src/callgraph.ts
|
|
31602
|
+
var import_php_parser2 = __toESM(require_src(), 1);
|
|
31603
|
+
import { readFileSync as readFileSync11 } from "node:fs";
|
|
31604
|
+
var parser2 = new import_php_parser2.Engine({
|
|
31605
|
+
parser: { extractDoc: false, php7: true },
|
|
31606
|
+
ast: { withPositions: true, withSource: false }
|
|
31607
|
+
});
|
|
31608
|
+
function isNode2(v) {
|
|
31609
|
+
return !!v && typeof v === "object" && typeof v.kind === "string";
|
|
31610
|
+
}
|
|
31611
|
+
function children2(node) {
|
|
31612
|
+
const out = [];
|
|
31613
|
+
for (const k of Object.keys(node)) {
|
|
31614
|
+
if (k === "loc")
|
|
31615
|
+
continue;
|
|
31616
|
+
const v = node[k];
|
|
31617
|
+
if (Array.isArray(v)) {
|
|
31618
|
+
for (const c of v)
|
|
31619
|
+
if (isNode2(c))
|
|
31620
|
+
out.push(c);
|
|
31621
|
+
} else if (isNode2(v)) {
|
|
31622
|
+
out.push(v);
|
|
31623
|
+
}
|
|
31624
|
+
}
|
|
31625
|
+
return out;
|
|
31626
|
+
}
|
|
31627
|
+
function nameOf(node) {
|
|
31628
|
+
if (!isNode2(node))
|
|
31629
|
+
return null;
|
|
31630
|
+
if (typeof node.name === "string")
|
|
31631
|
+
return node.name;
|
|
31632
|
+
if (isNode2(node.name))
|
|
31633
|
+
return nameOf(node.name);
|
|
31634
|
+
return null;
|
|
31635
|
+
}
|
|
31636
|
+
function nodeId(kind, name, cls) {
|
|
31637
|
+
if (kind === "function")
|
|
31638
|
+
return `func:${name}`;
|
|
31639
|
+
if (kind === "method")
|
|
31640
|
+
return `method:${cls ?? "?"}::${name}`;
|
|
31641
|
+
return "main";
|
|
31642
|
+
}
|
|
31643
|
+
function ensureNode(g, id, name, kind, file, line, cls) {
|
|
31644
|
+
let n = g.nodes.get(id);
|
|
31645
|
+
if (!n) {
|
|
31646
|
+
n = { id, name, kind, class: cls, file, line, callees: new Set, callers: new Set };
|
|
31647
|
+
g.nodes.set(id, n);
|
|
31648
|
+
}
|
|
31649
|
+
return n;
|
|
31650
|
+
}
|
|
31651
|
+
function addEdge(g, caller, callee, name, line, file) {
|
|
31652
|
+
g.edges.push({ caller, callee, name, line, file });
|
|
31653
|
+
const c = g.nodes.get(caller);
|
|
31654
|
+
const t = g.nodes.get(callee);
|
|
31655
|
+
if (c)
|
|
31656
|
+
c.callees.add(callee);
|
|
31657
|
+
if (t)
|
|
31658
|
+
t.callers.add(caller);
|
|
31659
|
+
}
|
|
31660
|
+
function buildCallGraph(path) {
|
|
31661
|
+
const g = { nodes: new Map, edges: [] };
|
|
31662
|
+
let code;
|
|
31663
|
+
try {
|
|
31664
|
+
code = readFileSync11(path, "utf8");
|
|
31665
|
+
} catch {
|
|
31666
|
+
return g;
|
|
31667
|
+
}
|
|
31668
|
+
let ast;
|
|
31669
|
+
try {
|
|
31670
|
+
ast = parser2.parseCode(code, path);
|
|
31671
|
+
} catch {
|
|
31672
|
+
return g;
|
|
31673
|
+
}
|
|
31674
|
+
const mainId = nodeId("main", "main");
|
|
31675
|
+
ensureNode(g, mainId, "<main>", "main", path, 0);
|
|
31676
|
+
const funcs = [];
|
|
31677
|
+
const methods = [];
|
|
31678
|
+
walk(ast, path, (n, ctx) => {
|
|
31679
|
+
if (n.kind === "function") {
|
|
31680
|
+
const name = nameOf(n.name);
|
|
31681
|
+
if (name)
|
|
31682
|
+
funcs.push({ name, node: n });
|
|
31683
|
+
} else if (n.kind === "method" && ctx.className) {
|
|
31684
|
+
const mname = nameOf(n.name);
|
|
31685
|
+
if (mname)
|
|
31686
|
+
methods.push({ cls: ctx.className, name: mname, node: n });
|
|
31687
|
+
}
|
|
31688
|
+
});
|
|
31689
|
+
for (const f of funcs) {
|
|
31690
|
+
const id = nodeId("function", f.name);
|
|
31691
|
+
ensureNode(g, id, f.name, "function", path, f.node.loc?.start?.line ?? 0);
|
|
31692
|
+
}
|
|
31693
|
+
for (const m of methods) {
|
|
31694
|
+
const id = nodeId("method", m.name, m.cls);
|
|
31695
|
+
ensureNode(g, id, m.name, "method", path, m.node.loc?.start?.line ?? 0, m.cls);
|
|
31696
|
+
}
|
|
31697
|
+
walk(ast, path, (n, ctx) => {
|
|
31698
|
+
if (n.kind !== "call")
|
|
31699
|
+
return;
|
|
31700
|
+
const line = n.loc?.start?.line ?? 0;
|
|
31701
|
+
const callerId = ctx.enclosing ?? mainId;
|
|
31702
|
+
resolveCall(g, n, callerId, ctx, path, line);
|
|
31703
|
+
});
|
|
31704
|
+
return g;
|
|
31705
|
+
}
|
|
31706
|
+
function walk(node, file, visit, ctx = {}) {
|
|
31707
|
+
if (!isNode2(node))
|
|
31708
|
+
return;
|
|
31709
|
+
let childCtx = ctx;
|
|
31710
|
+
if (node.kind === "class") {
|
|
31711
|
+
childCtx = { ...ctx, className: nameOf(node.name) ?? undefined };
|
|
31712
|
+
} else if (node.kind === "function") {
|
|
31713
|
+
const name = nameOf(node.name);
|
|
31714
|
+
childCtx = { ...ctx, enclosing: name ? nodeId("function", name) : ctx.enclosing };
|
|
31715
|
+
} else if (node.kind === "method") {
|
|
31716
|
+
const name = nameOf(node.name);
|
|
31717
|
+
childCtx = { ...ctx, enclosing: name ? nodeId("method", name, ctx.className) : ctx.enclosing };
|
|
31718
|
+
}
|
|
31719
|
+
visit(node, ctx);
|
|
31720
|
+
for (const c of children2(node))
|
|
31721
|
+
walk(c, file, visit, childCtx);
|
|
31722
|
+
}
|
|
31723
|
+
function resolveCall(g, call, callerId, ctx, file, line) {
|
|
31724
|
+
const what = call.what;
|
|
31725
|
+
if (!isNode2(what))
|
|
31726
|
+
return;
|
|
31727
|
+
if (what.kind === "name") {
|
|
31728
|
+
const fn = nameOf(what);
|
|
31729
|
+
if (!fn)
|
|
31730
|
+
return;
|
|
31731
|
+
const id = nodeId("function", fn);
|
|
31732
|
+
if (g.nodes.has(id)) {
|
|
31733
|
+
addEdge(g, callerId, id, fn, line, file);
|
|
31734
|
+
} else {
|
|
31735
|
+
addEdge(g, callerId, `unknown:${fn}`, fn, line, file);
|
|
31736
|
+
}
|
|
31737
|
+
return;
|
|
31738
|
+
}
|
|
31739
|
+
if (what.kind === "staticlookup") {
|
|
31740
|
+
const base = what.what;
|
|
31741
|
+
const baseName = nameOf(base) ?? (isNode2(base) && base.kind === "variable" ? base.name : null);
|
|
31742
|
+
const method = nameOf(what.offset);
|
|
31743
|
+
if (!method)
|
|
31744
|
+
return;
|
|
31745
|
+
let cls = baseName;
|
|
31746
|
+
if (cls === "self" || cls === "static")
|
|
31747
|
+
cls = ctx.className ?? "?";
|
|
31748
|
+
if (cls && cls !== "?") {
|
|
31749
|
+
const id = nodeId("method", method, cls);
|
|
31750
|
+
if (g.nodes.has(id))
|
|
31751
|
+
addEdge(g, callerId, id, method, line, file);
|
|
31752
|
+
}
|
|
31753
|
+
return;
|
|
31754
|
+
}
|
|
31755
|
+
if (what.kind === "propertylookup") {
|
|
31756
|
+
const base = what.what;
|
|
31757
|
+
const method = nameOf(what.offset);
|
|
31758
|
+
if (!method)
|
|
31759
|
+
return;
|
|
31760
|
+
if (isNode2(base) && base.kind === "variable" && base.name === "this") {
|
|
31761
|
+
if (ctx.className) {
|
|
31762
|
+
const id = nodeId("method", method, ctx.className);
|
|
31763
|
+
if (g.nodes.has(id))
|
|
31764
|
+
addEdge(g, callerId, id, method, line, file);
|
|
31765
|
+
}
|
|
31766
|
+
return;
|
|
31767
|
+
}
|
|
31768
|
+
let matched = false;
|
|
31769
|
+
for (const [id, n] of g.nodes) {
|
|
31770
|
+
if (n.kind === "method" && n.name === method) {
|
|
31771
|
+
addEdge(g, callerId, id, method, line, file);
|
|
31772
|
+
matched = true;
|
|
31773
|
+
}
|
|
31774
|
+
}
|
|
31775
|
+
if (!matched)
|
|
31776
|
+
addEdge(g, callerId, `unknown:${method}`, method, line, file);
|
|
31777
|
+
return;
|
|
31778
|
+
}
|
|
31779
|
+
}
|
|
31780
|
+
|
|
31781
|
+
// src/eagle2.ts
|
|
31782
|
+
var parser3 = new import_php_parser3.Engine({
|
|
31783
|
+
parser: { extractDoc: false, php7: true },
|
|
31784
|
+
ast: { withPositions: true, withSource: false }
|
|
31785
|
+
});
|
|
31786
|
+
function isNode3(v) {
|
|
31787
|
+
return !!v && typeof v === "object" && typeof v.kind === "string";
|
|
31788
|
+
}
|
|
31789
|
+
function children3(node) {
|
|
31790
|
+
const out = [];
|
|
31791
|
+
for (const k of Object.keys(node)) {
|
|
31792
|
+
if (k === "loc")
|
|
31793
|
+
continue;
|
|
31794
|
+
const v = node[k];
|
|
31795
|
+
if (Array.isArray(v)) {
|
|
31796
|
+
for (const c of v)
|
|
31797
|
+
if (isNode3(c))
|
|
31798
|
+
out.push(c);
|
|
31799
|
+
} else if (isNode3(v)) {
|
|
31800
|
+
out.push(v);
|
|
31801
|
+
}
|
|
31802
|
+
}
|
|
31803
|
+
return out;
|
|
31804
|
+
}
|
|
31805
|
+
function findKind2(node, kind, out = []) {
|
|
31806
|
+
if (!isNode3(node))
|
|
31807
|
+
return out;
|
|
31808
|
+
if (node.kind === kind)
|
|
31809
|
+
out.push(node);
|
|
31810
|
+
for (const c of children3(node))
|
|
31811
|
+
findKind2(c, kind, out);
|
|
31812
|
+
return out;
|
|
31813
|
+
}
|
|
31814
|
+
function nameOf2(node) {
|
|
31815
|
+
if (!isNode3(node))
|
|
31816
|
+
return null;
|
|
31817
|
+
if (typeof node.name === "string")
|
|
31818
|
+
return node.name;
|
|
31819
|
+
if (isNode3(node.name))
|
|
31820
|
+
return nameOf2(node.name);
|
|
31821
|
+
return null;
|
|
31822
|
+
}
|
|
31823
|
+
function rootVarName2(node) {
|
|
31824
|
+
if (!isNode3(node))
|
|
31825
|
+
return null;
|
|
31826
|
+
if (node.kind === "variable")
|
|
31827
|
+
return node.name ?? null;
|
|
31828
|
+
if (node.kind === "name")
|
|
31829
|
+
return typeof node.name === "string" ? node.name : node.name?.name ?? null;
|
|
31830
|
+
if (node.kind === "offsetlookup" || node.kind === "propertylookup")
|
|
31831
|
+
return rootVarName2(node.what);
|
|
31832
|
+
return null;
|
|
31833
|
+
}
|
|
31834
|
+
function sourceOf2(node) {
|
|
31835
|
+
if (!isNode3(node))
|
|
31836
|
+
return null;
|
|
31837
|
+
if (node.kind === "offsetlookup" && node.what?.kind === "variable") {
|
|
31838
|
+
const n = node.what.name;
|
|
31839
|
+
if (["_GET", "_POST", "_REQUEST", "_COOKIE", "_FILES", "_SERVER"].includes(n))
|
|
31840
|
+
return "$" + n;
|
|
31841
|
+
}
|
|
31842
|
+
if (node.kind === "variable") {
|
|
31843
|
+
const n = node.name;
|
|
31844
|
+
if (["_GET", "_POST", "_REQUEST", "_COOKIE", "_FILES", "_SERVER"].includes(n))
|
|
31845
|
+
return "$" + n;
|
|
31846
|
+
}
|
|
31847
|
+
if (node.kind === "call") {
|
|
31848
|
+
const n = rootVarName2(node.what);
|
|
31849
|
+
if (n === "getallheaders")
|
|
31850
|
+
return "getallheaders";
|
|
31851
|
+
if (n === "file_get_contents" && JSON.stringify(node).includes("php://input"))
|
|
31852
|
+
return "php://input";
|
|
31853
|
+
}
|
|
31854
|
+
return null;
|
|
31855
|
+
}
|
|
31856
|
+
function sinkClassOf2(call) {
|
|
31857
|
+
const what = call.what;
|
|
31858
|
+
if (!isNode3(what))
|
|
31859
|
+
return null;
|
|
31860
|
+
let token = "";
|
|
31861
|
+
if (what.kind === "propertylookup") {
|
|
31862
|
+
const base = rootVarName2(what.what);
|
|
31863
|
+
const method = what.offset?.name ?? what.offset?.value;
|
|
31864
|
+
token = `${base}->${method}(`;
|
|
31865
|
+
} else if (what.kind === "name") {
|
|
31866
|
+
token = `${what.name}(`;
|
|
31867
|
+
}
|
|
31868
|
+
if (!token)
|
|
31869
|
+
return null;
|
|
31870
|
+
const cls = classifySink2(token) ?? classifySink2(what.name ?? "");
|
|
31871
|
+
if (!cls)
|
|
31872
|
+
return null;
|
|
31873
|
+
return { token, cls };
|
|
31874
|
+
}
|
|
31875
|
+
var CLEAN = { tainted: false, sources: [], sanitizers: [] };
|
|
31876
|
+
function mergeTaint(...states) {
|
|
31877
|
+
const taintedStates = states.filter((s) => s.tainted);
|
|
31878
|
+
if (taintedStates.length === 0)
|
|
31879
|
+
return CLEAN;
|
|
31880
|
+
const sources = [...new Set(taintedStates.flatMap((s) => s.sources))];
|
|
31881
|
+
let sanitizers = taintedStates[0].sanitizers;
|
|
31882
|
+
for (const s of taintedStates.slice(1)) {
|
|
31883
|
+
sanitizers = sanitizers.filter((san) => s.sanitizers.some((x) => x.id === san.id));
|
|
31884
|
+
}
|
|
31885
|
+
return {
|
|
31886
|
+
tainted: true,
|
|
31887
|
+
sources,
|
|
31888
|
+
sanitizers,
|
|
31889
|
+
sourceLine: taintedStates.find((s) => s.sourceLine !== undefined)?.sourceLine
|
|
31890
|
+
};
|
|
31891
|
+
}
|
|
31892
|
+
function summarizeFunction(fn, id, name, summaries) {
|
|
31893
|
+
const params = (fn.arguments ?? []).map((a) => nameOf2(a) ?? "?");
|
|
31894
|
+
const byrefParams = new Set;
|
|
31895
|
+
(fn.arguments ?? []).forEach((a, i) => {
|
|
31896
|
+
if (a.byref === true)
|
|
31897
|
+
byrefParams.add(params[i]);
|
|
31898
|
+
});
|
|
31899
|
+
const summary = { id, name, params, byrefParams, paramSinks: new Map, paramReturns: new Set, paramCalls: new Map, paramWrites: new Map };
|
|
31900
|
+
const bodyStmts = fn.body?.kind === "block" ? fn.body.children ?? [] : [fn.body];
|
|
31901
|
+
for (const p of params) {
|
|
31902
|
+
const env = new Map;
|
|
31903
|
+
for (const q of params)
|
|
31904
|
+
env.set(q, CLEAN);
|
|
31905
|
+
env.set(p, { tainted: true, sources: [`arg:${p}`], sanitizers: [] });
|
|
31906
|
+
const ctx = { sinks: [], returnsTainted: false, calls: [] };
|
|
31907
|
+
analyzeBody(bodyStmts, env, summary, ctx, p, new Map, [], summaries);
|
|
31908
|
+
summary.paramSinks.set(p, ctx.sinks);
|
|
31909
|
+
if (ctx.returnsTainted)
|
|
31910
|
+
summary.paramReturns.add(p);
|
|
31911
|
+
summary.paramCalls.set(p, ctx.calls);
|
|
31912
|
+
if (byrefParams.has(p)) {
|
|
31913
|
+
const finalTaint = env.get(p);
|
|
31914
|
+
const written = finalTaint?.sources.filter((s) => !s.startsWith("arg:")) ?? [];
|
|
31915
|
+
if (written.length > 0)
|
|
31916
|
+
summary.paramWrites.set(p, written);
|
|
31917
|
+
}
|
|
31918
|
+
}
|
|
31919
|
+
return summary;
|
|
31920
|
+
}
|
|
31921
|
+
function analyzeBody(statements, env, summary, ctx, taintedParam, props, activeAuth, summaries) {
|
|
31922
|
+
for (const stmt of statements) {
|
|
31923
|
+
if (!isNode3(stmt))
|
|
31924
|
+
continue;
|
|
31925
|
+
const kind = stmt.kind;
|
|
31926
|
+
if (kind === "expressionstatement") {
|
|
31927
|
+
analyzeExpr(stmt.expression, env, summary, ctx, taintedParam, props, activeAuth, summaries);
|
|
31928
|
+
} else if (kind === "if") {
|
|
31929
|
+
const condGates = authGatesOf(stmt.test);
|
|
31930
|
+
const branchAuth = [...activeAuth, ...condGates];
|
|
31931
|
+
const thenStmts = stmt.body?.kind === "block" ? stmt.body.children ?? [] : [stmt.body];
|
|
31932
|
+
const thenEnv = cloneEnv(env);
|
|
31933
|
+
const thenCtx = { sinks: [], returnsTainted: false, calls: [] };
|
|
31934
|
+
analyzeBody(thenStmts, thenEnv, summary, thenCtx, taintedParam, cloneProps(props), branchAuth, summaries);
|
|
31935
|
+
mergeCtx(ctx, thenCtx);
|
|
31936
|
+
if (stmt.alternate) {
|
|
31937
|
+
const altStmts = stmt.alternate.kind === "block" ? stmt.alternate.children ?? [] : [stmt.alternate];
|
|
31938
|
+
const altEnv = cloneEnv(env);
|
|
31939
|
+
const altCtx = { sinks: [], returnsTainted: false, calls: [] };
|
|
31940
|
+
analyzeBody(altStmts, altEnv, summary, altCtx, taintedParam, cloneProps(props), activeAuth, summaries);
|
|
31941
|
+
mergeCtx(ctx, altCtx);
|
|
31942
|
+
for (const [k, v] of thenEnv) {
|
|
31943
|
+
const alt = altEnv.get(k);
|
|
31944
|
+
env.set(k, alt ? mergeTaint(v, alt) : v);
|
|
31945
|
+
}
|
|
31946
|
+
} else {
|
|
31947
|
+
for (const [k, v] of thenEnv)
|
|
31948
|
+
env.set(k, v);
|
|
31949
|
+
}
|
|
31950
|
+
} else if (kind === "block") {
|
|
31951
|
+
analyzeBody(stmt.children ?? [], env, summary, ctx, taintedParam, props, activeAuth, summaries);
|
|
31952
|
+
} else if (kind === "return") {
|
|
31953
|
+
const t = analyzeExpr(stmt.expr, env, summary, ctx, taintedParam, props, activeAuth, summaries);
|
|
31954
|
+
if (t.tainted)
|
|
31955
|
+
ctx.returnsTainted = true;
|
|
31956
|
+
} else if (kind === "echo" || kind === "print") {
|
|
31957
|
+
analyzeExpr(stmt, env, summary, ctx, taintedParam, props, activeAuth, summaries);
|
|
31958
|
+
} else {
|
|
31959
|
+
for (const c of children3(stmt)) {
|
|
31960
|
+
if (c.kind === "block" || c.kind === "if") {
|
|
31961
|
+
analyzeBody([c], env, summary, ctx, taintedParam, props, activeAuth, summaries);
|
|
31962
|
+
} else {
|
|
31963
|
+
analyzeExpr(c, env, summary, ctx, taintedParam, props, activeAuth, summaries);
|
|
31964
|
+
}
|
|
31965
|
+
}
|
|
31966
|
+
}
|
|
31967
|
+
}
|
|
31968
|
+
}
|
|
31969
|
+
function analyzeExpr(node, env, summary, ctx, taintedParam, props, activeAuth, summaries) {
|
|
31970
|
+
if (!isNode3(node))
|
|
31971
|
+
return CLEAN;
|
|
31972
|
+
const src = sourceOf2(node);
|
|
31973
|
+
if (src)
|
|
31974
|
+
return { tainted: true, sources: [src], sanitizers: [], sourceLine: node.loc?.start?.line };
|
|
31975
|
+
if (node.kind === "assign") {
|
|
31976
|
+
const byref = node.operator === "=&";
|
|
31977
|
+
const rhs = analyzeExpr(node.right, env, summary, ctx, taintedParam, props, activeAuth, summaries);
|
|
31978
|
+
const lhs = node.left;
|
|
31979
|
+
if (isNode3(lhs) && lhs.kind === "variable") {
|
|
31980
|
+
const varName = lhs.name;
|
|
31981
|
+
if (byref) {
|
|
31982
|
+
const refVar = rootVarName2(node.right);
|
|
31983
|
+
if (refVar) {
|
|
31984
|
+
const refTaint = env.get(refVar) ?? rhs;
|
|
31985
|
+
env.set(varName, refTaint);
|
|
31986
|
+
env.set(refVar, refTaint);
|
|
31987
|
+
} else {
|
|
31988
|
+
env.set(varName, rhs);
|
|
31989
|
+
}
|
|
31990
|
+
} else {
|
|
31991
|
+
env.set(varName, rhs);
|
|
31992
|
+
}
|
|
31993
|
+
} else if (isNode3(lhs) && lhs.kind === "propertylookup") {
|
|
31994
|
+
const objName = rootVarName2(lhs.what);
|
|
31995
|
+
const propName = lhs.offset?.name ?? "?";
|
|
31996
|
+
if (objName) {
|
|
31997
|
+
let oprops = props.get(objName);
|
|
31998
|
+
if (!oprops) {
|
|
31999
|
+
oprops = new Map;
|
|
32000
|
+
props.set(objName, oprops);
|
|
32001
|
+
}
|
|
32002
|
+
oprops.set(propName, rhs);
|
|
32003
|
+
}
|
|
32004
|
+
}
|
|
32005
|
+
return rhs;
|
|
32006
|
+
}
|
|
32007
|
+
if (node.kind === "call") {
|
|
32008
|
+
const sink = sinkClassOf2(node);
|
|
32009
|
+
const argTaints = node.arguments.map((a) => analyzeExpr(a, env, summary, ctx, taintedParam, props, activeAuth, summaries));
|
|
32010
|
+
const taintedArgs = argTaints.filter((t) => t.tainted);
|
|
32011
|
+
if (sink) {
|
|
32012
|
+
if (taintedArgs.length > 0) {
|
|
32013
|
+
const san = [...taintedArgs.flatMap((t) => t.sanitizers), ...findSanitizers(JSON.stringify(node))];
|
|
32014
|
+
const sanitized = isSanitized(san, sink.cls.id);
|
|
32015
|
+
const gates = activeAuth;
|
|
32016
|
+
ctx.sinks.push({ sink: sink.token, line: node.loc?.start?.line ?? 0, sanitized, authGated: gates.length > 0, authGates: gates });
|
|
32017
|
+
}
|
|
32018
|
+
for (const a of node.arguments)
|
|
32019
|
+
analyzeExpr(a, env, summary, ctx, taintedParam, props, activeAuth, summaries);
|
|
32020
|
+
return taintedArgs.length > 0 ? mergeTaint(...taintedArgs) : CLEAN;
|
|
32021
|
+
}
|
|
32022
|
+
const fnName = rootVarName2(node.what);
|
|
32023
|
+
if (fnName) {
|
|
32024
|
+
const san = findSanitizers(fnName + "(");
|
|
32025
|
+
if (san.length > 0) {
|
|
32026
|
+
if (taintedArgs.length > 0) {
|
|
32027
|
+
return mergeTaint(...taintedArgs.map((t) => ({ ...t, sanitizers: [...t.sanitizers, ...san] })));
|
|
32028
|
+
}
|
|
32029
|
+
return CLEAN;
|
|
32030
|
+
}
|
|
32031
|
+
for (let i = 0;i < node.arguments.length; i++) {
|
|
32032
|
+
const argVar = rootVarName2(node.arguments[i]);
|
|
32033
|
+
if (argVar === taintedParam) {
|
|
32034
|
+
ctx.calls.push({ callee: fnName, argIndex: i, line: node.loc?.start?.line ?? 0 });
|
|
32035
|
+
}
|
|
32036
|
+
}
|
|
32037
|
+
const helperId = resolveFuncId(fnName, summaries);
|
|
32038
|
+
const helperSum = helperId ? summaries.get(helperId) : undefined;
|
|
32039
|
+
if (helperSum && taintedArgs.length > 0) {
|
|
32040
|
+
for (let i = 0;i < node.arguments.length; i++) {
|
|
32041
|
+
if (argTaints[i]?.tainted) {
|
|
32042
|
+
const paramName = helperSum.params[i];
|
|
32043
|
+
if (paramName && helperSum.paramReturns.has(paramName)) {
|
|
32044
|
+
return mergeTaint(...taintedArgs);
|
|
32045
|
+
}
|
|
32046
|
+
}
|
|
32047
|
+
}
|
|
32048
|
+
}
|
|
32049
|
+
if (helperSum && helperSum.paramWrites.size > 0) {
|
|
32050
|
+
for (let i = 0;i < node.arguments.length; i++) {
|
|
32051
|
+
const paramName = helperSum.params[i];
|
|
32052
|
+
if (!paramName || !helperSum.paramWrites.has(paramName))
|
|
32053
|
+
continue;
|
|
32054
|
+
const argVar = rootVarName2(node.arguments[i]);
|
|
32055
|
+
const written = helperSum.paramWrites.get(paramName);
|
|
32056
|
+
if (argVar) {
|
|
32057
|
+
env.set(argVar, { tainted: true, sources: written, sanitizers: [] });
|
|
32058
|
+
}
|
|
32059
|
+
}
|
|
32060
|
+
}
|
|
32061
|
+
}
|
|
32062
|
+
return CLEAN;
|
|
32063
|
+
}
|
|
32064
|
+
if (node.kind === "variable") {
|
|
32065
|
+
const t = env.get(node.name);
|
|
32066
|
+
return t ? { ...t } : CLEAN;
|
|
32067
|
+
}
|
|
32068
|
+
if (node.kind === "offsetlookup") {
|
|
32069
|
+
const root = rootVarName2(node);
|
|
32070
|
+
if (root) {
|
|
32071
|
+
const t = env.get(root);
|
|
32072
|
+
if (t)
|
|
32073
|
+
return { ...t };
|
|
32074
|
+
}
|
|
32075
|
+
return analyzeExpr(node.what, env, summary, ctx, taintedParam, props, activeAuth, summaries);
|
|
32076
|
+
}
|
|
32077
|
+
if (node.kind === "propertylookup") {
|
|
32078
|
+
const objName = rootVarName2(node.what);
|
|
32079
|
+
const propName = node.offset?.name ?? "?";
|
|
32080
|
+
if (objName) {
|
|
32081
|
+
const pt = props.get(objName)?.get(propName);
|
|
32082
|
+
if (pt)
|
|
32083
|
+
return { ...pt };
|
|
32084
|
+
}
|
|
32085
|
+
return analyzeExpr(node.what, env, summary, ctx, taintedParam, props, activeAuth, summaries);
|
|
32086
|
+
}
|
|
32087
|
+
if (node.kind === "retif") {
|
|
32088
|
+
const t = analyzeExpr(node.trueExpr ?? node.test, env, summary, ctx, taintedParam, props, activeAuth, summaries);
|
|
32089
|
+
const f = node.falseExpr ? analyzeExpr(node.falseExpr, env, summary, ctx, taintedParam, props, activeAuth, summaries) : CLEAN;
|
|
32090
|
+
return mergeTaint(t, f);
|
|
32091
|
+
}
|
|
32092
|
+
if (node.kind === "bin" || node.kind === "concat" || node.kind === "encapsed") {
|
|
32093
|
+
const parts = children3(node);
|
|
32094
|
+
const taints = parts.map((p) => analyzeExpr(p, env, summary, ctx, taintedParam, props, activeAuth, summaries));
|
|
32095
|
+
return mergeTaint(...taints);
|
|
32096
|
+
}
|
|
32097
|
+
if (node.kind === "encapsedpart") {
|
|
32098
|
+
return analyzeExpr(node.expression, env, summary, ctx, taintedParam, props, activeAuth, summaries);
|
|
32099
|
+
}
|
|
32100
|
+
if (node.kind === "echo" || node.kind === "print") {
|
|
32101
|
+
const exprs = node.expressions ?? [node.expression];
|
|
32102
|
+
const cls = classifySink2(node.kind === "echo" ? "echo " : "print ");
|
|
32103
|
+
let ret = CLEAN;
|
|
32104
|
+
for (const e of exprs) {
|
|
32105
|
+
const t = analyzeExpr(e, env, summary, ctx, taintedParam, props, activeAuth, summaries);
|
|
32106
|
+
if (t.tainted && cls) {
|
|
32107
|
+
const san = [...t.sanitizers, ...findSanitizers(JSON.stringify(e))];
|
|
32108
|
+
ctx.sinks.push({ sink: node.kind + " ", line: node.loc?.start?.line ?? 0, sanitized: isSanitized(san, cls.id), authGated: activeAuth.length > 0, authGates: activeAuth });
|
|
32109
|
+
}
|
|
32110
|
+
ret = mergeTaint(ret, t);
|
|
32111
|
+
}
|
|
32112
|
+
return ret;
|
|
32113
|
+
}
|
|
32114
|
+
return CLEAN;
|
|
32115
|
+
}
|
|
32116
|
+
function cloneEnv(env) {
|
|
32117
|
+
return new Map([...env.entries()].map(([k, v]) => [k, { ...v, sources: [...v.sources], sanitizers: [...v.sanitizers] }]));
|
|
32118
|
+
}
|
|
32119
|
+
function cloneProps(props) {
|
|
32120
|
+
const out = new Map;
|
|
32121
|
+
for (const [k, v] of props)
|
|
32122
|
+
out.set(k, new Map(v));
|
|
32123
|
+
return out;
|
|
32124
|
+
}
|
|
32125
|
+
function mergeCtx(ctx, other) {
|
|
32126
|
+
ctx.sinks.push(...other.sinks);
|
|
32127
|
+
if (other.returnsTainted)
|
|
32128
|
+
ctx.returnsTainted = true;
|
|
32129
|
+
ctx.calls.push(...other.calls);
|
|
32130
|
+
}
|
|
32131
|
+
function authGatesOf(node) {
|
|
32132
|
+
if (!isNode3(node))
|
|
32133
|
+
return [];
|
|
32134
|
+
return AUTH_GATES.filter((g) => JSON.stringify(node).includes(g));
|
|
32135
|
+
}
|
|
32136
|
+
function collectDecls(ast, out) {
|
|
32137
|
+
walkDecls(ast, out);
|
|
32138
|
+
}
|
|
32139
|
+
function walkDecls(node, out, className) {
|
|
32140
|
+
if (!isNode3(node))
|
|
32141
|
+
return;
|
|
32142
|
+
if (node.kind === "function") {
|
|
32143
|
+
const name = nameOf2(node.name);
|
|
32144
|
+
if (name)
|
|
32145
|
+
out.push({ id: `func:${name}`, name, node, kind: "function" });
|
|
32146
|
+
} else if (node.kind === "class") {
|
|
32147
|
+
const cn = nameOf2(node.name);
|
|
32148
|
+
for (const c of children3(node)) {
|
|
32149
|
+
if (c.kind === "method") {
|
|
32150
|
+
const mn = nameOf2(c.name);
|
|
32151
|
+
if (mn && cn)
|
|
32152
|
+
out.push({ id: `method:${cn}::${mn}`, name: mn, node: c, kind: "method" });
|
|
32153
|
+
}
|
|
32154
|
+
}
|
|
32155
|
+
return;
|
|
32156
|
+
} else if (node.kind === "method") {
|
|
32157
|
+
const mn = nameOf2(node.name);
|
|
32158
|
+
if (mn && className)
|
|
32159
|
+
out.push({ id: `method:${className}::${mn}`, name: mn, node, kind: "method" });
|
|
32160
|
+
}
|
|
32161
|
+
const childCtx = node.kind === "class" ? nameOf2(node.name) ?? className : className;
|
|
32162
|
+
for (const c of children3(node))
|
|
32163
|
+
walkDecls(c, out, childCtx);
|
|
32164
|
+
}
|
|
32165
|
+
function resolveFuncId(name, summaries) {
|
|
32166
|
+
if (summaries.has(`func:${name}`))
|
|
32167
|
+
return `func:${name}`;
|
|
32168
|
+
for (const [id, s] of summaries) {
|
|
32169
|
+
if (s.name === name && id.startsWith("method:"))
|
|
32170
|
+
return id;
|
|
32171
|
+
}
|
|
32172
|
+
return null;
|
|
32173
|
+
}
|
|
32174
|
+
function analyzeDataFlow2(path) {
|
|
32175
|
+
const cg = buildCallGraph(path);
|
|
32176
|
+
const result = {
|
|
32177
|
+
file: path,
|
|
32178
|
+
findings: [],
|
|
32179
|
+
suppressed: 0,
|
|
32180
|
+
summary: { functions: 0, methods: 0, edges: cg.edges.length, call_graph: cg }
|
|
32181
|
+
};
|
|
32182
|
+
let code;
|
|
32183
|
+
try {
|
|
32184
|
+
code = readFileSync12(path, "utf8");
|
|
32185
|
+
} catch {
|
|
32186
|
+
return result;
|
|
32187
|
+
}
|
|
32188
|
+
let ast;
|
|
32189
|
+
try {
|
|
32190
|
+
ast = parser3.parseCode(code, path);
|
|
32191
|
+
} catch {
|
|
32192
|
+
return result;
|
|
32193
|
+
}
|
|
32194
|
+
const summaries = new Map;
|
|
32195
|
+
const decls = [];
|
|
32196
|
+
collectDecls(ast, decls);
|
|
32197
|
+
for (const d of decls) {
|
|
32198
|
+
summaries.set(d.id, summarizeFunction(d.node, d.id, d.name, summaries));
|
|
32199
|
+
if (d.kind === "function")
|
|
32200
|
+
result.summary.functions += 1;
|
|
32201
|
+
else
|
|
32202
|
+
result.summary.methods += 1;
|
|
32203
|
+
}
|
|
32204
|
+
const topStmts = [];
|
|
32205
|
+
for (const s of ast.children ?? []) {
|
|
32206
|
+
if (isNode3(s) && s.kind !== "function" && s.kind !== "class")
|
|
32207
|
+
topStmts.push(s);
|
|
32208
|
+
}
|
|
32209
|
+
const mainSummary = { id: "main", name: "main", params: [], byrefParams: new Set, paramSinks: new Map, paramReturns: new Set, paramCalls: new Map, paramWrites: new Map };
|
|
32210
|
+
const mainEnv = new Map;
|
|
32211
|
+
const mainCtx = { sinks: [], returnsTainted: false, calls: [] };
|
|
32212
|
+
const mainProps = new Map;
|
|
32213
|
+
analyzeBody(topStmts, mainEnv, mainSummary, mainCtx, "", mainProps, [], summaries);
|
|
32214
|
+
for (const hit of mainCtx.sinks) {
|
|
32215
|
+
const cls = classifySink2(hit.sink);
|
|
32216
|
+
if (!cls)
|
|
32217
|
+
continue;
|
|
32218
|
+
if (hit.sanitized) {
|
|
32219
|
+
result.suppressed += 1;
|
|
32220
|
+
continue;
|
|
32221
|
+
}
|
|
32222
|
+
result.findings.push({
|
|
32223
|
+
sink: hit.sink,
|
|
32224
|
+
sink_line: hit.line,
|
|
32225
|
+
category: cls.category,
|
|
32226
|
+
cwe: cls.cwe,
|
|
32227
|
+
sanitized: false,
|
|
32228
|
+
auth_gated: hit.authGated,
|
|
32229
|
+
auth_gates: hit.authGates,
|
|
32230
|
+
interprocedural: false,
|
|
32231
|
+
via_return: false
|
|
32232
|
+
});
|
|
32233
|
+
}
|
|
32234
|
+
const queue = [];
|
|
32235
|
+
const seen = new Set;
|
|
32236
|
+
const mainCalls = topStmts.flatMap((s) => findKind2(s, "call"));
|
|
32237
|
+
for (const call of mainCalls) {
|
|
32238
|
+
const fnName = rootVarName2(call.what);
|
|
32239
|
+
if (!fnName || sinkClassOf2(call))
|
|
32240
|
+
continue;
|
|
32241
|
+
const target = resolveFuncId(fnName, summaries);
|
|
32242
|
+
if (!target)
|
|
32243
|
+
continue;
|
|
32244
|
+
for (let i = 0;i < call.arguments.length; i++) {
|
|
32245
|
+
const argTaint = analyzeExpr(call.arguments[i], mainEnv, mainSummary, mainCtx, "", mainProps, [], summaries);
|
|
32246
|
+
if (argTaint.tainted) {
|
|
32247
|
+
const param = summaries.get(target).params[i];
|
|
32248
|
+
if (param)
|
|
32249
|
+
queue.push({ funcId: target, param, source: argTaint.sources[0], sourceLine: argTaint.sourceLine, viaReturn: false });
|
|
32250
|
+
}
|
|
32251
|
+
}
|
|
32252
|
+
}
|
|
32253
|
+
while (queue.length) {
|
|
32254
|
+
const item = queue.shift();
|
|
32255
|
+
const key = `${item.funcId}:${item.param}`;
|
|
32256
|
+
if (seen.has(key))
|
|
32257
|
+
continue;
|
|
32258
|
+
seen.add(key);
|
|
32259
|
+
const sum = summaries.get(item.funcId);
|
|
32260
|
+
if (!sum)
|
|
32261
|
+
continue;
|
|
32262
|
+
for (const hit of sum.paramSinks.get(item.param) ?? []) {
|
|
32263
|
+
const cls = classifySink2(hit.sink);
|
|
32264
|
+
if (!cls)
|
|
32265
|
+
continue;
|
|
32266
|
+
if (hit.sanitized) {
|
|
32267
|
+
result.suppressed += 1;
|
|
32268
|
+
continue;
|
|
32269
|
+
}
|
|
32270
|
+
result.findings.push({
|
|
32271
|
+
sink: hit.sink,
|
|
32272
|
+
sink_line: hit.line,
|
|
32273
|
+
category: cls.category,
|
|
32274
|
+
cwe: cls.cwe,
|
|
32275
|
+
source: item.source,
|
|
32276
|
+
source_line: item.sourceLine,
|
|
32277
|
+
sanitized: false,
|
|
32278
|
+
auth_gated: hit.authGated,
|
|
32279
|
+
auth_gates: hit.authGates,
|
|
32280
|
+
interprocedural: true,
|
|
32281
|
+
via_return: item.viaReturn
|
|
32282
|
+
});
|
|
32283
|
+
}
|
|
32284
|
+
for (const c of sum.paramCalls.get(item.param) ?? []) {
|
|
32285
|
+
const calleeId = resolveFuncId(c.callee, summaries);
|
|
32286
|
+
if (!calleeId)
|
|
32287
|
+
continue;
|
|
32288
|
+
const calleeParam = summaries.get(calleeId).params[c.argIndex];
|
|
32289
|
+
if (calleeParam)
|
|
32290
|
+
queue.push({ funcId: calleeId, param: calleeParam, source: item.source, sourceLine: item.sourceLine, viaReturn: false });
|
|
32291
|
+
}
|
|
32292
|
+
}
|
|
32293
|
+
return result;
|
|
32294
|
+
}
|
|
32295
|
+
|
|
31599
32296
|
// src/universal-taint.ts
|
|
31600
32297
|
function runTaintEngine(adapter, code, file) {
|
|
31601
32298
|
const result = { file, language: adapter.language, findings: [], suppressed: 0 };
|
|
@@ -31697,7 +32394,7 @@ function analyzeTaintUniversal(code, file) {
|
|
|
31697
32394
|
}
|
|
31698
32395
|
|
|
31699
32396
|
// src/adapters.ts
|
|
31700
|
-
var
|
|
32397
|
+
var import_php_parser4 = __toESM(require_src(), 1);
|
|
31701
32398
|
|
|
31702
32399
|
// node_modules/@babel/parser/lib/index.js
|
|
31703
32400
|
class Position {
|
|
@@ -49476,7 +50173,7 @@ var pythonHighlighting = styleTags({
|
|
|
49476
50173
|
", ;": tags.separator
|
|
49477
50174
|
});
|
|
49478
50175
|
var spec_identifier = { __proto__: null, await: 44, or: 54, and: 56, in: 60, not: 62, is: 64, if: 70, else: 72, lambda: 76, yield: 94, from: 96, async: 102, for: 104, None: 162, True: 164, False: 164, del: 178, pass: 182, break: 186, continue: 190, return: 194, raise: 202, import: 206, as: 208, global: 212, nonlocal: 214, assert: 218, type: 223, elif: 236, while: 240, try: 246, except: 248, finally: 250, with: 254, def: 258, class: 268, match: 279, case: 285 };
|
|
49479
|
-
var
|
|
50176
|
+
var parser4 = LRParser.deserialize({
|
|
49480
50177
|
version: 14,
|
|
49481
50178
|
states: "##jQ`QeOOP$}OSOOO&WQtO'#HUOOQS'#Co'#CoOOQS'#Cp'#CpO'vQdO'#CnO*UQtO'#HTOOQS'#HU'#HUOOQS'#DU'#DUOOQS'#HT'#HTO*rQdO'#D_O+VQdO'#DfO+gQdO'#DjO+zOWO'#DuO,VOWO'#DvO.[QtO'#GuOOQS'#Gu'#GuO'vQdO'#GtO0ZQtO'#GtOOQS'#Eb'#EbO0rQdO'#EcOOQS'#Gs'#GsO0|QdO'#GrOOQV'#Gr'#GrO1XQdO'#FYOOQS'#G^'#G^O1^QdO'#FXOOQV'#IS'#ISOOQV'#Gq'#GqOOQV'#Fq'#FqQ`QeOOO'vQdO'#CqO1lQdO'#C}O1sQdO'#DRO2RQdO'#HYO2cQtO'#EVO'vQdO'#EWOOQS'#EY'#EYOOQS'#E['#E[OOQS'#E^'#E^O2wQdO'#E`O3_QdO'#EdO3rQdO'#EfO3zQtO'#EfO1XQdO'#EiO0rQdO'#ElO1XQdO'#EnO0rQdO'#EtO0rQdO'#EwO4VQdO'#EyO4^QdO'#FOO4iQdO'#EzO0rQdO'#FOO1XQdO'#FQO1XQdO'#FVO4nQdO'#F[P4uOdO'#GpPOOO)CBd)CBdOOQS'#Ce'#CeOOQS'#Cf'#CfOOQS'#Cg'#CgOOQS'#Ch'#ChOOQS'#Ci'#CiOOQS'#Cj'#CjOOQS'#Cl'#ClO'vQdO,59OO'vQdO,59OO'vQdO,59OO'vQdO,59OO'vQdO,59OO'vQdO,59OO5TQdO'#DoOOQS,5:Y,5:YO5hQdO'#HdOOQS,5:],5:]O5uQ!fO,5:]O5zQtO,59YO1lQdO,59bO1lQdO,59bO1lQdO,59bO8jQdO,59bO8oQdO,59bO8vQdO,59jO8}QdO'#HTO:TQdO'#HSOOQS'#HS'#HSOOQS'#D['#D[O:lQdO,59aO'vQdO,59aO:zQdO,59aOOQS,59y,59yO;PQdO,5:RO'vQdO,5:ROOQS,5:Q,5:QO;_QdO,5:QO;dQdO,5:XO'vQdO,5:XO'vQdO,5:VOOQS,5:U,5:UO;uQdO,5:UO;zQdO,5:WOOOW'#Fy'#FyO<POWO,5:aOOQS,5:a,5:aO<[QdO'#HwOOOW'#Dw'#DwOOOW'#Fz'#FzO<lOWO,5:bOOQS,5:b,5:bOOQS'#F}'#F}O<zQtO,5:iO?lQtO,5=`O@VQ#xO,5=`O@vQtO,5=`OOQS,5:},5:}OA_QeO'#GWOBqQdO,5;^OOQV,5=^,5=^OB|QtO'#IPOCkQdO,5;tOOQS-E:[-E:[OOQV,5;s,5;sO4dQdO'#FQOOQV-E9o-E9oOCsQtO,59]OEzQtO,59iOFeQdO'#HVOFpQdO'#HVO1XQdO'#HVOF{QdO'#DTOGTQdO,59mOGYQdO'#HZO'vQdO'#HZO0rQdO,5=tOOQS,5=t,5=tO0rQdO'#EROOQS'#ES'#ESOGwQdO'#GPOHXQdO,58|OHXQdO,58|O*xQdO,5:oOHgQtO'#H]OOQS,5:r,5:rOOQS,5:z,5:zOHzQdO,5;OOI]QdO'#IOO1XQdO'#H}OOQS,5;Q,5;QOOQS'#GT'#GTOIqQtO,5;QOJPQdO,5;QOJUQdO'#IQOOQS,5;T,5;TOJdQdO'#H|OOQS,5;W,5;WOJuQdO,5;YO4iQdO,5;`O4iQdO,5;cOJ}QtO'#ITO'vQdO'#ITOKXQdO,5;eO4VQdO,5;eO0rQdO,5;jO1XQdO,5;lOK^QeO'#EuOLjQgO,5;fO!!kQdO'#IUO4iQdO,5;jO!!vQdO,5;lO!#OQdO,5;qO!#ZQtO,5;vO'vQdO,5;vPOOO,5=[,5=[P!#bOSO,5=[P!#jOdO,5=[O!&bQtO1G.jO!&iQtO1G.jO!)YQtO1G.jO!)dQtO1G.jO!+}QtO1G.jO!,bQtO1G.jO!,uQdO'#HcO!-TQtO'#GuO0rQdO'#HcO!-_QdO'#HbOOQS,5:Z,5:ZO!-gQdO,5:ZO!-lQdO'#HeO!-wQdO'#HeO!.[QdO,5>OOOQS'#Ds'#DsOOQS1G/w1G/wOOQS1G.|1G.|O!/[QtO1G.|O!/cQtO1G.|O1lQdO1G.|O!0OQdO1G/UOOQS'#DZ'#DZO0rQdO,59tOOQS1G.{1G.{O!0VQdO1G/eO!0gQdO1G/eO!0oQdO1G/fO'vQdO'#H[O!0tQdO'#H[O!0yQtO1G.{O!1ZQdO,59iO!2aQdO,5=zO!2qQdO,5=zO!2yQdO1G/mO!3OQtO1G/mOOQS1G/l1G/lO!3`QdO,5=uO!4VQdO,5=uO0rQdO1G/qO!4tQdO1G/sO!4yQtO1G/sO!5ZQtO1G/qOOQS1G/p1G/pOOQS1G/r1G/rOOOW-E9w-E9wOOQS1G/{1G/{O!5kQdO'#HxO0rQdO'#HxO!5|QdO,5>cOOOW-E9x-E9xOOQS1G/|1G/|OOQS-E9{-E9{O!6[Q#xO1G2zO!6{QtO1G2zO'vQdO,5<jOOQS,5<j,5<jOOQS-E9|-E9|OOQS,5<r,5<rOOQS-E:U-E:UOOQV1G0x1G0xO1XQdO'#GRO!7dQtO,5>kOOQS1G1`1G1`O!8RQdO1G1`OOQS'#DV'#DVO0rQdO,5=qOOQS,5=q,5=qO!8WQdO'#FrO!8cQdO,59oO!8kQdO1G/XO!8uQtO,5=uOOQS1G3`1G3`OOQS,5:m,5:mO!9fQdO'#GtOOQS,5<k,5<kOOQS-E9}-E9}O!9wQdO1G.hOOQS1G0Z1G0ZO!:VQdO,5=wO!:gQdO,5=wO0rQdO1G0jO0rQdO1G0jO!:xQdO,5>jO!;ZQdO,5>jO1XQdO,5>jO!;lQdO,5>iOOQS-E:R-E:RO!;qQdO1G0lO!;|QdO1G0lO!<RQdO,5>lO!<aQdO,5>lO!<oQdO,5>hO!=VQdO,5>hO!=hQdO'#EpO0rQdO1G0tO!=sQdO1G0tO!=xQgO1G0zO!AvQgO1G0}O!EqQdO,5>oO!E{QdO,5>oO!FTQtO,5>oO0rQdO1G1PO!F_QdO1G1PO4iQdO1G1UO!!vQdO1G1WOOQV,5;a,5;aO!FdQfO,5;aO!FiQgO1G1QO!JjQdO'#GZO4iQdO1G1QO4iQdO1G1QO!JzQdO,5>pO!KXQdO,5>pO1XQdO,5>pOOQV1G1U1G1UO!KaQdO'#FSO!KrQ!fO1G1WO!KzQdO1G1WOOQV1G1]1G1]O4iQdO1G1]O!LPQdO1G1]O!LXQdO'#F^OOQV1G1b1G1bO!#ZQtO1G1bPOOO1G2v1G2vP!L^OSO1G2vOOQS,5=},5=}OOQS'#Dp'#DpO0rQdO,5=}O!LfQdO,5=|O!LyQdO,5=|OOQS1G/u1G/uO!MRQdO,5>PO!McQdO,5>PO!MkQdO,5>PO!NOQdO,5>PO!N`QdO,5>POOQS1G3j1G3jOOQS7+$h7+$hO!8kQdO7+$pO#!RQdO1G.|O#!YQdO1G.|OOQS1G/`1G/`OOQS,5<`,5<`O'vQdO,5<`OOQS7+%P7+%PO#!aQdO7+%POOQS-E9r-E9rOOQS7+%Q7+%QO#!qQdO,5=vO'vQdO,5=vOOQS7+$g7+$gO#!vQdO7+%PO##OQdO7+%QO##TQdO1G3fOOQS7+%X7+%XO##eQdO1G3fO##mQdO7+%XOOQS,5<_,5<_O'vQdO,5<_O##rQdO1G3aOOQS-E9q-E9qO#$iQdO7+%]OOQS7+%_7+%_O#$wQdO1G3aO#%fQdO7+%_O#%kQdO1G3gO#%{QdO1G3gO#&TQdO7+%]O#&YQdO,5>dO#&sQdO,5>dO#&sQdO,5>dOOQS'#Dx'#DxO#'UO&jO'#DzO#'aO`O'#HyOOOW1G3}1G3}O#'fQdO1G3}O#'nQdO1G3}O#'yQ#xO7+(fO#(jQtO1G2UP#)TQdO'#GOOOQS,5<m,5<mOOQS-E:P-E:POOQS7+&z7+&zOOQS1G3]1G3]OOQS,5<^,5<^OOQS-E9p-E9pOOQS7+$s7+$sO#)bQdO,5=`O#){QdO,5=`O#*^QtO,5<aO#*qQdO1G3cOOQS-E9s-E9sOOQS7+&U7+&UO#+RQdO7+&UO#+aQdO,5<nO#+uQdO1G4UOOQS-E:Q-E:QO#,WQdO1G4UOOQS1G4T1G4TOOQS7+&W7+&WO#,iQdO7+&WOOQS,5<p,5<pO#,tQdO1G4WOOQS-E:S-E:SOOQS,5<l,5<lO#-SQdO1G4SOOQS-E:O-E:OO1XQdO'#EqO#-jQdO'#EqO#-uQdO'#IRO#-}QdO,5;[OOQS7+&`7+&`O0rQdO7+&`O#.SQgO7+&fO!JmQdO'#GXO4iQdO7+&fO4iQdO7+&iO#2QQtO,5<tO'vQdO,5<tO#2[QdO1G4ZOOQS-E:W-E:WO#2fQdO1G4ZO4iQdO7+&kO0rQdO7+&kOOQV7+&p7+&pO!KrQ!fO7+&rO!KzQdO7+&rO`QeO1G0{OOQV-E:X-E:XO4iQdO7+&lO4iQdO7+&lOOQV,5<u,5<uO#2nQdO,5<uO!JmQdO,5<uOOQV7+&l7+&lO#2yQgO7+&lO#6tQdO,5<vO#7PQdO1G4[OOQS-E:Y-E:YO#7^QdO1G4[O#7fQdO'#IWO#7tQdO'#IWO1XQdO'#IWOOQS'#IW'#IWO#8PQdO'#IVOOQS,5;n,5;nO#8XQdO,5;nO0rQdO'#FUOOQV7+&r7+&rO4iQdO7+&rOOQV7+&w7+&wO4iQdO7+&wO#8^QfO,5;xOOQV7+&|7+&|POOO7+(b7+(bO#8cQdO1G3iOOQS,5<c,5<cO#8qQdO1G3hOOQS-E9u-E9uO#9UQdO,5<dO#9aQdO,5<dO#9tQdO1G3kOOQS-E9v-E9vO#:UQdO1G3kO#:^QdO1G3kO#:nQdO1G3kO#:UQdO1G3kOOQS<<H[<<H[O#:yQtO1G1zOOQS<<Hk<<HkP#;WQdO'#FtO8vQdO1G3bO#;eQdO1G3bO#;jQdO<<HkOOQS<<Hl<<HlO#;zQdO7+)QOOQS<<Hs<<HsO#<[QtO1G1yP#<{QdO'#FsO#=YQdO7+)RO#=jQdO7+)RO#=rQdO<<HwO#=wQdO7+({OOQS<<Hy<<HyO#>nQdO,5<bO'vQdO,5<bOOQS-E9t-E9tOOQS<<Hw<<HwOOQS,5<g,5<gO0rQdO,5<gO#>sQdO1G4OOOQS-E9y-E9yO#?^QdO1G4OO<[QdO'#H{OOOO'#D{'#D{OOOO'#F|'#F|O#?oO&jO,5:fOOOW,5>e,5>eOOOW7+)i7+)iO#?zQdO7+)iO#@SQdO1G2zO#@mQdO1G2zP'vQdO'#FuO0rQdO<<IpO1XQdO1G2YP1XQdO'#GSO#AOQdO7+)pO#AaQdO7+)pOOQS<<Ir<<IrP1XQdO'#GUP0rQdO'#GQOOQS,5;],5;]O#ArQdO,5>mO#BQQdO,5>mOOQS1G0v1G0vOOQS<<Iz<<IzOOQV-E:V-E:VO4iQdO<<JQOOQV,5<s,5<sO4iQdO,5<sOOQV<<JQ<<JQOOQV<<JT<<JTO#BYQtO1G2`P#BdQdO'#GYO#BkQdO7+)uO#BuQgO<<JVO4iQdO<<JVOOQV<<J^<<J^O4iQdO<<J^O!KrQ!fO<<J^O#FpQgO7+&gOOQV<<JW<<JWO#FzQgO<<JWOOQV1G2a1G2aO1XQdO1G2aO#JuQdO1G2aO4iQdO<<JWO1XQdO1G2bP0rQdO'#G[O#KQQdO7+)vO#K_QdO7+)vOOQS'#FT'#FTO0rQdO,5>rO#KgQdO,5>rO#KrQdO,5>rO#K}QdO,5>qO#L`QdO,5>qOOQS1G1Y1G1YOOQS,5;p,5;pOOQV<<Jc<<JcO#LhQdO1G1dOOQS7+)T7+)TP#LmQdO'#FwO#L}QdO1G2OO#MbQdO1G2OO#MrQdO1G2OP#M}QdO'#FxO#N[QdO7+)VO#NlQdO7+)VO#NlQdO7+)VO#NtQdO7+)VO$ UQdO7+(|O8vQdO7+(|OOQSAN>VAN>VO$ oQdO<<LmOOQSAN>cAN>cO0rQdO1G1|O$!PQtO1G1|P$!ZQdO'#FvOOQS1G2R1G2RP$!hQdO'#F{O$!uQdO7+)jO$#`QdO,5>gOOOO-E9z-E9zOOOW<<MT<<MTO$#nQdO7+(fOOQSAN?[AN?[OOQS7+'t7+'tO$$XQdO<<M[OOQS,5<q,5<qO$$jQdO1G4XOOQS-E:T-E:TOOQVAN?lAN?lOOQV1G2_1G2_O4iQdOAN?qO$$xQgOAN?qOOQVAN?xAN?xO4iQdOAN?xOOQV<<JR<<JRO4iQdOAN?rO4iQdO7+'{OOQV7+'{7+'{O1XQdO7+'{OOQVAN?rAN?rOOQS7+'|7+'|O$(sQdO<<MbOOQS1G4^1G4^O0rQdO1G4^OOQS,5<w,5<wO$)QQdO1G4]OOQS-E:Z-E:ZOOQU'#G_'#G_O$)cQfO7+'OO$)nQdO'#F_O$*uQdO7+'jO$+VQdO7+'jOOQS7+'j7+'jO$+bQdO<<LqO$+rQdO<<LqO$+rQdO<<LqO$+zQdO'#H^OOQS<<Lh<<LhO$,UQdO<<LhOOQS7+'h7+'hOOQS'#D|'#D|OOOO1G4R1G4RO$,oQdO1G4RO$,wQdO1G4RP!=hQdO'#GVOOQVG25]G25]O4iQdOG25]OOQVG25dG25dOOQVG25^G25^OOQV<<Kg<<KgO4iQdO<<KgOOQS7+)x7+)xP$-SQdO'#G]OOQU-E:]-E:]OOQV<<Jj<<JjO$-vQtO'#FaOOQS'#Fc'#FcO$.WQdO'#FbO$.xQdO'#FbOOQS'#Fb'#FbO$.}QdO'#IYO$)nQdO'#FiO$)nQdO'#FiO$/fQdO'#FjO$)nQdO'#FkO$/mQdO'#IZOOQS'#IZ'#IZO$0[QdO,5;yOOQS<<KU<<KUO$0dQdO<<KUO$0tQdOANB]O$1UQdOANB]O$1^QdO'#H_OOQS'#H_'#H_O1sQdO'#DcO$1wQdO,5=xOOQSANBSANBSOOOO7+)m7+)mO$2`QdO7+)mOOQVLD*wLD*wOOQVANARANARO5uQ!fO'#GaO$2hQtO,5<SO$)nQdO'#FmOOQS,5<W,5<WOOQS'#Fd'#FdO$3YQdO,5;|O$3_QdO,5;|OOQS'#Fg'#FgO$)nQdO'#G`O$4PQdO,5<QO$4kQdO,5>tO$4{QdO,5>tO1XQdO,5<PO$5^QdO,5<TO$5cQdO,5<TO$)nQdO'#I[O$5hQdO'#I[O$5mQdO,5<UOOQS,5<V,5<VO0rQdO'#FpOOQU1G1e1G1eO4iQdO1G1eOOQSAN@pAN@pO$5rQdOG27wO$6SQdO,59}OOQS1G3d1G3dOOOO<<MX<<MXOOQS,5<{,5<{OOQS-E:_-E:_O$6XQtO'#FaO$6`QdO'#I]O$6nQdO'#I]O$6vQdO,5<XOOQS1G1h1G1hO$6{QdO1G1hO$7QQdO,5<zOOQS-E:^-E:^O$7lQdO,5=OO$8TQdO1G4`OOQS-E:b-E:bOOQS1G1k1G1kOOQS1G1o1G1oO$8eQdO,5>vO$)nQdO,5>vOOQS1G1p1G1pOOQS,5<[,5<[OOQU7+'P7+'PO$+zQdO1G/iO$)nQdO,5<YO$8sQdO,5>wO$8zQdO,5>wOOQS1G1s1G1sOOQS7+'S7+'SP$)nQdO'#GdO$9SQdO1G4bO$9^QdO1G4bO$9fQdO1G4bOOQS7+%T7+%TO$9tQdO1G1tO$:SQtO'#FaO$:ZQdO,5<}OOQS,5<},5<}O$:iQdO1G4cOOQS-E:a-E:aO$)nQdO,5<|O$:pQdO,5<|O$:uQdO7+)|OOQS-E:`-E:`O$;PQdO7+)|O$)nQdO,5<ZP$)nQdO'#GcO$;XQdO1G2hO$)nQdO1G2hP$;gQdO'#GbO$;nQdO<<MhO$;xQdO1G1uO$<WQdO7+(SO8vQdO'#C}O8vQdO,59bO8vQdO,59bO8vQdO,59bO$<fQtO,5=`O8vQdO1G.|O0rQdO1G/XO0rQdO7+$pP$<yQdO'#GOO'vQdO'#GtO$=WQdO,59bO$=]QdO,59bO$=dQdO,59mO$=iQdO1G/UO1sQdO'#DRO8vQdO,59j",
|
|
49482
50179
|
stateData: "$>S~O%cOS%^OSSOS%]PQ~OPdOVaOfoOhYOopOs!POvqO!PrO!Q{O!T!SO!U!RO!XZO!][O!h`O!r`O!s`O!t`O!{tO!}uO#PvO#RwO#TxO#XyO#ZzO#^|O#_|O#a}O#c!OO#l!QO#o!TO#s!UO#u!VO#z!WO#}hO$P!XO%oRO%pRO%tSO%uWO&Z]O&[]O&]]O&^]O&_]O&`]O&a]O&b]O&c^O&d^O&e^O&f^O&g^O&h^O&i^O&j^O~O%]!YO~OV!aO_!aOa!bOh!iO!X!kO!f!mO%j![O%k!]O%l!^O%m!_O%n!_O%o!`O%p!`O%q!aO%r!aO%s!aO~Ok%xXl%xXm%xXn%xXo%xXp%xXs%xXz%xX{%xX!x%xX#g%xX%[%xX%_%xX%z%xXg%xX!T%xX!U%xX%{%xX!W%xX![%xX!Q%xX#[%xXt%xX!m%xX~P%SOfoOhYO!XZO!][O!h`O!r`O!s`O!t`O%oRO%pRO%tSO%uWO&Z]O&[]O&]]O&^]O&_]O&`]O&a]O&b]O&c^O&d^O&e^O&f^O&g^O&h^O&i^O&j^O~Oz%wX{%wX#g%wX%[%wX%_%wX%z%wX~Ok!pOl!qOm!oOn!oOo!rOp!sOs!tO!x%wX~P)pOV!zOg!|Oo0cOv0qO!PrO~P'vOV#OOo0cOv0qO!W#PO~P'vOV#SOa#TOo0cOv0qO![#UO~P'vOQ#XO%`#XO%a#ZO~OQ#^OR#[O%`#^O%a#`O~OV%iX_%iXa%iXh%iXk%iXl%iXm%iXn%iXo%iXp%iXs%iXz%iX!X%iX!f%iX%j%iX%k%iX%l%iX%m%iX%n%iX%o%iX%p%iX%q%iX%r%iX%s%iXg%iX!T%iX!U%iX~O&Z]O&[]O&]]O&^]O&_]O&`]O&a]O&b]O&c^O&d^O&e^O&f^O&g^O&h^O&i^O&j^O{%iX!x%iX#g%iX%[%iX%_%iX%z%iX%{%iX!W%iX![%iX!Q%iX#[%iXt%iX!m%iX~P,eOz#dO{%hX!x%hX#g%hX%[%hX%_%hX%z%hX~Oo0cOv0qO~P'vO#g#gO%[#iO%_#iO~O%uWO~O!T#nO#u!VO#z!WO#}hO~OopO~P'vOV#sOa#tO%uWO{wP~OV#xOo0cOv0qO!Q#yO~P'vO{#{O!x$QO%z#|O#g!yX%[!yX%_!yX~OV#xOo0cOv0qO#g#SX%[#SX%_#SX~P'vOo0cOv0qO#g#WX%[#WX%_#WX~P'vOh$WO%uWO~O!f$YO!r$YO%uWO~OV$eO~P'vO!U$gO#s$hO#u$iO~O{$jO~OV$qO~P'vOS$sO%[$rO%_$rO%c$tO~OV$}Oa$}Og%POo0cOv0qO~P'vOo0cOv0qO{%SO~P'vO&Y%UO~Oa!bOh!iO!X!kO!f!mOVba_bakbalbambanbaobapbasbazba{ba!xba#gba%[ba%_ba%jba%kba%lba%mba%nba%oba%pba%qba%rba%sba%zbagba!Tba!Uba%{ba!Wba![ba!Qba#[batba!mba~On%ZO~Oo%ZO~P'vOo0cO~P'vOk0eOl0fOm0dOn0dOo0mOp0nOs0rOg%wX!T%wX!U%wX%{%wX!W%wX![%wX!Q%wX#[%wX!m%wX~P)pO%{%]Og%vXz%vX!T%vX!U%vX!W%vX{%vX~Og%_Oz%`O!T%dO!U%cO~Og%_O~Oz%gO!T%dO!U%cO!W&SX~O!W%kO~Oz%lO{%nO!T%dO!U%cO![%}X~O![%rO~O![%sO~OQ#XO%`#XO%a%uO~OV%wOo0cOv0qO!PrO~P'vOQ#^OR#[O%`#^O%a%zO~OV!qa_!qaa!qah!qak!qal!qam!qan!qao!qap!qas!qaz!qa{!qa!X!qa!f!qa!x!qa#g!qa%[!qa%_!qa%j!qa%k!qa%l!qa%m!qa%n!qa%o!qa%p!qa%q!qa%r!qa%s!qa%z!qag!qa!T!qa!U!qa%{!qa!W!qa![!qa!Q!qa#[!qat!qa!m!qa~P#yOz%|O{%ha!x%ha#g%ha%[%ha%_%ha%z%ha~P%SOV&OOopOvqO{%ha!x%ha#g%ha%[%ha%_%ha%z%ha~P'vOz%|O{%ha!x%ha#g%ha%[%ha%_%ha%z%ha~OPdOVaOopOvqO!PrO!Q{O!{tO!}uO#PvO#RwO#TxO#XyO#ZzO#^|O#_|O#a}O#c!OO#g$zX%[$zX%_$zX~P'vO#g#gO%[&TO%_&TO~O!f&UOh&sX%[&sXz&sX#[&sX#g&sX%_&sX#Z&sXg&sX~Oh!iO%[&WO~Okealeameaneaoeapeaseazea{ea!xea#gea%[ea%_ea%zeagea!Tea!Uea%{ea!Wea![ea!Qea#[eatea!mea~P%SOsqazqa{qa#gqa%[qa%_qa%zqa~Ok!pOl!qOm!oOn!oOo!rOp!sO!xqa~PEcO%z&YOz%yX{%yX~O%uWOz%yX{%yX~Oz&]O{wX~O{&_O~Oz%lO#g%}X%[%}X%_%}Xg%}X{%}X![%}X!m%}X%z%}X~OV0lOo0cOv0qO!PrO~P'vO%z#|O#gUa%[Ua%_Ua~Oz&hO#g&PX%[&PX%_&PXn&PX~P%SOz&kO!Q&jO#g#Wa%[#Wa%_#Wa~Oz&lO#[&nO#g&rX%[&rX%_&rXg&rX~O!f$YO!r$YO#Z&qO%uWO~O#Z&qO~Oz&sO#g&tX%[&tX%_&tX~Oz&uO#g&pX%[&pX%_&pX{&pX~O!X&wO%z&xO~Oz&|On&wX~P%SOn'PO~OPdOVaOopOvqO!PrO!Q{O!{tO!}uO#PvO#RwO#TxO#XyO#ZzO#^|O#_|O#a}O#c!OO%['UO~P'vOt'YO#p'WO#q'XOP#naV#naf#nah#nao#nas#nav#na!P#na!Q#na!T#na!U#na!X#na!]#na!h#na!r#na!s#na!t#na!{#na!}#na#P#na#R#na#T#na#X#na#Z#na#^#na#_#na#a#na#c#na#l#na#o#na#s#na#u#na#z#na#}#na$P#na%X#na%o#na%p#na%t#na%u#na&Z#na&[#na&]#na&^#na&_#na&`#na&a#na&b#na&c#na&d#na&e#na&f#na&g#na&h#na&i#na&j#na%Z#na%_#na~Oz'ZO#[']O{&xX~Oh'_O!X&wO~Oh!iO{$jO!X&wO~O{'eO~P%SO%['hO%_'hO~OS'iO%['hO%_'hO~OV!aO_!aOa!bOh!iO!X!kO!f!mO%l!^O%m!_O%n!_O%o!`O%p!`O%q!aO%r!aO%s!aOkWilWimWinWioWipWisWizWi{Wi!xWi#gWi%[Wi%_Wi%jWi%zWigWi!TWi!UWi%{Wi!WWi![Wi!QWi#[WitWi!mWi~O%k!]O~P!#uO%kWi~P!#uOV!aO_!aOa!bOh!iO!X!kO!f!mO%o!`O%p!`O%q!aO%r!aO%s!aOkWilWimWinWioWipWisWizWi{Wi!xWi#gWi%[Wi%_Wi%jWi%kWi%lWi%zWigWi!TWi!UWi%{Wi!WWi![Wi!QWi#[WitWi!mWi~O%m!_O%n!_O~P!&pO%mWi%nWi~P!&pOa!bOh!iO!X!kO!f!mOkWilWimWinWioWipWisWizWi{Wi!xWi#gWi%[Wi%_Wi%jWi%kWi%lWi%mWi%nWi%oWi%pWi%zWigWi!TWi!UWi%{Wi!WWi![Wi!QWi#[WitWi!mWi~OV!aO_!aO%q!aO%r!aO%s!aO~P!)nOVWi_Wi%qWi%rWi%sWi~P!)nO!T%dO!U%cOg&VXz&VX~O%z'kO%{'kO~P,eOz'mOg&UX~Og'oO~Oz'pO{'rO!W&XX~Oo0cOv0qOz'pO{'sO!W&XX~P'vO!W'uO~Om!oOn!oOo!rOp!sOkjisjizji{ji!xji#gji%[ji%_ji%zji~Ol!qO~P!.aOlji~P!.aOk0eOl0fOm0dOn0dOo0mOp0nO~Ot'wO~P!/jOV'|Og'}Oo0cOv0qO~P'vOg'}Oz(OO~Og(QO~O!U(SO~Og(TOz(OO!T%dO!U%cO~P%SOk0eOl0fOm0dOn0dOo0mOp0nOgqa!Tqa!Uqa%{qa!Wqa![qa!Qqa#[qatqa!mqa~PEcOV'|Oo0cOv0qO!W&Sa~P'vOz(WO!W&Sa~O!W(XO~Oz(WO!T%dO!U%cO!W&Sa~P%SOV(]Oo0cOv0qO![%}a#g%}a%[%}a%_%}ag%}a{%}a!m%}a%z%}a~P'vOz(^O![%}a#g%}a%[%}a%_%}ag%}a{%}a!m%}a%z%}a~O![(aO~Oz(^O!T%dO!U%cO![%}a~P%SOz(dO!T%dO!U%cO![&Ta~P%SOz(gO{&lX![&lX!m&lX%z&lX~O{(kO![(mO!m(nO%z(jO~OV&OOopOvqO{%hi!x%hi#g%hi%[%hi%_%hi%z%hi~P'vOz(pO{%hi!x%hi#g%hi%[%hi%_%hi%z%hi~O!f&UOh&sa%[&saz&sa#[&sa#g&sa%_&sa#Z&sag&sa~O%[(uO~OV#sOa#tO%uWO~Oz&]O{wa~OopOvqO~P'vOz(^O#g%}a%[%}a%_%}ag%}a{%}a![%}a!m%}a%z%}a~P%SOz(zO#g%hX%[%hX%_%hX%z%hX~O%z#|O#gUi%[Ui%_Ui~O#g&Pa%[&Pa%_&Pan&Pa~P'vOz(}O#g&Pa%[&Pa%_&Pan&Pa~O%uWO#g&ra%[&ra%_&rag&ra~Oz)SO#g&ra%[&ra%_&rag&ra~Og)VO~OV)WOh$WO%uWO~O#Z)XO~O%uWO#g&ta%[&ta%_&ta~Oz)ZO#g&ta%[&ta%_&ta~Oo0cOv0qO#g&pa%[&pa%_&pa{&pa~P'vOz)^O#g&pa%[&pa%_&pa{&pa~OV)`Oa)`O%uWO~O%z)eO~Ot)hO#j)gOP#hiV#hif#hih#hio#his#hiv#hi!P#hi!Q#hi!T#hi!U#hi!X#hi!]#hi!h#hi!r#hi!s#hi!t#hi!{#hi!}#hi#P#hi#R#hi#T#hi#X#hi#Z#hi#^#hi#_#hi#a#hi#c#hi#l#hi#o#hi#s#hi#u#hi#z#hi#}#hi$P#hi%X#hi%o#hi%p#hi%t#hi%u#hi&Z#hi&[#hi&]#hi&^#hi&_#hi&`#hi&a#hi&b#hi&c#hi&d#hi&e#hi&f#hi&g#hi&h#hi&i#hi&j#hi%Z#hi%_#hi~Ot)iOP#kiV#kif#kih#kio#kis#kiv#ki!P#ki!Q#ki!T#ki!U#ki!X#ki!]#ki!h#ki!r#ki!s#ki!t#ki!{#ki!}#ki#P#ki#R#ki#T#ki#X#ki#Z#ki#^#ki#_#ki#a#ki#c#ki#l#ki#o#ki#s#ki#u#ki#z#ki#}#ki$P#ki%X#ki%o#ki%p#ki%t#ki%u#ki&Z#ki&[#ki&]#ki&^#ki&_#ki&`#ki&a#ki&b#ki&c#ki&d#ki&e#ki&f#ki&g#ki&h#ki&i#ki&j#ki%Z#ki%_#ki~OV)kOn&wa~P'vOz)lOn&wa~Oz)lOn&wa~P%SOn)pO~O%Y)tO~Ot)wO#p'WO#q)vOP#niV#nif#nih#nio#nis#niv#ni!P#ni!Q#ni!T#ni!U#ni!X#ni!]#ni!h#ni!r#ni!s#ni!t#ni!{#ni!}#ni#P#ni#R#ni#T#ni#X#ni#Z#ni#^#ni#_#ni#a#ni#c#ni#l#ni#o#ni#s#ni#u#ni#z#ni#}#ni$P#ni%X#ni%o#ni%p#ni%t#ni%u#ni&Z#ni&[#ni&]#ni&^#ni&_#ni&`#ni&a#ni&b#ni&c#ni&d#ni&e#ni&f#ni&g#ni&h#ni&i#ni&j#ni%Z#ni%_#ni~OV)zOo0cOv0qO{$jO~P'vOo0cOv0qO{&xa~P'vOz*OO{&xa~OV*SOa*TOg*WO%q*UO%uWO~O{$jO&{*YO~Oh'_O~Oh!iO{$jO~O%[*_O~O%[*aO%_*aO~OV$}Oa$}Oo0cOv0qOg&Ua~P'vOz*dOg&Ua~Oo0cOv0qO{*gO!W&Xa~P'vOz*hO!W&Xa~Oo0cOv0qOz*hO{*kO!W&Xa~P'vOo0cOv0qOz*hO!W&Xa~P'vOz*hO{*kO!W&Xa~Om0dOn0dOo0mOp0nOgjikjisjizji!Tji!Uji%{ji!Wji{ji![ji#gji%[ji%_ji!Qji#[jitji!mji%zji~Ol0fO~P!NkOlji~P!NkOV'|Og*pOo0cOv0qO~P'vOn*rO~Og*pOz*tO~Og*uO~OV'|Oo0cOv0qO!W&Si~P'vOz*vO!W&Si~O!W*wO~OV(]Oo0cOv0qO![%}i#g%}i%[%}i%_%}ig%}i{%}i!m%}i%z%}i~P'vOz*zO!T%dO!U%cO![&Ti~Oz*}O![%}i#g%}i%[%}i%_%}ig%}i{%}i!m%}i%z%}i~O![+OO~Oa+QOo0cOv0qO![&Ti~P'vOz*zO![&Ti~O![+SO~OV+UOo0cOv0qO{&la![&la!m&la%z&la~P'vOz+VO{&la![&la!m&la%z&la~O!]+YO&n+[O![!nX~O![+^O~O{(kO![+_O~O{(kO![+_O!m+`O~OV&OOopOvqO{%hq!x%hq#g%hq%[%hq%_%hq%z%hq~P'vOz$ri{$ri!x$ri#g$ri%[$ri%_$ri%z$ri~P%SOV&OOopOvqO~P'vOV&OOo0cOv0qO#g%ha%[%ha%_%ha%z%ha~P'vOz+aO#g%ha%[%ha%_%ha%z%ha~Oz$ia#g$ia%[$ia%_$ian$ia~P%SO#g&Pi%[&Pi%_&Pin&Pi~P'vOz+dO#g#Wq%[#Wq%_#Wq~O#[+eOz$va#g$va%[$va%_$vag$va~O%uWO#g&ri%[&ri%_&rig&ri~Oz+gO#g&ri%[&ri%_&rig&ri~OV+iOh$WO%uWO~O%uWO#g&ti%[&ti%_&ti~Oo0cOv0qO#g&pi%[&pi%_&pi{&pi~P'vO{#{Oz#eX!W#eX~Oz+mO!W&uX~O!W+oO~Ot+rO#j)gOP#hqV#hqf#hqh#hqo#hqs#hqv#hq!P#hq!Q#hq!T#hq!U#hq!X#hq!]#hq!h#hq!r#hq!s#hq!t#hq!{#hq!}#hq#P#hq#R#hq#T#hq#X#hq#Z#hq#^#hq#_#hq#a#hq#c#hq#l#hq#o#hq#s#hq#u#hq#z#hq#}#hq$P#hq%X#hq%o#hq%p#hq%t#hq%u#hq&Z#hq&[#hq&]#hq&^#hq&_#hq&`#hq&a#hq&b#hq&c#hq&d#hq&e#hq&f#hq&g#hq&h#hq&i#hq&j#hq%Z#hq%_#hq~On$|az$|a~P%SOV)kOn&wi~P'vOz+yOn&wi~Oz,TO{$jO#[,TO~O#q,VOP#nqV#nqf#nqh#nqo#nqs#nqv#nq!P#nq!Q#nq!T#nq!U#nq!X#nq!]#nq!h#nq!r#nq!s#nq!t#nq!{#nq!}#nq#P#nq#R#nq#T#nq#X#nq#Z#nq#^#nq#_#nq#a#nq#c#nq#l#nq#o#nq#s#nq#u#nq#z#nq#}#nq$P#nq%X#nq%o#nq%p#nq%t#nq%u#nq&Z#nq&[#nq&]#nq&^#nq&_#nq&`#nq&a#nq&b#nq&c#nq&d#nq&e#nq&f#nq&g#nq&h#nq&i#nq&j#nq%Z#nq%_#nq~O#[,WOz%Oa{%Oa~Oo0cOv0qO{&xi~P'vOz,YO{&xi~O{#{O%z,[Og&zXz&zX~O%uWOg&zXz&zX~Oz,`Og&yX~Og,bO~O%Y,eO~O!T%dO!U%cOg&Viz&Vi~OV$}Oa$}Oo0cOv0qOg&Ui~P'vO{,hOz$la!W$la~Oo0cOv0qO{,iOz$la!W$la~P'vOo0cOv0qO{*gO!W&Xi~P'vOz,lO!W&Xi~Oo0cOv0qOz,lO!W&Xi~P'vOz,lO{,oO!W&Xi~Og$hiz$hi!W$hi~P%SOV'|Oo0cOv0qO~P'vOn,qO~OV'|Og,rOo0cOv0qO~P'vOV'|Oo0cOv0qO!W&Sq~P'vOz$gi![$gi#g$gi%[$gi%_$gig$gi{$gi!m$gi%z$gi~P%SOV(]Oo0cOv0qO~P'vOa+QOo0cOv0qO![&Tq~P'vOz,sO![&Tq~O![,tO~OV(]Oo0cOv0qO![%}q#g%}q%[%}q%_%}qg%}q{%}q!m%}q%z%}q~P'vO{,uO~OV+UOo0cOv0qO{&li![&li!m&li%z&li~P'vOz,zO{&li![&li!m&li%z&li~O!]+YO&n+[O![!na~O{(kO![,}O~OV&OOo0cOv0qO#g%hi%[%hi%_%hi%z%hi~P'vOz-OO#g%hi%[%hi%_%hi%z%hi~O%uWO#g&rq%[&rq%_&rqg&rq~Oz-RO#g&rq%[&rq%_&rqg&rq~OV)`Oa)`O%uWO!W&ua~Oz-TO!W&ua~On$|iz$|i~P%SOV)kO~P'vOV)kOn&wq~P'vOt-XOP#myV#myf#myh#myo#mys#myv#my!P#my!Q#my!T#my!U#my!X#my!]#my!h#my!r#my!s#my!t#my!{#my!}#my#P#my#R#my#T#my#X#my#Z#my#^#my#_#my#a#my#c#my#l#my#o#my#s#my#u#my#z#my#}#my$P#my%X#my%o#my%p#my%t#my%u#my&Z#my&[#my&]#my&^#my&_#my&`#my&a#my&b#my&c#my&d#my&e#my&f#my&g#my&h#my&i#my&j#my%Z#my%_#my~O%Z-]O%_-]O~P`O#q-^OP#nyV#nyf#nyh#nyo#nys#nyv#ny!P#ny!Q#ny!T#ny!U#ny!X#ny!]#ny!h#ny!r#ny!s#ny!t#ny!{#ny!}#ny#P#ny#R#ny#T#ny#X#ny#Z#ny#^#ny#_#ny#a#ny#c#ny#l#ny#o#ny#s#ny#u#ny#z#ny#}#ny$P#ny%X#ny%o#ny%p#ny%t#ny%u#ny&Z#ny&[#ny&]#ny&^#ny&_#ny&`#ny&a#ny&b#ny&c#ny&d#ny&e#ny&f#ny&g#ny&h#ny&i#ny&j#ny%Z#ny%_#ny~Oz-aO{$jO#[-aO~Oo0cOv0qO{&xq~P'vOz-dO{&xq~O%z,[Og&zaz&za~O{#{Og&zaz&za~OV*SOa*TO%q*UO%uWOg&ya~Oz-hOg&ya~O$S-lO~OV$}Oa$}Oo0cOv0qO~P'vOo0cOv0qO{-mOz$li!W$li~P'vOo0cOv0qOz$li!W$li~P'vO{-mOz$li!W$li~Oo0cOv0qO{*gO~P'vOo0cOv0qO{*gO!W&Xq~P'vOz-pO!W&Xq~Oo0cOv0qOz-pO!W&Xq~P'vOs-sO!T%dO!U%cOg&Oq!W&Oq![&Oqz&Oq~P!/jOa+QOo0cOv0qO![&Ty~P'vOz$ji![$ji~P%SOa+QOo0cOv0qO~P'vOV+UOo0cOv0qO~P'vOV+UOo0cOv0qO{&lq![&lq!m&lq%z&lq~P'vO{(kO![-xO!m-yO%z-wO~OV&OOo0cOv0qO#g%hq%[%hq%_%hq%z%hq~P'vO%uWO#g&ry%[&ry%_&ryg&ry~OV)`Oa)`O%uWO!W&ui~Ot-}OP#m!RV#m!Rf#m!Rh#m!Ro#m!Rs#m!Rv#m!R!P#m!R!Q#m!R!T#m!R!U#m!R!X#m!R!]#m!R!h#m!R!r#m!R!s#m!R!t#m!R!{#m!R!}#m!R#P#m!R#R#m!R#T#m!R#X#m!R#Z#m!R#^#m!R#_#m!R#a#m!R#c#m!R#l#m!R#o#m!R#s#m!R#u#m!R#z#m!R#}#m!R$P#m!R%X#m!R%o#m!R%p#m!R%t#m!R%u#m!R&Z#m!R&[#m!R&]#m!R&^#m!R&_#m!R&`#m!R&a#m!R&b#m!R&c#m!R&d#m!R&e#m!R&f#m!R&g#m!R&h#m!R&i#m!R&j#m!R%Z#m!R%_#m!R~Oo0cOv0qO{&xy~P'vOV*SOa*TO%q*UO%uWOg&yi~O$S-lO%Z.VO%_.VO~OV.aOh._O!X.^O!].`O!h.YO!s.[O!t.[O%p.XO%uWO&Z]O&[]O&]]O&^]O&_]O&`]O&a]O&b]O~Oo0cOv0qOz$lq!W$lq~P'vO{.fOz$lq!W$lq~Oo0cOv0qO{*gO!W&Xy~P'vOz.gO!W&Xy~Oo0cOv.kO~P'vOs-sO!T%dO!U%cOg&Oy!W&Oy![&Oyz&Oy~P!/jO{(kO![.nO~O{(kO![.nO!m.oO~OV*SOa*TO%q*UO%uWO~Oh.tO!f.rOz$TX#[$TX%j$TXg$TX~Os$TX{$TX!W$TX![$TX~P$-bO%o.vO%p.vOs$UXz$UX{$UX#[$UX%j$UX!W$UXg$UX![$UX~O!h.xO~Oz.|O#[/OO%j.yOs&|X{&|X!W&|Xg&|X~Oa/RO~P$)zOh.tOs&}Xz&}X{&}X#[&}X%j&}X!W&}Xg&}X![&}X~Os/VO{$jO~Oo0cOv0qOz$ly!W$ly~P'vOo0cOv0qO{*gO!W&X!R~P'vOz/ZO!W&X!R~Og&RXs&RX!T&RX!U&RX!W&RX![&RXz&RX~P!/jOs-sO!T%dO!U%cOg&Qa!W&Qa![&Qaz&Qa~O{(kO![/^O~O!f.rOh$[as$[az$[a{$[a#[$[a%j$[a!W$[ag$[a![$[a~O!h/eO~O%o.vO%p.vOs$Uaz$Ua{$Ua#[$Ua%j$Ua!W$Uag$Ua![$Ua~O%j.yOs$Yaz$Ya{$Ya#[$Ya!W$Yag$Ya![$Ya~Os&|a{&|a!W&|ag&|a~P$)nOz/jOs&|a{&|a!W&|ag&|a~O!W/mO~Og/mO~O{/oO~O![/pO~Oo0cOv0qO{*gO!W&X!Z~P'vO{/sO~O%z/tO~P$-bOz/uO#[/OO%j.yOg'PX~Oz/uOg'PX~Og/wO~O!h/xO~O#[/OOs%Saz%Sa{%Sa%j%Sa!W%Sag%Sa![%Sa~O#[/OO%j.yOs%Waz%Wa{%Wa!W%Wag%Wa~Os&|i{&|i!W&|ig&|i~P$)nOz/zO#[/OO%j.yO!['Oa~Og'Pa~P$)nOz0SOg'Pa~Oa0UO!['Oi~P$)zOz0WO!['Oi~Oz0WO#[/OO%j.yO!['Oi~O#[/OO%j.yOg$biz$bi~O%z0ZO~P$-bO#[/OO%j.yOg%Vaz%Va~Og'Pi~P$)nO{0^O~Oa0UO!['Oq~P$)zOz0`O!['Oq~O#[/OO%j.yOz%Ui![%Ui~Oa0UO~P$)zOa0UO!['Oy~P$)zO#[/OO%j.yOg$ciz$ci~O#[/OO%j.yOz%Uq![%Uq~Oz+aO#g%ha%[%ha%_%ha%z%ha~P%SOV&OOo0cOv0qO~P'vOn0hO~Oo0hO~P'vO{0iO~Ot0jO~P!/jO&]&Z&j&h&i&g&f&d&e&c&b&`&a&_&^&[%u~",
|
|
@@ -49501,7 +50198,7 @@ var parser2 = LRParser.deserialize({
|
|
|
49501
50198
|
});
|
|
49502
50199
|
|
|
49503
50200
|
// src/adapters.ts
|
|
49504
|
-
var phpEngine = new
|
|
50201
|
+
var phpEngine = new import_php_parser4.Engine({ parser: { extractDoc: false, php7: true }, ast: { withPositions: true, withSource: false } });
|
|
49505
50202
|
var PHP_SOURCES = [
|
|
49506
50203
|
["_GET", "http_parameter"],
|
|
49507
50204
|
["_POST", "http_body"],
|
|
@@ -49794,7 +50491,7 @@ var pythonAdapter = {
|
|
|
49794
50491
|
language: "python",
|
|
49795
50492
|
extensions: [".py", ".pyw"],
|
|
49796
50493
|
parse(code, _file) {
|
|
49797
|
-
const tree =
|
|
50494
|
+
const tree = parser4.parse(code);
|
|
49798
50495
|
const sources = [];
|
|
49799
50496
|
const sinks = [];
|
|
49800
50497
|
const sanitizers = [];
|
|
@@ -50777,7 +51474,7 @@ function reportJson(findings, opts = {}) {
|
|
|
50777
51474
|
}
|
|
50778
51475
|
|
|
50779
51476
|
// src/benchmark.ts
|
|
50780
|
-
import { readFileSync as
|
|
51477
|
+
import { readFileSync as readFileSync13, readdirSync as readdirSync4, writeFileSync as writeFileSync2, rmSync } from "node:fs";
|
|
50781
51478
|
import { join as join9 } from "node:path";
|
|
50782
51479
|
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
50783
51480
|
import { tmpdir } from "node:os";
|
|
@@ -50786,7 +51483,7 @@ var CORPUS = join9(ROOT4, "bench", "corpus");
|
|
|
50786
51483
|
function parseCorpusFile(path) {
|
|
50787
51484
|
let text;
|
|
50788
51485
|
try {
|
|
50789
|
-
text =
|
|
51486
|
+
text = readFileSync13(path, "utf8");
|
|
50790
51487
|
} catch {
|
|
50791
51488
|
return null;
|
|
50792
51489
|
}
|
|
@@ -51634,6 +52331,38 @@ function createServer() {
|
|
|
51634
52331
|
});
|
|
51635
52332
|
return { content: [{ type: "text", text: JSON.stringify({ ...r, next_steps: guidance }) }] };
|
|
51636
52333
|
});
|
|
52334
|
+
server.registerTool("eagle_eye2", {
|
|
52335
|
+
title: "Whole-program interprocedural taint (EAGLE-EYE 2.0)",
|
|
52336
|
+
description: "EAGLE-EYE 2.0: whole-program data-flow on a PHP AST — call-graph-aware interprocedural taint with return propagation, by-reference alias tracking, ternary/conditional merge, context-sensitive sanitizers, and authorization-gate detection. Prefer this over taint_scan for accurate cross-function reachability.",
|
|
52337
|
+
inputSchema: { path: string2().describe("Source file path (PHP)") }
|
|
52338
|
+
}, async ({ path }) => {
|
|
52339
|
+
const r = analyzeDataFlow2(path);
|
|
52340
|
+
const taintedSinks = [...new Set(r.findings.map((f) => f.sink))];
|
|
52341
|
+
const authGated = r.findings.filter((f) => f.auth_gated).length;
|
|
52342
|
+
const guidance = nextSteps({
|
|
52343
|
+
tier: "eagle-eye",
|
|
52344
|
+
hasFindings: r.findings.length > 0,
|
|
52345
|
+
sanitizedCount: r.suppressed,
|
|
52346
|
+
taintedSinks
|
|
52347
|
+
});
|
|
52348
|
+
return {
|
|
52349
|
+
content: [{
|
|
52350
|
+
type: "text",
|
|
52351
|
+
text: JSON.stringify({
|
|
52352
|
+
file: r.file,
|
|
52353
|
+
findings: r.findings.length,
|
|
52354
|
+
suppressed: r.suppressed,
|
|
52355
|
+
auth_gated: authGated,
|
|
52356
|
+
interprocedural: r.findings.filter((f) => f.interprocedural).length,
|
|
52357
|
+
functions: r.summary.functions,
|
|
52358
|
+
methods: r.summary.methods,
|
|
52359
|
+
call_edges: r.summary.edges,
|
|
52360
|
+
results: r.findings,
|
|
52361
|
+
next_steps: guidance
|
|
52362
|
+
})
|
|
52363
|
+
}]
|
|
52364
|
+
};
|
|
52365
|
+
});
|
|
51637
52366
|
server.registerTool("taint_tree", {
|
|
51638
52367
|
title: "Whole-tree taint scan",
|
|
51639
52368
|
description: "EAGLE-EYE: run inter-procedural taint analysis across an entire source tree.",
|
|
@@ -51787,7 +52516,7 @@ async function serve() {
|
|
|
51787
52516
|
}
|
|
51788
52517
|
|
|
51789
52518
|
// src/cli.ts
|
|
51790
|
-
import { readFileSync as
|
|
52519
|
+
import { readFileSync as readFileSync15, existsSync as existsSync6, writeFileSync as writeFileSync4, mkdirSync as mkdirSync4 } from "node:fs";
|
|
51791
52520
|
import { join as join11, dirname as dirname2 } from "node:path";
|
|
51792
52521
|
import { homedir as homedir5 } from "node:os";
|
|
51793
52522
|
import { fileURLToPath as fileURLToPath8 } from "node:url";
|
|
@@ -51869,7 +52598,7 @@ function resolveCommand() {
|
|
|
51869
52598
|
}
|
|
51870
52599
|
function readJson(p) {
|
|
51871
52600
|
try {
|
|
51872
|
-
return JSON.parse(
|
|
52601
|
+
return JSON.parse(readFileSync15(p, "utf8"));
|
|
51873
52602
|
} catch {
|
|
51874
52603
|
return null;
|
|
51875
52604
|
}
|
|
@@ -51912,7 +52641,7 @@ function copyOpenCodeAgents() {
|
|
|
51912
52641
|
const src = join11(srcDir, f);
|
|
51913
52642
|
const dst = join11(dstDir, f);
|
|
51914
52643
|
if (existsSync6(src)) {
|
|
51915
|
-
writeFileSync4(dst,
|
|
52644
|
+
writeFileSync4(dst, readFileSync15(src, "utf8"));
|
|
51916
52645
|
}
|
|
51917
52646
|
}
|
|
51918
52647
|
}
|
|
@@ -51921,7 +52650,7 @@ function codexWrite(p) {
|
|
|
51921
52650
|
const dir = dirname2(p);
|
|
51922
52651
|
if (!existsSync6(dir))
|
|
51923
52652
|
mkdirSync4(dir, { recursive: true });
|
|
51924
|
-
let existing = existsSync6(p) ?
|
|
52653
|
+
let existing = existsSync6(p) ? readFileSync15(p, "utf8") : "";
|
|
51925
52654
|
if (!existing.trimEnd().endsWith(`
|
|
51926
52655
|
`))
|
|
51927
52656
|
existing += `
|
|
@@ -51940,7 +52669,7 @@ function hermesWrite(p) {
|
|
|
51940
52669
|
const dir = dirname2(p);
|
|
51941
52670
|
if (!existsSync6(dir))
|
|
51942
52671
|
mkdirSync4(dir, { recursive: true });
|
|
51943
|
-
let existing = existsSync6(p) ?
|
|
52672
|
+
let existing = existsSync6(p) ? readFileSync15(p, "utf8") : "";
|
|
51944
52673
|
existing = existing.replace(/^ blitzstrike:\n(?: .*\n?)*/m, "");
|
|
51945
52674
|
if (!existing.trimEnd().endsWith(`
|
|
51946
52675
|
`))
|
|
@@ -52078,7 +52807,7 @@ Registered with ${ok}/${installed.length} agent(s).`);
|
|
|
52078
52807
|
}
|
|
52079
52808
|
|
|
52080
52809
|
// src/index.ts
|
|
52081
|
-
import { readFileSync as
|
|
52810
|
+
import { readFileSync as readFileSync16, existsSync as existsSync7 } from "node:fs";
|
|
52082
52811
|
import { join as join12 } from "node:path";
|
|
52083
52812
|
import { fileURLToPath as fileURLToPath9 } from "node:url";
|
|
52084
52813
|
var ROOT7 = join12(fileURLToPath9(new URL(".", import.meta.url)), "..");
|
|
@@ -52086,7 +52815,7 @@ function readVersion() {
|
|
|
52086
52815
|
try {
|
|
52087
52816
|
const p = join12(ROOT7, "package.json");
|
|
52088
52817
|
if (existsSync7(p))
|
|
52089
|
-
return JSON.parse(
|
|
52818
|
+
return JSON.parse(readFileSync16(p, "utf8")).version ?? "1.0.0";
|
|
52090
52819
|
} catch {}
|
|
52091
52820
|
return "1.0.0";
|
|
52092
52821
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "blitzstrike",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.35",
|
|
4
4
|
"description": "Blitz Strike — a universal MCP security-audit toolbelt. BLITZ sweeps the attack surface, EAGLE-EYE traces source-to-sink, STRIKE verifies live. 57 attack chains, 130-tool catalog, intelligence data layer. One server, every agent.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|