cognium-dev 4.7.0 → 4.7.2
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 +177 -22
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -9350,13 +9350,15 @@ function computeChains(defs, uses) {
|
|
|
9350
9350
|
existing.push(use);
|
|
9351
9351
|
usesByLine.set(use.line, existing);
|
|
9352
9352
|
}
|
|
9353
|
+
const seenChains = new Set;
|
|
9353
9354
|
for (const def of defs) {
|
|
9354
9355
|
if (def.kind === "local") {
|
|
9355
9356
|
const usesOnLine = usesByLine.get(def.line) ?? [];
|
|
9356
9357
|
for (const use of usesOnLine) {
|
|
9357
9358
|
if (use.def_id !== null && use.def_id !== def.id) {
|
|
9358
|
-
const
|
|
9359
|
-
if (!
|
|
9359
|
+
const key = `${use.def_id}\x00${def.id}\x00${use.variable}`;
|
|
9360
|
+
if (!seenChains.has(key)) {
|
|
9361
|
+
seenChains.add(key);
|
|
9360
9362
|
chains.push({
|
|
9361
9363
|
from_def: use.def_id,
|
|
9362
9364
|
to_def: def.id,
|
|
@@ -11384,7 +11386,7 @@ var DEFAULT_SINKS = [
|
|
|
11384
11386
|
{ method: "setCommandline", class: "DefaultExecutor", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
11385
11387
|
{ method: "parse", class: "CommandLine", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
11386
11388
|
{ method: "addArgument", class: "CommandLine", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
11387
|
-
{ method: "File", class: "constructor", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0, 1] },
|
|
11389
|
+
{ method: "File", class: "constructor", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0, 1], exclude_languages: ["csharp"] },
|
|
11388
11390
|
{ method: "FileInputStream", class: "constructor", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
|
|
11389
11391
|
{ method: "FileOutputStream", class: "constructor", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
|
|
11390
11392
|
{ method: "FileReader", class: "constructor", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
|
|
@@ -11531,7 +11533,7 @@ var DEFAULT_SINKS = [
|
|
|
11531
11533
|
{ method: "validate", type: "xss", cwe: "CWE-79", severity: "medium", arg_positions: [0] },
|
|
11532
11534
|
{ method: "startElement", class: "ContentHandler", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0, 1, 2] },
|
|
11533
11535
|
{ method: "characters", class: "ContentHandler", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
|
|
11534
|
-
{ method: "output", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
|
|
11536
|
+
{ method: "output", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0], exclude_languages: ["rust"] },
|
|
11535
11537
|
{ method: "setOutput", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
|
|
11536
11538
|
{ method: "writeAttribute", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0, 1] },
|
|
11537
11539
|
{ method: "startElement", class: "MagicSAXFilter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0, 1, 2] },
|
|
@@ -12345,6 +12347,18 @@ var DEFAULT_SINKS = [
|
|
|
12345
12347
|
{ method: "FileStream", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12346
12348
|
{ method: "StreamReader", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12347
12349
|
{ method: "StreamWriter", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12350
|
+
{ method: "Copy", class: "File", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0, 1], languages: ["csharp"] },
|
|
12351
|
+
{ method: "Move", class: "File", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0, 1], languages: ["csharp"] },
|
|
12352
|
+
{ method: "Delete", class: "File", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12353
|
+
{ method: "Open", class: "File", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12354
|
+
{ method: "OpenText", class: "File", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12355
|
+
{ method: "Create", class: "File", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12356
|
+
{ method: "WriteAllLines", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12357
|
+
{ method: "AppendAllLines", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12358
|
+
{ method: "CreateDirectory", class: "Directory", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12359
|
+
{ method: "Delete", class: "Directory", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12360
|
+
{ method: "GetFiles", class: "Directory", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12361
|
+
{ method: "EnumerateFiles", class: "Directory", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12348
12362
|
{ method: "GetAsync", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12349
12363
|
{ method: "PostAsync", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12350
12364
|
{ method: "PutAsync", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
@@ -12359,8 +12373,14 @@ var DEFAULT_SINKS = [
|
|
|
12359
12373
|
{ method: "Create", class: "WebRequest", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12360
12374
|
{ method: "EvaluateAsync", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
12361
12375
|
{ method: "RunAsync", class: "CSharpScript", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
12376
|
+
{ method: "Load", class: "Assembly", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
12377
|
+
{ method: "LoadFrom", class: "Assembly", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
12378
|
+
{ method: "LoadFile", class: "Assembly", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
12362
12379
|
{ method: "Deserialize", class: "BinaryFormatter", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
12363
12380
|
{ method: "Deserialize", class: "NetDataContractSerializer", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
12381
|
+
{ method: "Deserialize", class: "SoapFormatter", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
12382
|
+
{ method: "Deserialize", class: "LosFormatter", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
12383
|
+
{ method: "Deserialize", class: "ObjectStateFormatter", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
12364
12384
|
{ method: "Raw", class: "Html", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12365
12385
|
{ method: "Write", class: "Response", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12366
12386
|
{ method: "HtmlString", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
@@ -12371,12 +12391,20 @@ var DEFAULT_SINKS = [
|
|
|
12371
12391
|
{ method: "AddHeader", type: "crlf", cwe: "CWE-113", severity: "medium", arg_positions: [1], languages: ["csharp"] },
|
|
12372
12392
|
{ method: "AppendHeader", type: "crlf", cwe: "CWE-113", severity: "medium", arg_positions: [1], languages: ["csharp"] },
|
|
12373
12393
|
{ method: "Parse", class: "BsonDocument", type: "nosql_injection", cwe: "CWE-943", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12394
|
+
{ method: "LogInformation", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0], languages: ["csharp"] },
|
|
12395
|
+
{ method: "LogWarning", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0], languages: ["csharp"] },
|
|
12396
|
+
{ method: "LogError", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0], languages: ["csharp"] },
|
|
12397
|
+
{ method: "LogDebug", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0], languages: ["csharp"] },
|
|
12398
|
+
{ method: "LogCritical", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0], languages: ["csharp"] },
|
|
12399
|
+
{ method: "LogTrace", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0], languages: ["csharp"] },
|
|
12400
|
+
{ method: "Log", class: "ILogger", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [1], languages: ["csharp"] },
|
|
12374
12401
|
{ method: "SelectSingleNode", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12375
12402
|
{ method: "SelectNodes", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12376
12403
|
{ method: "Compile", class: "XPathExpression", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12377
12404
|
{ method: "LoadXml", type: "xxe", cwe: "CWE-611", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12378
12405
|
{ method: "Load", class: "XmlDocument", type: "xxe", cwe: "CWE-611", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12379
12406
|
{ method: "Load", class: "XDocument", type: "xxe", cwe: "CWE-611", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12407
|
+
{ method: "XmlTextReader", type: "xxe", cwe: "CWE-611", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12380
12408
|
{ method: "execute", class: "Connection", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
|
|
12381
12409
|
{ method: "fetch", class: "Connection", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
|
|
12382
12410
|
{ method: "fetchrow", class: "Connection", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
|
|
@@ -13512,6 +13540,40 @@ function isSafeJSChildProcessCall(call, pattern, language) {
|
|
|
13512
13540
|
return false;
|
|
13513
13541
|
return true;
|
|
13514
13542
|
}
|
|
13543
|
+
function isSafeCSharpProcessStartCall(call, pattern, language) {
|
|
13544
|
+
if (language !== "csharp")
|
|
13545
|
+
return false;
|
|
13546
|
+
if (pattern.type !== "command_injection")
|
|
13547
|
+
return false;
|
|
13548
|
+
if (call.method_name !== "Start")
|
|
13549
|
+
return false;
|
|
13550
|
+
if (call.arguments.length < 2)
|
|
13551
|
+
return false;
|
|
13552
|
+
const fileArg = call.arguments.find((a) => a.position === 0);
|
|
13553
|
+
if (!fileArg)
|
|
13554
|
+
return false;
|
|
13555
|
+
let raw;
|
|
13556
|
+
if (fileArg.literal !== null && fileArg.literal !== undefined) {
|
|
13557
|
+
raw = String(fileArg.literal).trim();
|
|
13558
|
+
} else {
|
|
13559
|
+
raw = (fileArg.expression ?? "").trim();
|
|
13560
|
+
}
|
|
13561
|
+
if (!/^@?"[^"]*"$/.test(raw))
|
|
13562
|
+
return false;
|
|
13563
|
+
const program = (raw.replace(/^@?"|"$/g, "").split(/[\\/]/).pop() ?? "").toLowerCase().replace(/\.exe$/, "");
|
|
13564
|
+
const SHELL_PROGRAMS = new Set([
|
|
13565
|
+
"sh",
|
|
13566
|
+
"bash",
|
|
13567
|
+
"zsh",
|
|
13568
|
+
"dash",
|
|
13569
|
+
"ash",
|
|
13570
|
+
"ksh",
|
|
13571
|
+
"cmd",
|
|
13572
|
+
"powershell",
|
|
13573
|
+
"pwsh"
|
|
13574
|
+
]);
|
|
13575
|
+
return !SHELL_PROGRAMS.has(program);
|
|
13576
|
+
}
|
|
13515
13577
|
function isSafeRustCommandCall(call, pattern, language) {
|
|
13516
13578
|
if (language !== "rust")
|
|
13517
13579
|
return false;
|
|
@@ -13802,6 +13864,9 @@ function findSinks(calls, patterns, typeHierarchy, language, sourceLines, types)
|
|
|
13802
13864
|
if (isSafeJSChildProcessCall(call, pattern, language)) {
|
|
13803
13865
|
continue;
|
|
13804
13866
|
}
|
|
13867
|
+
if (isSafeCSharpProcessStartCall(call, pattern, language)) {
|
|
13868
|
+
continue;
|
|
13869
|
+
}
|
|
13805
13870
|
if (pattern.safe_if_class_literal_at !== undefined && argIsClassLiteral(call, pattern.safe_if_class_literal_at, types)) {
|
|
13806
13871
|
continue;
|
|
13807
13872
|
}
|
|
@@ -14942,7 +15007,7 @@ function canSourceReachSink(sourceType, sinkType) {
|
|
|
14942
15007
|
file_input: ["deserialization", "xxe", "path_traversal", "command_injection", "code_injection"],
|
|
14943
15008
|
network_input: ["sql_injection", "command_injection", "xss", "ssrf", "log_injection", "format_string", "nosql_injection", "prompt_injection"],
|
|
14944
15009
|
config_param: ["sql_injection", "command_injection", "path_traversal", "xss", "ssrf", "log_injection", "format_string"],
|
|
14945
|
-
interprocedural_param: ["sql_injection", "command_injection", "path_traversal", "xss", "xpath_injection", "ldap_injection", "ssrf", "code_injection", "mybatis_mapper_call", "crlf", "mass_assignment", "open_redirect", "trust_boundary", "log_injection", "format_string", "nosql_injection", "prompt_injection"],
|
|
15010
|
+
interprocedural_param: ["sql_injection", "command_injection", "path_traversal", "xss", "xpath_injection", "ldap_injection", "ssrf", "code_injection", "mybatis_mapper_call", "crlf", "mass_assignment", "open_redirect", "trust_boundary", "log_injection", "format_string", "nosql_injection", "prompt_injection", "xxe", "deserialization"],
|
|
14946
15011
|
plugin_param: ["sql_injection", "command_injection", "path_traversal", "xss", "code_injection", "log_injection", "format_string"]
|
|
14947
15012
|
};
|
|
14948
15013
|
const validSinks = sourceToSinkMapping[sourceType];
|
|
@@ -25032,6 +25097,7 @@ class LanguageSourcesPass {
|
|
|
25032
25097
|
additionalSources.push(...findSetterChainSources(types, code, language));
|
|
25033
25098
|
additionalSources.push(...findJavaScriptAssignmentSources(code, language));
|
|
25034
25099
|
additionalSources.push(...findCSharpRequestSources(code, language));
|
|
25100
|
+
additionalSources.push(...findGoArgvSources(code, language));
|
|
25035
25101
|
const jsDOMSinks = findJavaScriptDOMSinks(code, language);
|
|
25036
25102
|
for (const s of jsDOMSinks) {
|
|
25037
25103
|
const alreadyExists = additionalSinks.some((x) => x.line === s.line && x.cwe === s.cwe);
|
|
@@ -25634,6 +25700,35 @@ function findSetterChainSources(types, sourceCode, language) {
|
|
|
25634
25700
|
}
|
|
25635
25701
|
return sources;
|
|
25636
25702
|
}
|
|
25703
|
+
function findGoArgvSources(sourceCode, language) {
|
|
25704
|
+
if (language !== "go")
|
|
25705
|
+
return [];
|
|
25706
|
+
const sources = [];
|
|
25707
|
+
const lines = sourceCode.split(`
|
|
25708
|
+
`);
|
|
25709
|
+
const rangeRe = /\bfor\b[^;{]*?,\s*([A-Za-z_]\w*)\s*:?=\s*range\s+os\.Args\b/;
|
|
25710
|
+
const assignRe = /\b([A-Za-z_]\w*)\s*:?=\s*os\.Args\b/;
|
|
25711
|
+
for (let i2 = 0;i2 < lines.length; i2++) {
|
|
25712
|
+
const line = lines[i2];
|
|
25713
|
+
const rm = rangeRe.exec(line);
|
|
25714
|
+
const m = rm ?? assignRe.exec(line);
|
|
25715
|
+
if (!m)
|
|
25716
|
+
continue;
|
|
25717
|
+
const varName = m[1];
|
|
25718
|
+
const lineNumber = i2 + 1;
|
|
25719
|
+
if (sources.some((s) => s.line === lineNumber && s.variable === varName))
|
|
25720
|
+
continue;
|
|
25721
|
+
sources.push({
|
|
25722
|
+
type: "io_input",
|
|
25723
|
+
location: `${varName} = os.Args`,
|
|
25724
|
+
severity: "high",
|
|
25725
|
+
line: lineNumber,
|
|
25726
|
+
confidence: 1,
|
|
25727
|
+
variable: varName
|
|
25728
|
+
});
|
|
25729
|
+
}
|
|
25730
|
+
return sources;
|
|
25731
|
+
}
|
|
25637
25732
|
function findCSharpRequestSources(sourceCode, language) {
|
|
25638
25733
|
if (language !== "csharp")
|
|
25639
25734
|
return [];
|
|
@@ -26411,7 +26506,8 @@ function buildJavaTaintedVars(sourceCode, seedVars) {
|
|
|
26411
26506
|
if (knownTainted.has(lhs))
|
|
26412
26507
|
continue;
|
|
26413
26508
|
const escaped = (v) => v.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
26414
|
-
const
|
|
26509
|
+
const rhsCode = rhs.replace(/\$@?"(?:[^"\\]|\\.)*"/g, (lit) => " " + [...lit.matchAll(/\{([^}]*)\}/g)].map((x) => x[1]).join(" ") + " ").replace(/@?"(?:[^"\\]|\\.)*"/g, " ").replace(/'(?:[^'\\]|\\.)'/g, " ");
|
|
26510
|
+
const ref = [...knownTainted].some((v) => new RegExp(`(?<![\\p{L}\\p{N}_])${escaped(v)}(?![\\p{L}\\p{N}_])`, "u").test(rhsCode));
|
|
26415
26511
|
if (ref) {
|
|
26416
26512
|
derived.set(lhs, i2 + 1);
|
|
26417
26513
|
knownTainted.add(lhs);
|
|
@@ -26597,7 +26693,7 @@ function findBashTaintSources(sourceCode, dfg) {
|
|
|
26597
26693
|
});
|
|
26598
26694
|
}
|
|
26599
26695
|
}
|
|
26600
|
-
const envRe = /\$([A-Z][A-Z0-9_]{2,})|\$\{([A-Z][A-Z0-9_]{2,})
|
|
26696
|
+
const envRe = /\$([A-Z][A-Z0-9_]{2,})|\$\{([A-Z][A-Z0-9_]{2,})(?:[:#%/^,@!*+?=-][^}]*)?\}/g;
|
|
26601
26697
|
let em;
|
|
26602
26698
|
while ((em = envRe.exec(line)) !== null) {
|
|
26603
26699
|
const envVar = em[1] ?? em[2];
|
|
@@ -36419,6 +36515,26 @@ function analyzeInterprocedural2(graphOrTypes, callsOrSources, dfgOrSinks, sourc
|
|
|
36419
36515
|
"Command",
|
|
36420
36516
|
"CommandContext"
|
|
36421
36517
|
]);
|
|
36518
|
+
const ormQueryBuilderMethods = new Set([
|
|
36519
|
+
"findMany",
|
|
36520
|
+
"findFirst",
|
|
36521
|
+
"findUnique",
|
|
36522
|
+
"findUniqueOrThrow",
|
|
36523
|
+
"findFirstOrThrow",
|
|
36524
|
+
"findOne",
|
|
36525
|
+
"findAll",
|
|
36526
|
+
"findByPk",
|
|
36527
|
+
"findAndCountAll",
|
|
36528
|
+
"findBy",
|
|
36529
|
+
"findOneBy",
|
|
36530
|
+
"where",
|
|
36531
|
+
"andWhere",
|
|
36532
|
+
"orWhere",
|
|
36533
|
+
"whereIn",
|
|
36534
|
+
"whereNot",
|
|
36535
|
+
"first",
|
|
36536
|
+
"bind"
|
|
36537
|
+
]);
|
|
36422
36538
|
const sanitizerMethods = new Set;
|
|
36423
36539
|
for (const san of sanitizers) {
|
|
36424
36540
|
sanitizerMethods.add(san.method);
|
|
@@ -36443,7 +36559,7 @@ function analyzeInterprocedural2(graphOrTypes, callsOrSources, dfgOrSinks, sourc
|
|
|
36443
36559
|
}
|
|
36444
36560
|
const targetMethod = getMethodNode(methodNodes, call.method_name);
|
|
36445
36561
|
if (!targetMethod) {
|
|
36446
|
-
if (taintedArgPositions.length > 0 && !collectionMethods.has(call.method_name) && !sanitizerMethods.has(call.method_name) && !safeUtilityMethods.has(call.method_name)) {
|
|
36562
|
+
if (taintedArgPositions.length > 0 && !collectionMethods.has(call.method_name) && !sanitizerMethods.has(call.method_name) && !safeUtilityMethods.has(call.method_name) && !ormQueryBuilderMethods.has(call.method_name)) {
|
|
36447
36563
|
const isBash = graph.ir.meta.language === "bash";
|
|
36448
36564
|
const bashSafeBuiltins = new Set([
|
|
36449
36565
|
"echo",
|
|
@@ -38233,6 +38349,7 @@ var SKIP_NAMES3 = new Set([
|
|
|
38233
38349
|
"unknown",
|
|
38234
38350
|
"bigint"
|
|
38235
38351
|
]);
|
|
38352
|
+
var EMPTY_LINES = [];
|
|
38236
38353
|
|
|
38237
38354
|
class UnusedVariablePass {
|
|
38238
38355
|
name = "unused-variable";
|
|
@@ -38247,6 +38364,35 @@ class UnusedVariablePass {
|
|
|
38247
38364
|
`);
|
|
38248
38365
|
const unusedVars = [];
|
|
38249
38366
|
const reported = new Set;
|
|
38367
|
+
const defsByVar = new Map;
|
|
38368
|
+
for (const d of graph.ir.dfg.defs) {
|
|
38369
|
+
const arr = defsByVar.get(d.variable);
|
|
38370
|
+
if (arr)
|
|
38371
|
+
arr.push(d);
|
|
38372
|
+
else
|
|
38373
|
+
defsByVar.set(d.variable, [d]);
|
|
38374
|
+
}
|
|
38375
|
+
const nameLines = new Map;
|
|
38376
|
+
const idRe = /[A-Za-z_][A-Za-z0-9_]*/g;
|
|
38377
|
+
for (let i2 = 0;i2 < codeLines.length; i2++) {
|
|
38378
|
+
const line = codeLines[i2];
|
|
38379
|
+
idRe.lastIndex = 0;
|
|
38380
|
+
let seen = null;
|
|
38381
|
+
let m;
|
|
38382
|
+
while ((m = idRe.exec(line)) !== null) {
|
|
38383
|
+
const w = m[0];
|
|
38384
|
+
if (seen === null)
|
|
38385
|
+
seen = new Set;
|
|
38386
|
+
if (seen.has(w))
|
|
38387
|
+
continue;
|
|
38388
|
+
seen.add(w);
|
|
38389
|
+
const arr = nameLines.get(w);
|
|
38390
|
+
if (arr)
|
|
38391
|
+
arr.push(i2 + 1);
|
|
38392
|
+
else
|
|
38393
|
+
nameLines.set(w, [i2 + 1]);
|
|
38394
|
+
}
|
|
38395
|
+
}
|
|
38250
38396
|
for (const def of graph.ir.dfg.defs) {
|
|
38251
38397
|
if (def.kind !== "local")
|
|
38252
38398
|
continue;
|
|
@@ -38263,19 +38409,20 @@ class UnusedVariablePass {
|
|
|
38263
38409
|
const uses = graph.usesOfDef(def.id);
|
|
38264
38410
|
if (uses.length > 0)
|
|
38265
38411
|
continue;
|
|
38266
|
-
const otherDefs =
|
|
38412
|
+
const otherDefs = (defsByVar.get(variable) ?? []).filter((d) => d.id !== def.id);
|
|
38267
38413
|
const otherDefLines = new Set(otherDefs.map((d) => d.line));
|
|
38268
|
-
const
|
|
38269
|
-
const
|
|
38414
|
+
const plainName = /^[A-Za-z_][A-Za-z0-9_]*$/.test(variable);
|
|
38415
|
+
const idxLines = plainName ? nameLines.get(variable) ?? EMPTY_LINES : null;
|
|
38416
|
+
const namePattern = plainName ? null : new RegExp(`\\b${variable.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\b`);
|
|
38270
38417
|
if (otherDefLines.size === 0) {
|
|
38271
|
-
const usedElsewhere = codeLines.some((line, idx) => idx !== def.line - 1 && namePattern.test(line));
|
|
38418
|
+
const usedElsewhere = idxLines !== null ? idxLines.some((ln) => ln !== def.line) : codeLines.some((line, idx) => idx !== def.line - 1 && namePattern.test(line));
|
|
38272
38419
|
if (usedElsewhere)
|
|
38273
38420
|
continue;
|
|
38274
38421
|
} else {
|
|
38275
38422
|
const lineText2 = codeLines[def.line - 1] ?? "";
|
|
38276
38423
|
const isTrueDeclaration = /\b(?:let|const|var)\s+[\w{[]/.test(lineText2) || /\b(?:int|long|float|double|boolean|byte|char|short|var|final)\b/.test(lineText2) || /\b[A-Z]\w*(?:<[^>]*>)?\s+\w/.test(lineText2) || /\blet\s+(?:mut\s+)?\w/.test(lineText2);
|
|
38277
38424
|
if (isTrueDeclaration) {
|
|
38278
|
-
const usedBeforeNextDef = codeLines.some((line, idx) => {
|
|
38425
|
+
const usedBeforeNextDef = idxLines !== null ? idxLines.some((ln) => ln !== def.line && !otherDefLines.has(ln) && !otherDefs.some((d) => d.line > def.line && d.line < ln)) : codeLines.some((line, idx) => {
|
|
38279
38426
|
const lineNum = idx + 1;
|
|
38280
38427
|
if (lineNum === def.line || otherDefLines.has(lineNum))
|
|
38281
38428
|
return false;
|
|
@@ -38286,7 +38433,7 @@ class UnusedVariablePass {
|
|
|
38286
38433
|
if (usedBeforeNextDef)
|
|
38287
38434
|
continue;
|
|
38288
38435
|
} else {
|
|
38289
|
-
const usedOnNonDefLine = codeLines.some((line, idx) => {
|
|
38436
|
+
const usedOnNonDefLine = idxLines !== null ? idxLines.some((ln) => ln !== def.line && !otherDefLines.has(ln)) : codeLines.some((line, idx) => {
|
|
38290
38437
|
const lineNum = idx + 1;
|
|
38291
38438
|
return lineNum !== def.line && !otherDefLines.has(lineNum) && namePattern.test(line);
|
|
38292
38439
|
});
|
|
@@ -41350,6 +41497,10 @@ function isLikelyCredentialAssignment(line) {
|
|
|
41350
41497
|
return null;
|
|
41351
41498
|
if (isAllSameChar(value))
|
|
41352
41499
|
return null;
|
|
41500
|
+
if (value.toLowerCase() === name2.toLowerCase())
|
|
41501
|
+
return null;
|
|
41502
|
+
if (/^(?:https?:\/\/|urn:|xmlns)/i.test(value))
|
|
41503
|
+
return null;
|
|
41353
41504
|
if (value.length < 12)
|
|
41354
41505
|
return null;
|
|
41355
41506
|
if (shannonEntropy(value) < 3.5)
|
|
@@ -43712,9 +43863,7 @@ class InfoDisclosureStacktracePass {
|
|
|
43712
43863
|
// ../circle-ir/dist/analysis/passes/unrestricted-file-upload-pass.js
|
|
43713
43864
|
var UPLOAD_NAME_RE = /(?:getOriginalFilename|getSubmittedFileName|originalname|originalName|\.filename|\.Filename|FileHeader\.Filename|UploadFile)/;
|
|
43714
43865
|
var FILE_SAFE_CALL_RE = /(?:secure_filename|FilenameUtils\.getExtension|\.lastIndexOf\(['"]\.['"]\)|ALLOWED_EXT|ALLOWED_EXTENSIONS|allowedExtensions|\bfileFilter\b|filepath\.Ext|path\.extname)/;
|
|
43715
|
-
function lineWindow(
|
|
43716
|
-
const lines = code.split(`
|
|
43717
|
-
`);
|
|
43866
|
+
function lineWindow(lines, startLine, endLine) {
|
|
43718
43867
|
const s = Math.max(0, startLine - 1);
|
|
43719
43868
|
const e = Math.min(lines.length, endLine);
|
|
43720
43869
|
return lines.slice(s, e).join(`
|
|
@@ -43738,10 +43887,12 @@ class UnrestrictedFileUploadPass {
|
|
|
43738
43887
|
const { graph, language, code } = ctx;
|
|
43739
43888
|
const file = graph.ir.meta.file;
|
|
43740
43889
|
const findings = [];
|
|
43890
|
+
const codeLines = code.split(`
|
|
43891
|
+
`);
|
|
43741
43892
|
const safeFunctionRanges = [];
|
|
43742
43893
|
for (const t of graph.ir.types) {
|
|
43743
43894
|
for (const m of t.methods) {
|
|
43744
|
-
const body2 = lineWindow(
|
|
43895
|
+
const body2 = lineWindow(codeLines, m.start_line, m.end_line);
|
|
43745
43896
|
if (FILE_SAFE_CALL_RE.test(body2)) {
|
|
43746
43897
|
safeFunctionRanges.push({ start: m.start_line, end: m.end_line });
|
|
43747
43898
|
}
|
|
@@ -43752,7 +43903,7 @@ class UnrestrictedFileUploadPass {
|
|
|
43752
43903
|
if (line >= r.start && line <= r.end)
|
|
43753
43904
|
return true;
|
|
43754
43905
|
}
|
|
43755
|
-
const win = lineWindow(
|
|
43906
|
+
const win = lineWindow(codeLines, Math.max(1, line - 20), line + 5);
|
|
43756
43907
|
return FILE_SAFE_CALL_RE.test(win);
|
|
43757
43908
|
};
|
|
43758
43909
|
if (language === "java") {
|
|
@@ -48002,7 +48153,7 @@ var colors = {
|
|
|
48002
48153
|
};
|
|
48003
48154
|
|
|
48004
48155
|
// src/version.ts
|
|
48005
|
-
var version = "4.7.
|
|
48156
|
+
var version = "4.7.2";
|
|
48006
48157
|
|
|
48007
48158
|
// src/formatters.ts
|
|
48008
48159
|
var LIBRARY_API_SURFACE_TAG2 = "library-api-surface:caller-responsibility";
|
|
@@ -49080,7 +49231,9 @@ async function initWasm(spin) {
|
|
|
49080
49231
|
typescript: join3(wasmDir, "tree-sitter-javascript.wasm"),
|
|
49081
49232
|
python: join3(wasmDir, "tree-sitter-python.wasm"),
|
|
49082
49233
|
rust: join3(wasmDir, "tree-sitter-rust.wasm"),
|
|
49083
|
-
html: join3(wasmDir, "tree-sitter-html.wasm")
|
|
49234
|
+
html: join3(wasmDir, "tree-sitter-html.wasm"),
|
|
49235
|
+
csharp: join3(wasmDir, "tree-sitter-csharp.wasm"),
|
|
49236
|
+
tsx: join3(wasmDir, "tree-sitter-tsx.wasm")
|
|
49084
49237
|
}
|
|
49085
49238
|
});
|
|
49086
49239
|
} else {
|
|
@@ -49113,7 +49266,9 @@ Please ensure the wasm/ directory is located next to the binary or in your curre
|
|
|
49113
49266
|
typescript: wasmBasePath + "tree-sitter-javascript.wasm",
|
|
49114
49267
|
python: wasmBasePath + "tree-sitter-python.wasm",
|
|
49115
49268
|
rust: wasmBasePath + "tree-sitter-rust.wasm",
|
|
49116
|
-
html: wasmBasePath + "tree-sitter-html.wasm"
|
|
49269
|
+
html: wasmBasePath + "tree-sitter-html.wasm",
|
|
49270
|
+
csharp: wasmBasePath + "tree-sitter-csharp.wasm",
|
|
49271
|
+
tsx: wasmBasePath + "tree-sitter-tsx.wasm"
|
|
49117
49272
|
}
|
|
49118
49273
|
});
|
|
49119
49274
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cognium-dev",
|
|
3
|
-
"version": "4.7.
|
|
3
|
+
"version": "4.7.2",
|
|
4
4
|
"description": "Static Application Security Testing CLI for detecting security vulnerabilities via taint tracking",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
},
|
|
67
67
|
"dependencies": {
|
|
68
68
|
"@cognium/project-profile-detect": "^1.1.0",
|
|
69
|
-
"circle-ir": "^4.7.
|
|
69
|
+
"circle-ir": "^4.7.2"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
72
|
"@types/node": "^25.5.0",
|