cognium-dev 3.49.0 → 3.50.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/cli.js +86 -15
  2. package/package.json +2 -2
package/dist/cli.js CHANGED
@@ -21511,6 +21511,28 @@ function buildTaintFlow(source, sink, taintInfo) {
21511
21511
  };
21512
21512
  }
21513
21513
 
21514
+ // ../circle-ir/dist/analysis/findings.js
21515
+ function canSourceReachSink(sourceType, sinkType) {
21516
+ const sourceToSinkMapping = {
21517
+ http_param: ["sql_injection", "command_injection", "path_traversal", "xss", "xpath_injection", "ldap_injection", "ssrf", "mybatis_mapper_call", "code_injection"],
21518
+ http_body: ["sql_injection", "command_injection", "deserialization", "xxe", "xss", "code_injection", "mybatis_mapper_call"],
21519
+ http_header: ["sql_injection", "xss", "ssrf", "mybatis_mapper_call", "code_injection"],
21520
+ http_cookie: ["sql_injection", "xss", "mybatis_mapper_call", "code_injection"],
21521
+ http_path: ["path_traversal", "sql_injection", "ssrf", "mybatis_mapper_call"],
21522
+ http_query: ["sql_injection", "command_injection", "xss", "ssrf", "mybatis_mapper_call", "code_injection"],
21523
+ io_input: ["command_injection", "path_traversal", "deserialization", "xxe", "code_injection", "xss"],
21524
+ env_input: ["command_injection", "path_traversal"],
21525
+ db_input: ["xss", "sql_injection"],
21526
+ file_input: ["deserialization", "xxe", "path_traversal", "command_injection", "code_injection"],
21527
+ network_input: ["sql_injection", "command_injection", "xss", "ssrf"],
21528
+ config_param: ["sql_injection", "command_injection", "path_traversal", "xss", "ssrf"],
21529
+ interprocedural_param: ["sql_injection", "command_injection", "path_traversal", "xss", "xpath_injection", "ldap_injection", "ssrf", "code_injection", "mybatis_mapper_call"],
21530
+ plugin_param: ["sql_injection", "command_injection", "path_traversal", "xss", "code_injection"]
21531
+ };
21532
+ const validSinks = sourceToSinkMapping[sourceType];
21533
+ return validSinks ? validSinks.includes(sinkType) : false;
21534
+ }
21535
+
21514
21536
  // ../circle-ir/dist/analysis/passes/taint-propagation-pass.js
21515
21537
  class TaintPropagationPass {
21516
21538
  name = "taint-propagation";
@@ -21521,7 +21543,11 @@ class TaintPropagationPass {
21521
21543
  const constProp = ctx.getResult("constant-propagation");
21522
21544
  const sinkFilter = ctx.getResult("sink-filter");
21523
21545
  const { sources, sinks, sanitizers } = sinkFilter;
21524
- if (sources.length === 0 || sinks.length === 0) {
21546
+ if (sinks.length === 0) {
21547
+ return { flows: [] };
21548
+ }
21549
+ const canSynthesize = ctx.language === "python" && typeof ctx.code === "string";
21550
+ if (sources.length === 0 && !canSynthesize) {
21525
21551
  return { flows: [] };
21526
21552
  }
21527
21553
  const propagationResult = propagateTaint2(graph, sources, sinks, sanitizers);
@@ -21805,25 +21831,37 @@ function detectParameterSinkFlows(types, calls, sources, sinks, unreachableLines
21805
21831
  function detectExpressionScanFlows(calls, sources, sinks, sanitizers, unreachableLines, code, language) {
21806
21832
  const flows = [];
21807
21833
  const sourcesWithVar = sources.filter((s) => typeof s.variable === "string" && s.variable.length > 0);
21808
- if (sourcesWithVar.length === 0)
21809
- return flows;
21810
21834
  const aliasSanitizedFor = new Map;
21811
21835
  if (language === "python" && typeof code === "string") {
21812
21836
  const derived = buildPythonTaintedVars(code);
21813
21837
  if (derived.size > 0) {
21838
+ const existingVars = new Set(sourcesWithVar.map((s) => s.variable));
21839
+ const hasRealSource = sourcesWithVar.length > 0;
21814
21840
  let anchor = sourcesWithVar[0];
21815
- for (const s of sourcesWithVar) {
21816
- if (s.line < anchor.line)
21817
- anchor = s;
21841
+ if (anchor) {
21842
+ for (const s of sourcesWithVar) {
21843
+ if (s.line < anchor.line)
21844
+ anchor = s;
21845
+ }
21818
21846
  }
21819
- const existingVars = new Set(sourcesWithVar.map((s) => s.variable));
21820
- for (const [varName] of derived) {
21847
+ for (const [varName, originLine] of derived) {
21821
21848
  if (!varName || existingVars.has(varName))
21822
21849
  continue;
21823
- sourcesWithVar.push({
21824
- ...anchor,
21825
- variable: varName
21826
- });
21850
+ if (hasRealSource && anchor) {
21851
+ sourcesWithVar.push({
21852
+ ...anchor,
21853
+ variable: varName
21854
+ });
21855
+ } else {
21856
+ sourcesWithVar.push({
21857
+ type: "http_param",
21858
+ location: `<derived> ${varName}`,
21859
+ severity: "high",
21860
+ line: originLine,
21861
+ confidence: 0.9,
21862
+ variable: varName
21863
+ });
21864
+ }
21827
21865
  existingVars.add(varName);
21828
21866
  }
21829
21867
  if (sanitizers && sanitizers.length > 0) {
@@ -21863,7 +21901,7 @@ function detectExpressionScanFlows(calls, sources, sinks, sanitizers, unreachabl
21863
21901
  }
21864
21902
  }
21865
21903
  }
21866
- if (language === "rust" && typeof code === "string") {
21904
+ if (language === "rust" && typeof code === "string" && sourcesWithVar.length > 0) {
21867
21905
  const seedVars = new Set(sourcesWithVar.map((s) => s.variable));
21868
21906
  const derived = buildRustTaintedVars(code, seedVars);
21869
21907
  if (derived.size > 0) {
@@ -21937,6 +21975,39 @@ function detectExpressionScanFlows(calls, sources, sinks, sanitizers, unreachabl
21937
21975
  }
21938
21976
  }
21939
21977
  }
21978
+ const sourcesByLine = new Map;
21979
+ for (const s of sources) {
21980
+ if (s.variable && s.variable.length > 0)
21981
+ continue;
21982
+ const arr = sourcesByLine.get(s.line) ?? [];
21983
+ arr.push(s);
21984
+ sourcesByLine.set(s.line, arr);
21985
+ }
21986
+ for (const sink of sinks) {
21987
+ if (unreachableLines.has(sink.line))
21988
+ continue;
21989
+ const colocSources = sourcesByLine.get(sink.line);
21990
+ if (!colocSources || colocSources.length === 0)
21991
+ continue;
21992
+ for (const source of colocSources) {
21993
+ if (!canSourceReachSink(source.type, sink.type))
21994
+ continue;
21995
+ if (flows.some((f) => f.source_line === source.line && f.sink_line === sink.line && f.sink_type === sink.type))
21996
+ continue;
21997
+ flows.push({
21998
+ source_line: source.line,
21999
+ sink_line: sink.line,
22000
+ source_type: source.type,
22001
+ sink_type: sink.type,
22002
+ path: [
22003
+ { variable: "<inline>", line: source.line, type: "source" },
22004
+ { variable: "<inline>", line: sink.line, type: "sink" }
22005
+ ],
22006
+ confidence: source.confidence * sink.confidence * 0.85,
22007
+ sanitized: false
22008
+ });
22009
+ }
22010
+ }
21940
22011
  return flows;
21941
22012
  }
21942
22013
 
@@ -22373,7 +22444,7 @@ class InterproceduralPass {
22373
22444
  const taintProp = ctx.getResult("taint-propagation");
22374
22445
  const { sources, sinks, sanitizers } = sinkFilter;
22375
22446
  if (sources.length === 0) {
22376
- return { additionalSinks: [], additionalFlows: [] };
22447
+ return { additionalSinks: [], additionalFlows: [...taintProp.flows] };
22377
22448
  }
22378
22449
  const additionalSinks = [];
22379
22450
  const additionalFlows = [...taintProp.flows];
@@ -28411,7 +28482,7 @@ var colors = {
28411
28482
  };
28412
28483
 
28413
28484
  // src/version.ts
28414
- var version = "3.49.0";
28485
+ var version = "3.50.0";
28415
28486
 
28416
28487
  // src/formatters.ts
28417
28488
  var SINK_SEVERITY = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cognium-dev",
3
- "version": "3.49.0",
3
+ "version": "3.50.0",
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",
@@ -65,7 +65,7 @@
65
65
  "registry": "https://registry.npmjs.org/"
66
66
  },
67
67
  "dependencies": {
68
- "circle-ir": "^3.49.0"
68
+ "circle-ir": "^3.50.0"
69
69
  },
70
70
  "devDependencies": {
71
71
  "@types/node": "^25.5.0",