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.
Files changed (2) hide show
  1. package/dist/cli.js +177 -22
  2. 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 exists = chains.some((c) => c.from_def === use.def_id && c.to_def === def.id && c.via === use.variable);
9359
- if (!exists) {
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 ref = [...knownTainted].some((v) => new RegExp(`(?<![\\p{L}\\p{N}_])${escaped(v)}(?![\\p{L}\\p{N}_])`, "u").test(rhs));
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,})\}/g;
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 = graph.ir.dfg.defs.filter((d) => d.variable === variable && d.id !== def.id);
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 escapedName = variable.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
38269
- const namePattern = new RegExp(`\\b${escapedName}\\b`);
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(code, startLine, endLine) {
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(code, m.start_line, m.end_line);
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(code, Math.max(1, line - 20), line + 5);
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.0";
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.0",
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.0"
69
+ "circle-ir": "^4.7.2"
70
70
  },
71
71
  "devDependencies": {
72
72
  "@types/node": "^25.5.0",