cognium-dev 3.93.0 → 3.96.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 +40 -4
  2. package/package.json +2 -2
package/dist/cli.js CHANGED
@@ -12125,6 +12125,19 @@ var CWE_78_RECEIVER_ALLOWLIST = new Set([
12125
12125
  "ProcessExecutor",
12126
12126
  "RuntimeUtil"
12127
12127
  ]);
12128
+ function isFunctionCallbackArgument(arg) {
12129
+ if (arg.literal !== null && arg.literal !== undefined)
12130
+ return false;
12131
+ const expr = (arg.expression ?? "").trim();
12132
+ if (expr.length === 0)
12133
+ return false;
12134
+ const body2 = expr.startsWith("async ") ? expr.slice(6).trimStart() : expr;
12135
+ if (body2.startsWith("("))
12136
+ return true;
12137
+ if (/^function\b/.test(body2))
12138
+ return true;
12139
+ return false;
12140
+ }
12128
12141
  function findSinks(calls, patterns, typeHierarchy, language, sourceLines) {
12129
12142
  const sinkMap = new Map;
12130
12143
  for (const call of calls) {
@@ -12157,6 +12170,12 @@ function findSinks(calls, patterns, typeHierarchy, language, sourceLines) {
12157
12170
  }
12158
12171
  }
12159
12172
  }
12173
+ if (pattern.type === "code_injection" && (call.method_name === "setInterval" || call.method_name === "setTimeout")) {
12174
+ const firstArg = call.arguments.find((a) => a.position === 0);
12175
+ if (firstArg && isFunctionCallbackArgument(firstArg)) {
12176
+ continue;
12177
+ }
12178
+ }
12160
12179
  const location = formatCallLocation(call);
12161
12180
  const key = `${location}:${call.location.line}:${pattern.cwe}`;
12162
12181
  const confidence = calculateSinkConfidence(call, pattern);
@@ -17897,6 +17916,16 @@ function applyPerFileFindingCap(filePath, findings, cap) {
17897
17916
  return [advisory];
17898
17917
  }
17899
17918
 
17919
+ // ../circle-ir/dist/analysis/confidence-filter.js
17920
+ function applyConfidenceFilter(findings, includeSpeculative) {
17921
+ if (includeSpeculative)
17922
+ return findings;
17923
+ return findings.filter(isHighConfidence);
17924
+ }
17925
+ function isHighConfidence(finding) {
17926
+ return finding.confidence === undefined || finding.confidence === "high";
17927
+ }
17928
+
17900
17929
  // ../circle-ir/dist/languages/registry.js
17901
17930
  class DefaultLanguageRegistry {
17902
17931
  plugins = new Map;
@@ -25205,6 +25234,10 @@ function shouldGateInterproceduralParam(sourceType, enclosingMethod, enclosingTy
25205
25234
  class InterproceduralPass {
25206
25235
  name = "interprocedural";
25207
25236
  category = "security";
25237
+ enableEntryPointGate;
25238
+ constructor(options) {
25239
+ this.enableEntryPointGate = options?.enableEntryPointGate ?? true;
25240
+ }
25208
25241
  run(ctx) {
25209
25242
  const { graph } = ctx;
25210
25243
  const constProp = ctx.getResult("constant-propagation");
@@ -25263,7 +25296,7 @@ class InterproceduralPass {
25263
25296
  continue;
25264
25297
  if (source.type === "interprocedural_param" && source.confidence < 0.6)
25265
25298
  continue;
25266
- if (source.type === "interprocedural_param" && source.in_method) {
25299
+ if (this.enableEntryPointGate && source.type === "interprocedural_param" && source.in_method) {
25267
25300
  const enclosing = methodNameIndex.get(source.in_method);
25268
25301
  if (shouldGateInterproceduralParam(source.type, enclosing?.method, enclosing?.type, { language, types: graph.ir.types })) {
25269
25302
  continue;
@@ -34253,7 +34286,9 @@ async function analyze(code, filePath, language, options = {}) {
34253
34286
  pipeline.add(new LanguageSourcesPass);
34254
34287
  pipeline.add(new SinkFilterPass);
34255
34288
  pipeline.add(new TaintPropagationPass);
34256
- pipeline.add(new InterproceduralPass);
34289
+ pipeline.add(new InterproceduralPass({
34290
+ enableEntryPointGate: options.enableEntryPointGate ?? true
34291
+ }));
34257
34292
  if (!disabledPasses.has("scan-secrets"))
34258
34293
  pipeline.add(new ScanSecretsPass);
34259
34294
  if (!disabledPasses.has("dead-code"))
@@ -34383,7 +34418,8 @@ async function analyze(code, filePath, language, options = {}) {
34383
34418
  unresolvedItems: unresolved.length
34384
34419
  });
34385
34420
  emitFindingsInstrumentation(filePath, findings, taint);
34386
- const cappedFindings = applyPerFileFindingCap(filePath, findings, options.perFileFindingCap ?? DEFAULT_PER_FILE_FINDING_CAP);
34421
+ const verifiedFindings = applyConfidenceFilter(findings, options.includeSpeculative === true);
34422
+ const cappedFindings = applyPerFileFindingCap(filePath, verifiedFindings, options.perFileFindingCap ?? DEFAULT_PER_FILE_FINDING_CAP);
34387
34423
  return {
34388
34424
  meta,
34389
34425
  types,
@@ -34562,7 +34598,7 @@ var colors = {
34562
34598
  };
34563
34599
 
34564
34600
  // src/version.ts
34565
- var version = "3.93.0";
34601
+ var version = "3.96.0";
34566
34602
 
34567
34603
  // src/formatters.ts
34568
34604
  var SINK_SEVERITY = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cognium-dev",
3
- "version": "3.93.0",
3
+ "version": "3.96.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.93.0"
68
+ "circle-ir": "^3.96.0"
69
69
  },
70
70
  "devDependencies": {
71
71
  "@types/node": "^25.5.0",