cognium-dev 4.9.27 → 4.9.28
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/dist/cli.js +324 -12
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -5506,6 +5506,33 @@ function extractCSharpCalls(tree, cache) {
|
|
|
5506
5506
|
});
|
|
5507
5507
|
continue;
|
|
5508
5508
|
}
|
|
5509
|
+
if (left?.type === "identifier" && asn.parent?.type === "initializer_expression") {
|
|
5510
|
+
const creation = asn.parent.parent;
|
|
5511
|
+
if (creation?.type !== "object_creation_expression")
|
|
5512
|
+
continue;
|
|
5513
|
+
const ctorType = creation.childForFieldName("type");
|
|
5514
|
+
const right2 = asn.childForFieldName("right");
|
|
5515
|
+
if (!ctorType || !right2)
|
|
5516
|
+
continue;
|
|
5517
|
+
const typeName = csharpBareName(ctorType);
|
|
5518
|
+
const rhsText2 = getNodeText(right2);
|
|
5519
|
+
calls.push({
|
|
5520
|
+
method_name: getNodeText(left),
|
|
5521
|
+
receiver: typeName,
|
|
5522
|
+
receiver_type: typeName,
|
|
5523
|
+
receiver_type_fqn: null,
|
|
5524
|
+
arguments: [{
|
|
5525
|
+
position: 0,
|
|
5526
|
+
expression: rhsText2,
|
|
5527
|
+
variable: right2.type === "identifier" ? rhsText2 : null,
|
|
5528
|
+
literal: CSHARP_LITERAL_NODE_TYPES.has(right2.type) ? rhsText2 : null,
|
|
5529
|
+
value: null
|
|
5530
|
+
}],
|
|
5531
|
+
location: { line: asn.startPosition.row + 1, column: asn.startPosition.column },
|
|
5532
|
+
in_method: findEnclosingMethod(asn)
|
|
5533
|
+
});
|
|
5534
|
+
continue;
|
|
5535
|
+
}
|
|
5509
5536
|
if (left?.type !== "member_access_expression")
|
|
5510
5537
|
continue;
|
|
5511
5538
|
const nameNode = left.childForFieldName("name");
|
|
@@ -5518,6 +5545,15 @@ function extractCSharpCalls(tree, cache) {
|
|
|
5518
5545
|
const recvType = recv ? typeMap.get(recv) : undefined;
|
|
5519
5546
|
if (recvType !== "DirectorySearcher")
|
|
5520
5547
|
continue;
|
|
5548
|
+
} else if (propName === "StatusDescription") {
|
|
5549
|
+
const recv = exprNode ? getNodeText(exprNode) : "";
|
|
5550
|
+
if (!/(^|\.)(Response|HttpResponse|Context\.Response)$/.test(recv))
|
|
5551
|
+
continue;
|
|
5552
|
+
} else if (propName === "BaseAddress") {
|
|
5553
|
+
const recv = exprNode ? getNodeText(exprNode) : null;
|
|
5554
|
+
const recvType = recv ? typeMap.get(recv) : undefined;
|
|
5555
|
+
if (recvType !== "HttpClient")
|
|
5556
|
+
continue;
|
|
5521
5557
|
} else if (propName !== "CommandText") {
|
|
5522
5558
|
continue;
|
|
5523
5559
|
}
|
|
@@ -5541,8 +5577,36 @@ function extractCSharpCalls(tree, cache) {
|
|
|
5541
5577
|
in_method: findEnclosingMethod(asn)
|
|
5542
5578
|
});
|
|
5543
5579
|
}
|
|
5580
|
+
const casts = getNodesFromCache(tree.rootNode, "cast_expression", cache);
|
|
5581
|
+
for (const cast of casts) {
|
|
5582
|
+
const typeNode = cast.childForFieldName("type");
|
|
5583
|
+
const valueNode = cast.childForFieldName("value");
|
|
5584
|
+
if (!typeNode || !valueNode)
|
|
5585
|
+
continue;
|
|
5586
|
+
const typeName = csharpBareName(typeNode);
|
|
5587
|
+
if (!CSHARP_RAW_MARKUP_CAST_TYPES.has(typeName))
|
|
5588
|
+
continue;
|
|
5589
|
+
const valueText = getNodeText(valueNode);
|
|
5590
|
+
calls.push({
|
|
5591
|
+
method_name: typeName,
|
|
5592
|
+
receiver: null,
|
|
5593
|
+
receiver_type: null,
|
|
5594
|
+
receiver_type_fqn: null,
|
|
5595
|
+
arguments: [{
|
|
5596
|
+
position: 0,
|
|
5597
|
+
expression: valueText,
|
|
5598
|
+
variable: valueNode.type === "identifier" ? valueText : null,
|
|
5599
|
+
literal: CSHARP_LITERAL_NODE_TYPES.has(valueNode.type) ? valueText : null,
|
|
5600
|
+
value: null
|
|
5601
|
+
}],
|
|
5602
|
+
location: { line: cast.startPosition.row + 1, column: cast.startPosition.column },
|
|
5603
|
+
in_method: findEnclosingMethod(cast),
|
|
5604
|
+
is_constructor: true
|
|
5605
|
+
});
|
|
5606
|
+
}
|
|
5544
5607
|
return calls;
|
|
5545
5608
|
}
|
|
5609
|
+
var CSHARP_RAW_MARKUP_CAST_TYPES = new Set(["MarkupString"]);
|
|
5546
5610
|
function extractCSharpArguments(argsNode) {
|
|
5547
5611
|
const args2 = [];
|
|
5548
5612
|
let position = 0;
|
|
@@ -5563,12 +5627,22 @@ function extractCSharpArguments(argsNode) {
|
|
|
5563
5627
|
position: position++,
|
|
5564
5628
|
expression: text,
|
|
5565
5629
|
variable: expr?.type === "identifier" ? text : null,
|
|
5566
|
-
literal: expr
|
|
5630
|
+
literal: expr && CSHARP_LITERAL_NODE_TYPES.has(expr.type) ? text : null,
|
|
5567
5631
|
value: null
|
|
5568
5632
|
});
|
|
5569
5633
|
}
|
|
5570
5634
|
return args2;
|
|
5571
5635
|
}
|
|
5636
|
+
var CSHARP_LITERAL_NODE_TYPES = new Set([
|
|
5637
|
+
"string_literal",
|
|
5638
|
+
"verbatim_string_literal",
|
|
5639
|
+
"raw_string_literal",
|
|
5640
|
+
"character_literal",
|
|
5641
|
+
"integer_literal",
|
|
5642
|
+
"real_literal",
|
|
5643
|
+
"boolean_literal",
|
|
5644
|
+
"null_literal"
|
|
5645
|
+
]);
|
|
5572
5646
|
function extractJavaScriptCalls(tree, cache) {
|
|
5573
5647
|
const calls = [];
|
|
5574
5648
|
const context = buildJSResolutionContext(tree, cache);
|
|
@@ -12482,8 +12556,6 @@ var DEFAULT_SINKS = [
|
|
|
12482
12556
|
{ method: "deserialize", class: "bincode", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0] },
|
|
12483
12557
|
{ method: "from_str", class: "toml", type: "deserialization", cwe: "CWE-502", severity: "high", arg_positions: [0] },
|
|
12484
12558
|
{ method: "from_str", class: "ron", type: "deserialization", cwe: "CWE-502", severity: "high", arg_positions: [0] },
|
|
12485
|
-
{ method: "from_str", type: "deserialization", cwe: "CWE-502", severity: "medium", arg_positions: [0] },
|
|
12486
|
-
{ method: "from_slice", type: "deserialization", cwe: "CWE-502", severity: "medium", arg_positions: [0] },
|
|
12487
12559
|
{ method: "body", class: "HttpResponseBuilder", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
|
|
12488
12560
|
{ method: "body", class: "HttpResponse", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
|
|
12489
12561
|
{ method: "Html", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
|
|
@@ -12707,10 +12779,12 @@ var DEFAULT_SINKS = [
|
|
|
12707
12779
|
{ method: "WriteAsync", class: "Response", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12708
12780
|
{ method: "HtmlString", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12709
12781
|
{ method: "MarkupString", class: "constructor", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12782
|
+
{ method: "StatusDescription", class: "Response", type: "xss", cwe: "CWE-81", severity: "medium", arg_positions: [0], languages: ["csharp"] },
|
|
12710
12783
|
{ method: "Content", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12711
12784
|
{ method: "Format", class: "String", type: "format_string", cwe: "CWE-134", severity: "medium", arg_positions: [0], languages: ["csharp"] },
|
|
12712
12785
|
{ method: "DirectorySearcher", type: "ldap_injection", cwe: "CWE-90", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12713
12786
|
{ method: "DirectoryEntry", type: "ldap_injection", cwe: "CWE-90", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12787
|
+
{ method: "BaseAddress", class: "HttpClient", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12714
12788
|
{ method: "Redirect", type: "open_redirect", cwe: "CWE-601", severity: "medium", arg_positions: [0], languages: ["csharp"] },
|
|
12715
12789
|
{ method: "RedirectPermanent", type: "open_redirect", cwe: "CWE-601", severity: "medium", arg_positions: [0], languages: ["csharp"] },
|
|
12716
12790
|
{ method: "AddHeader", type: "crlf", cwe: "CWE-113", severity: "medium", arg_positions: [1], languages: ["csharp"] },
|
|
@@ -14920,8 +14994,9 @@ function matchesSinkPattern(call, pattern, typeHierarchy, language) {
|
|
|
14920
14994
|
return false;
|
|
14921
14995
|
} else if (!call.receiver && !call.receiver_type) {
|
|
14922
14996
|
const target = call.resolution?.target;
|
|
14997
|
+
const normalisedTarget = language === "rust" ? target?.replace(/::/g, ".") : target;
|
|
14923
14998
|
const expectedTail = `${pattern.class}.${pattern.method}`;
|
|
14924
|
-
if (
|
|
14999
|
+
if (normalisedTarget && (normalisedTarget === expectedTail || normalisedTarget.endsWith("." + expectedTail))) {} else {
|
|
14925
15000
|
return false;
|
|
14926
15001
|
}
|
|
14927
15002
|
}
|
|
@@ -26079,7 +26154,7 @@ class LanguageSourcesPass {
|
|
|
26079
26154
|
}
|
|
26080
26155
|
}
|
|
26081
26156
|
if (language === "csharp") {
|
|
26082
|
-
additionalSanitizers.push(...findCSharpFullPathStartsWithGuardSanitizers(code));
|
|
26157
|
+
additionalSanitizers.push(...findCSharpFullPathStartsWithGuardSanitizers(code), ...findCSharpEarlyReturnGuardSanitizers(code, language));
|
|
26083
26158
|
}
|
|
26084
26159
|
if (language === "java") {
|
|
26085
26160
|
additionalSanitizers.push(...findJavaSafeJsonParseSanitizers(code));
|
|
@@ -29574,6 +29649,76 @@ function guardRejects(lines, i2, terminatorRe, window2) {
|
|
|
29574
29649
|
}
|
|
29575
29650
|
return false;
|
|
29576
29651
|
}
|
|
29652
|
+
function findCSharpEarlyReturnGuardSanitizers(code, language) {
|
|
29653
|
+
if (language !== "csharp")
|
|
29654
|
+
return [];
|
|
29655
|
+
const sanitizers = [];
|
|
29656
|
+
const lines = code.split(`
|
|
29657
|
+
`);
|
|
29658
|
+
const terminatorRe = /\b(throw|return)\b/;
|
|
29659
|
+
const allowlistRes = [
|
|
29660
|
+
/\bif\s*\(\s*Array\s*\.\s*IndexOf\s*\([^,]+,\s*([A-Za-z_][\w.]*)\s*\)\s*<\s*0\s*\)/,
|
|
29661
|
+
/\bif\s*\(\s*!\s*[A-Za-z_][\w.]*\s*\.\s*Contains\s*\(\s*([A-Za-z_][\w.]*)\s*\)\s*\)/
|
|
29662
|
+
];
|
|
29663
|
+
const charClassRe = /\bif\s*\(\s*!\s*([A-Za-z_][\w.]*)\s*\.\s*All\s*\(\s*char\s*\.\s*Is[A-Za-z]+\s*\)\s*\)/;
|
|
29664
|
+
for (let i2 = 0;i2 < lines.length; i2++) {
|
|
29665
|
+
let guardedExpr = null;
|
|
29666
|
+
for (const re of allowlistRes) {
|
|
29667
|
+
const m = re.exec(lines[i2]);
|
|
29668
|
+
if (m) {
|
|
29669
|
+
guardedExpr = m[1];
|
|
29670
|
+
break;
|
|
29671
|
+
}
|
|
29672
|
+
}
|
|
29673
|
+
if (!guardedExpr) {
|
|
29674
|
+
const m = charClassRe.exec(lines[i2]);
|
|
29675
|
+
if (m)
|
|
29676
|
+
guardedExpr = m[1];
|
|
29677
|
+
}
|
|
29678
|
+
if (!guardedExpr)
|
|
29679
|
+
continue;
|
|
29680
|
+
if (!guardRejects(lines, i2, terminatorRe, 6))
|
|
29681
|
+
continue;
|
|
29682
|
+
const root = guardedExpr.split(".")[0];
|
|
29683
|
+
const guarded = new Set([guardedExpr, root]);
|
|
29684
|
+
const assignRe = /^\s*(?:(?:var|string)\s+)?([A-Za-z_]\w*)\s*=(?!=)\s*(.*)$/;
|
|
29685
|
+
for (let b = i2 - 1;b >= 0; b--) {
|
|
29686
|
+
const a = assignRe.exec(lines[b]);
|
|
29687
|
+
if (!a || !guarded.has(a[1]))
|
|
29688
|
+
continue;
|
|
29689
|
+
for (const id of a[2].match(/[A-Za-z_]\w*/g) ?? [])
|
|
29690
|
+
guarded.add(id);
|
|
29691
|
+
}
|
|
29692
|
+
const mentions = (t) => {
|
|
29693
|
+
for (const n of guarded)
|
|
29694
|
+
if (new RegExp(`\\b${n.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\b`).test(t))
|
|
29695
|
+
return true;
|
|
29696
|
+
return false;
|
|
29697
|
+
};
|
|
29698
|
+
for (let l = i2 + 1;l < lines.length; l++) {
|
|
29699
|
+
const a = assignRe.exec(lines[l]);
|
|
29700
|
+
if (a && mentions(a[2]))
|
|
29701
|
+
guarded.add(a[1]);
|
|
29702
|
+
if (mentions(lines[l])) {
|
|
29703
|
+
sanitizers.push({
|
|
29704
|
+
type: "csharp_early_return_guard",
|
|
29705
|
+
method: "guard",
|
|
29706
|
+
line: l + 1,
|
|
29707
|
+
sanitizes: [
|
|
29708
|
+
"ssrf",
|
|
29709
|
+
"xpath_injection",
|
|
29710
|
+
"ldap_injection",
|
|
29711
|
+
"path_traversal",
|
|
29712
|
+
"command_injection",
|
|
29713
|
+
"sql_injection",
|
|
29714
|
+
"external_taint_escape"
|
|
29715
|
+
]
|
|
29716
|
+
});
|
|
29717
|
+
}
|
|
29718
|
+
}
|
|
29719
|
+
}
|
|
29720
|
+
return sanitizers;
|
|
29721
|
+
}
|
|
29577
29722
|
function findCSharpFullPathStartsWithGuardSanitizers(code) {
|
|
29578
29723
|
const sanitizers = [];
|
|
29579
29724
|
const lines = code.split(`
|
|
@@ -36647,6 +36792,65 @@ class LibraryProfileXssGatePass {
|
|
|
36647
36792
|
}
|
|
36648
36793
|
|
|
36649
36794
|
// ../circle-ir/dist/analysis/passes/taint-propagation-pass.js
|
|
36795
|
+
var CONTAINER_READ_SOURCES = new Set(["plugin_param", "config_param"]);
|
|
36796
|
+
function makeConstPropVeto(constProp, graph, sources, code) {
|
|
36797
|
+
const lines = typeof code === "string" ? code.split(`
|
|
36798
|
+
`) : [];
|
|
36799
|
+
const selfReassign = new Map;
|
|
36800
|
+
const escape = (v) => v.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
36801
|
+
for (const [line, defs] of graph.defsByLine) {
|
|
36802
|
+
const text = lines[line - 1];
|
|
36803
|
+
if (!text)
|
|
36804
|
+
continue;
|
|
36805
|
+
for (const d of defs) {
|
|
36806
|
+
if (d.kind !== "local" && d.kind !== "param")
|
|
36807
|
+
continue;
|
|
36808
|
+
const v = escape(d.variable);
|
|
36809
|
+
const m = new RegExp(`(?:^|[^\\w.$])${v}\\s*(?:([-+*/%&|^]|<<|>>)=|=(?!=))(.*)$`).exec(text);
|
|
36810
|
+
if (!m)
|
|
36811
|
+
continue;
|
|
36812
|
+
if (m[1] || new RegExp(`(?:^|[^\\w.$])${v}\\b`).test(m[2])) {
|
|
36813
|
+
const arr = selfReassign.get(d.variable) ?? [];
|
|
36814
|
+
arr.push(line);
|
|
36815
|
+
selfReassign.set(d.variable, arr);
|
|
36816
|
+
}
|
|
36817
|
+
}
|
|
36818
|
+
}
|
|
36819
|
+
const reassignedAt = (v, line) => (selfReassign.get(v) ?? []).includes(line);
|
|
36820
|
+
const defAt = (v, line) => {
|
|
36821
|
+
const own = (graph.defsByLine.get(line) ?? []).find((d) => d.variable === v);
|
|
36822
|
+
if (own)
|
|
36823
|
+
return own;
|
|
36824
|
+
const use = (graph.usesByLine.get(line) ?? []).find((u) => u.variable === v && u.def_id != null);
|
|
36825
|
+
return use ? graph.defById.get(use.def_id) : undefined;
|
|
36826
|
+
};
|
|
36827
|
+
return (step, sourceLine, sinkLine) => {
|
|
36828
|
+
const r = isFalsePositive(constProp, step.line, step.variable);
|
|
36829
|
+
if (!r.isFalsePositive)
|
|
36830
|
+
return false;
|
|
36831
|
+
if (r.reason !== "variable_not_tainted")
|
|
36832
|
+
return true;
|
|
36833
|
+
const lo = Math.min(sourceLine, sinkLine);
|
|
36834
|
+
let d = defAt(step.variable, step.line);
|
|
36835
|
+
let selfHops = 0;
|
|
36836
|
+
for (let guard = 0;d && d.line > lo && reassignedAt(d.variable, d.line) && guard < 32; guard++) {
|
|
36837
|
+
const here = d.id;
|
|
36838
|
+
const prior = (graph.usesByLine.get(d.line) ?? []).find((u) => u.variable === d.variable && u.def_id != null && u.def_id !== here);
|
|
36839
|
+
if (!prior)
|
|
36840
|
+
break;
|
|
36841
|
+
selfHops++;
|
|
36842
|
+
d = graph.defById.get(prior.def_id);
|
|
36843
|
+
}
|
|
36844
|
+
if (!d)
|
|
36845
|
+
return true;
|
|
36846
|
+
if (d.line === sourceLine && sources.some((s) => s.line === sourceLine && !CONTAINER_READ_SOURCES.has(s.type)))
|
|
36847
|
+
return false;
|
|
36848
|
+
if (selfHops > 0 && d.line >= lo)
|
|
36849
|
+
return false;
|
|
36850
|
+
return true;
|
|
36851
|
+
};
|
|
36852
|
+
}
|
|
36853
|
+
|
|
36650
36854
|
class TaintPropagationPass {
|
|
36651
36855
|
name = "taint-propagation";
|
|
36652
36856
|
category = "security";
|
|
@@ -36664,12 +36868,12 @@ class TaintPropagationPass {
|
|
|
36664
36868
|
return { flows: [] };
|
|
36665
36869
|
}
|
|
36666
36870
|
const propagationResult = propagateTaint(graph, sources, sinks, sanitizers);
|
|
36871
|
+
const isVetoed = makeConstPropVeto(constProp, graph, sources, ctx.code);
|
|
36667
36872
|
const verifiedFlows = propagationResult.flows.filter((flow) => {
|
|
36668
36873
|
if (constProp.unreachableLines.has(flow.sink.line))
|
|
36669
36874
|
return false;
|
|
36670
36875
|
for (const step of flow.path) {
|
|
36671
|
-
|
|
36672
|
-
if (fpCheck.isFalsePositive)
|
|
36876
|
+
if (isVetoed(step, flow.source.line, flow.sink.line))
|
|
36673
36877
|
return false;
|
|
36674
36878
|
}
|
|
36675
36879
|
if (isCorrelatedPredicateFP(constProp, flow))
|
|
@@ -36775,7 +36979,7 @@ class TaintPropagationPass {
|
|
|
36775
36979
|
continue;
|
|
36776
36980
|
let isFP = false;
|
|
36777
36981
|
for (const step of f.path) {
|
|
36778
|
-
if (
|
|
36982
|
+
if (isVetoed(step, f.source_line, f.sink_line)) {
|
|
36779
36983
|
isFP = true;
|
|
36780
36984
|
break;
|
|
36781
36985
|
}
|
|
@@ -36801,7 +37005,7 @@ class TaintPropagationPass {
|
|
|
36801
37005
|
continue;
|
|
36802
37006
|
let isFP = false;
|
|
36803
37007
|
for (const step of f.path) {
|
|
36804
|
-
if (
|
|
37008
|
+
if (isVetoed(step, f.source_line, f.sink_line)) {
|
|
36805
37009
|
isFP = true;
|
|
36806
37010
|
break;
|
|
36807
37011
|
}
|
|
@@ -38205,6 +38409,109 @@ var GO_PURE_PACKAGES = new Set([
|
|
|
38205
38409
|
"hex",
|
|
38206
38410
|
"base64"
|
|
38207
38411
|
]);
|
|
38412
|
+
var CSHARP_PURE_STATIC_RECEIVERS = new Set([
|
|
38413
|
+
"string",
|
|
38414
|
+
"String",
|
|
38415
|
+
"Convert",
|
|
38416
|
+
"Encoding",
|
|
38417
|
+
"BitConverter",
|
|
38418
|
+
"Math",
|
|
38419
|
+
"Int16",
|
|
38420
|
+
"Int32",
|
|
38421
|
+
"Int64",
|
|
38422
|
+
"UInt16",
|
|
38423
|
+
"UInt32",
|
|
38424
|
+
"UInt64",
|
|
38425
|
+
"Double",
|
|
38426
|
+
"Single",
|
|
38427
|
+
"Decimal",
|
|
38428
|
+
"Boolean",
|
|
38429
|
+
"Byte",
|
|
38430
|
+
"SByte",
|
|
38431
|
+
"Char",
|
|
38432
|
+
"Guid",
|
|
38433
|
+
"DateTime",
|
|
38434
|
+
"DateTimeOffset",
|
|
38435
|
+
"TimeSpan",
|
|
38436
|
+
"Enum",
|
|
38437
|
+
"Array",
|
|
38438
|
+
"Buffer",
|
|
38439
|
+
"Nullable",
|
|
38440
|
+
"CultureInfo",
|
|
38441
|
+
"StringComparer",
|
|
38442
|
+
"Comparer",
|
|
38443
|
+
"EqualityComparer",
|
|
38444
|
+
"Console",
|
|
38445
|
+
"Debug",
|
|
38446
|
+
"Trace",
|
|
38447
|
+
"Logger",
|
|
38448
|
+
"logger",
|
|
38449
|
+
"_logger",
|
|
38450
|
+
"Log"
|
|
38451
|
+
]);
|
|
38452
|
+
var CSHARP_NON_ESCAPE_METHODS = new Set([
|
|
38453
|
+
"ToString",
|
|
38454
|
+
"ToArray",
|
|
38455
|
+
"ToList",
|
|
38456
|
+
"ToCharArray",
|
|
38457
|
+
"GetHashCode",
|
|
38458
|
+
"Equals",
|
|
38459
|
+
"CompareTo",
|
|
38460
|
+
"Trim",
|
|
38461
|
+
"TrimStart",
|
|
38462
|
+
"TrimEnd",
|
|
38463
|
+
"Substring",
|
|
38464
|
+
"Split",
|
|
38465
|
+
"Join",
|
|
38466
|
+
"Concat",
|
|
38467
|
+
"PadLeft",
|
|
38468
|
+
"PadRight",
|
|
38469
|
+
"ToLower",
|
|
38470
|
+
"ToUpper",
|
|
38471
|
+
"ToLowerInvariant",
|
|
38472
|
+
"ToUpperInvariant",
|
|
38473
|
+
"StartsWith",
|
|
38474
|
+
"EndsWith",
|
|
38475
|
+
"Contains",
|
|
38476
|
+
"IndexOf",
|
|
38477
|
+
"LastIndexOf",
|
|
38478
|
+
"Insert",
|
|
38479
|
+
"Remove",
|
|
38480
|
+
"Normalize",
|
|
38481
|
+
"Append",
|
|
38482
|
+
"AppendLine",
|
|
38483
|
+
"AppendFormat",
|
|
38484
|
+
"TryParse",
|
|
38485
|
+
"Parse",
|
|
38486
|
+
"LogInformation",
|
|
38487
|
+
"LogWarning",
|
|
38488
|
+
"LogError",
|
|
38489
|
+
"LogDebug",
|
|
38490
|
+
"LogTrace",
|
|
38491
|
+
"LogCritical",
|
|
38492
|
+
"Information",
|
|
38493
|
+
"Warning",
|
|
38494
|
+
"Verbose",
|
|
38495
|
+
"Fatal",
|
|
38496
|
+
"BeginScope",
|
|
38497
|
+
"Add",
|
|
38498
|
+
"AddLast",
|
|
38499
|
+
"AddFirst",
|
|
38500
|
+
"AddRange",
|
|
38501
|
+
"TryAdd",
|
|
38502
|
+
"Insert",
|
|
38503
|
+
"Push",
|
|
38504
|
+
"Enqueue"
|
|
38505
|
+
]);
|
|
38506
|
+
function isCSharpNonEscapeCall(call) {
|
|
38507
|
+
const name2 = call.method_name;
|
|
38508
|
+
const recv = (call.receiver ?? "").split(".").pop() ?? "";
|
|
38509
|
+
if (CSHARP_PURE_STATIC_RECEIVERS.has(recv))
|
|
38510
|
+
return true;
|
|
38511
|
+
if (CSHARP_NON_ESCAPE_METHODS.has(name2))
|
|
38512
|
+
return true;
|
|
38513
|
+
return false;
|
|
38514
|
+
}
|
|
38208
38515
|
function isGoNonEscapeCall(call) {
|
|
38209
38516
|
const name2 = call.method_name;
|
|
38210
38517
|
const recv = (call.receiver ?? "").split(".").pop() ?? "";
|
|
@@ -38452,6 +38759,9 @@ function analyzeInterprocedural2(graphOrTypes, callsOrSources, dfgOrSinks, sourc
|
|
|
38452
38759
|
if (graph.ir.meta.language === "go" && isGoNonEscapeCall(call)) {
|
|
38453
38760
|
continue;
|
|
38454
38761
|
}
|
|
38762
|
+
if (graph.ir.meta.language === "csharp" && isCSharpNonEscapeCall(call)) {
|
|
38763
|
+
continue;
|
|
38764
|
+
}
|
|
38455
38765
|
const bashSafeBuiltins = new Set([
|
|
38456
38766
|
"echo",
|
|
38457
38767
|
"printf",
|
|
@@ -40086,6 +40396,8 @@ class VariableShadowingPass {
|
|
|
40086
40396
|
const outerEntry = declLocals[0];
|
|
40087
40397
|
for (let i2 = 1;i2 < numDeclLocals; i2++) {
|
|
40088
40398
|
const inner = declLocals[i2];
|
|
40399
|
+
if (inner.def.line <= outerEntry.def.line)
|
|
40400
|
+
continue;
|
|
40089
40401
|
if (!isInNestedScope(codeLines, outerEntry.def.line, inner.def.line))
|
|
40090
40402
|
continue;
|
|
40091
40403
|
const key = `${variable}-${inner.def.line}`;
|
|
@@ -50357,7 +50669,7 @@ var colors = {
|
|
|
50357
50669
|
};
|
|
50358
50670
|
|
|
50359
50671
|
// src/version.ts
|
|
50360
|
-
var version = "4.9.
|
|
50672
|
+
var version = "4.9.28";
|
|
50361
50673
|
|
|
50362
50674
|
// src/formatters.ts
|
|
50363
50675
|
var LIBRARY_API_SURFACE_TAG2 = "library-api-surface:caller-responsibility";
|
|
@@ -50909,8 +51221,8 @@ function generateSarifResults(results, crossFileData) {
|
|
|
50909
51221
|
|
|
50910
51222
|
// src/build-info.ts
|
|
50911
51223
|
var buildInfo = {
|
|
50912
|
-
gitSha: "
|
|
50913
|
-
builtAt: "2026-
|
|
51224
|
+
gitSha: "7bfe5de",
|
|
51225
|
+
builtAt: "2026-10-01T00:24:15.337Z"
|
|
50914
51226
|
};
|
|
50915
51227
|
|
|
50916
51228
|
// src/utils/args.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cognium-dev",
|
|
3
|
-
"version": "4.9.
|
|
3
|
+
"version": "4.9.28",
|
|
4
4
|
"description": "Static Application Security Testing CLI for detecting security vulnerabilities via taint tracking",
|
|
5
5
|
"bin": {
|
|
6
6
|
"cognium-dev": "dist/cli.js"
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
},
|
|
66
66
|
"dependencies": {
|
|
67
67
|
"@cognium/project-profile-detect": "1.1.2",
|
|
68
|
-
"circle-ir": "4.9.
|
|
68
|
+
"circle-ir": "4.9.28"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
71
|
"@types/node": "^26.6.2",
|