cognium-dev 3.91.0 → 3.95.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.
- package/dist/cli.js +136 -77
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -17789,6 +17789,124 @@ function normalizeCondition(cond) {
|
|
|
17789
17789
|
}
|
|
17790
17790
|
return normalized;
|
|
17791
17791
|
}
|
|
17792
|
+
// ../circle-ir/dist/utils/logger.js
|
|
17793
|
+
var LOG_LEVELS = {
|
|
17794
|
+
trace: 0,
|
|
17795
|
+
debug: 1,
|
|
17796
|
+
info: 2,
|
|
17797
|
+
warn: 3,
|
|
17798
|
+
error: 4,
|
|
17799
|
+
fatal: 5,
|
|
17800
|
+
silent: 6
|
|
17801
|
+
};
|
|
17802
|
+
var currentLevel = "silent";
|
|
17803
|
+
var customLogger = null;
|
|
17804
|
+
function shouldLog(level) {
|
|
17805
|
+
return LOG_LEVELS[level] >= LOG_LEVELS[currentLevel];
|
|
17806
|
+
}
|
|
17807
|
+
function setLogLevel(level) {
|
|
17808
|
+
currentLevel = level;
|
|
17809
|
+
}
|
|
17810
|
+
var logger = {
|
|
17811
|
+
trace: (msg, obj) => {
|
|
17812
|
+
if (customLogger) {
|
|
17813
|
+
customLogger.trace(msg, obj);
|
|
17814
|
+
return;
|
|
17815
|
+
}
|
|
17816
|
+
if (shouldLog("trace"))
|
|
17817
|
+
console.debug(obj ? `[TRACE] ${msg} ${JSON.stringify(obj)}` : `[TRACE] ${msg}`);
|
|
17818
|
+
},
|
|
17819
|
+
debug: (msg, obj) => {
|
|
17820
|
+
if (customLogger) {
|
|
17821
|
+
customLogger.debug(msg, obj);
|
|
17822
|
+
return;
|
|
17823
|
+
}
|
|
17824
|
+
if (shouldLog("debug"))
|
|
17825
|
+
console.debug(obj ? `[DEBUG] ${msg} ${JSON.stringify(obj)}` : `[DEBUG] ${msg}`);
|
|
17826
|
+
},
|
|
17827
|
+
info: (msg, obj) => {
|
|
17828
|
+
if (customLogger) {
|
|
17829
|
+
customLogger.info(msg, obj);
|
|
17830
|
+
return;
|
|
17831
|
+
}
|
|
17832
|
+
if (shouldLog("info"))
|
|
17833
|
+
console.error(obj ? `[INFO] ${msg} ${JSON.stringify(obj)}` : `[INFO] ${msg}`);
|
|
17834
|
+
},
|
|
17835
|
+
warn: (msg, obj) => {
|
|
17836
|
+
if (customLogger) {
|
|
17837
|
+
customLogger.warn(msg, obj);
|
|
17838
|
+
return;
|
|
17839
|
+
}
|
|
17840
|
+
if (shouldLog("warn"))
|
|
17841
|
+
console.warn(obj ? `[WARN] ${msg} ${JSON.stringify(obj)}` : `[WARN] ${msg}`);
|
|
17842
|
+
},
|
|
17843
|
+
error: (msg, obj) => {
|
|
17844
|
+
if (customLogger) {
|
|
17845
|
+
customLogger.error(msg, obj);
|
|
17846
|
+
return;
|
|
17847
|
+
}
|
|
17848
|
+
if (shouldLog("error"))
|
|
17849
|
+
console.error(obj ? `[ERROR] ${msg} ${JSON.stringify(obj)}` : `[ERROR] ${msg}`);
|
|
17850
|
+
},
|
|
17851
|
+
fatal: (msg, obj) => {
|
|
17852
|
+
if (customLogger) {
|
|
17853
|
+
customLogger.fatal(msg, obj);
|
|
17854
|
+
return;
|
|
17855
|
+
}
|
|
17856
|
+
if (shouldLog("fatal"))
|
|
17857
|
+
console.error(obj ? `[FATAL] ${msg} ${JSON.stringify(obj)}` : `[FATAL] ${msg}`);
|
|
17858
|
+
},
|
|
17859
|
+
isLevelEnabled: (level) => {
|
|
17860
|
+
return shouldLog(level);
|
|
17861
|
+
}
|
|
17862
|
+
};
|
|
17863
|
+
|
|
17864
|
+
// ../circle-ir/dist/analysis/per-file-finding-cap.js
|
|
17865
|
+
var DEFAULT_PER_FILE_FINDING_CAP = 1000;
|
|
17866
|
+
var SATURATED_FILE_RULE_ID = "saturated-file";
|
|
17867
|
+
function applyPerFileFindingCap(filePath, findings, cap) {
|
|
17868
|
+
if (cap <= 0)
|
|
17869
|
+
return findings;
|
|
17870
|
+
if (findings.length <= cap)
|
|
17871
|
+
return findings;
|
|
17872
|
+
const suppressedCount = findings.length;
|
|
17873
|
+
const byRule = {};
|
|
17874
|
+
const bySeverity = {};
|
|
17875
|
+
for (const f of findings) {
|
|
17876
|
+
byRule[f.rule_id] = (byRule[f.rule_id] ?? 0) + 1;
|
|
17877
|
+
bySeverity[f.severity] = (bySeverity[f.severity] ?? 0) + 1;
|
|
17878
|
+
}
|
|
17879
|
+
logger.warn(`File ${filePath} produced ${suppressedCount} findings (cap=${cap}); ` + "suppressing individual findings and emitting saturated-file advisory.", { file: filePath, suppressedCount, cap, byRule, bySeverity });
|
|
17880
|
+
const advisory = {
|
|
17881
|
+
id: `${SATURATED_FILE_RULE_ID}-${filePath}-1`,
|
|
17882
|
+
pass: SATURATED_FILE_RULE_ID,
|
|
17883
|
+
category: "maintainability",
|
|
17884
|
+
rule_id: SATURATED_FILE_RULE_ID,
|
|
17885
|
+
severity: "low",
|
|
17886
|
+
level: "note",
|
|
17887
|
+
message: `File suppressed: produced ${suppressedCount} findings, exceeding the ` + `per-file cap of ${cap}. This typically indicates cross-product noise, ` + "mislabelled sink class, or pathological generated code rather than a " + "legitimate detection burst. Individual findings dropped; re-run with " + "`perFileFindingCap: 0` to bypass the cap if the volume is intentional.",
|
|
17888
|
+
file: filePath,
|
|
17889
|
+
line: 1,
|
|
17890
|
+
evidence: {
|
|
17891
|
+
suppressed_count: suppressedCount,
|
|
17892
|
+
cap,
|
|
17893
|
+
by_rule: byRule,
|
|
17894
|
+
by_severity: bySeverity
|
|
17895
|
+
}
|
|
17896
|
+
};
|
|
17897
|
+
return [advisory];
|
|
17898
|
+
}
|
|
17899
|
+
|
|
17900
|
+
// ../circle-ir/dist/analysis/confidence-filter.js
|
|
17901
|
+
function applyConfidenceFilter(findings, includeSpeculative) {
|
|
17902
|
+
if (includeSpeculative)
|
|
17903
|
+
return findings;
|
|
17904
|
+
return findings.filter(isHighConfidence);
|
|
17905
|
+
}
|
|
17906
|
+
function isHighConfidence(finding) {
|
|
17907
|
+
return finding.confidence === undefined || finding.confidence === "high";
|
|
17908
|
+
}
|
|
17909
|
+
|
|
17792
17910
|
// ../circle-ir/dist/languages/registry.js
|
|
17793
17911
|
class DefaultLanguageRegistry {
|
|
17794
17912
|
plugins = new Map;
|
|
@@ -20800,78 +20918,6 @@ function registerBuiltinPlugins() {
|
|
|
20800
20918
|
registerLanguage(new HtmlPlugin);
|
|
20801
20919
|
registerLanguage(new GoPlugin);
|
|
20802
20920
|
}
|
|
20803
|
-
// ../circle-ir/dist/utils/logger.js
|
|
20804
|
-
var LOG_LEVELS = {
|
|
20805
|
-
trace: 0,
|
|
20806
|
-
debug: 1,
|
|
20807
|
-
info: 2,
|
|
20808
|
-
warn: 3,
|
|
20809
|
-
error: 4,
|
|
20810
|
-
fatal: 5,
|
|
20811
|
-
silent: 6
|
|
20812
|
-
};
|
|
20813
|
-
var currentLevel = "silent";
|
|
20814
|
-
var customLogger = null;
|
|
20815
|
-
function shouldLog(level) {
|
|
20816
|
-
return LOG_LEVELS[level] >= LOG_LEVELS[currentLevel];
|
|
20817
|
-
}
|
|
20818
|
-
function setLogLevel(level) {
|
|
20819
|
-
currentLevel = level;
|
|
20820
|
-
}
|
|
20821
|
-
var logger = {
|
|
20822
|
-
trace: (msg, obj) => {
|
|
20823
|
-
if (customLogger) {
|
|
20824
|
-
customLogger.trace(msg, obj);
|
|
20825
|
-
return;
|
|
20826
|
-
}
|
|
20827
|
-
if (shouldLog("trace"))
|
|
20828
|
-
console.debug(obj ? `[TRACE] ${msg} ${JSON.stringify(obj)}` : `[TRACE] ${msg}`);
|
|
20829
|
-
},
|
|
20830
|
-
debug: (msg, obj) => {
|
|
20831
|
-
if (customLogger) {
|
|
20832
|
-
customLogger.debug(msg, obj);
|
|
20833
|
-
return;
|
|
20834
|
-
}
|
|
20835
|
-
if (shouldLog("debug"))
|
|
20836
|
-
console.debug(obj ? `[DEBUG] ${msg} ${JSON.stringify(obj)}` : `[DEBUG] ${msg}`);
|
|
20837
|
-
},
|
|
20838
|
-
info: (msg, obj) => {
|
|
20839
|
-
if (customLogger) {
|
|
20840
|
-
customLogger.info(msg, obj);
|
|
20841
|
-
return;
|
|
20842
|
-
}
|
|
20843
|
-
if (shouldLog("info"))
|
|
20844
|
-
console.error(obj ? `[INFO] ${msg} ${JSON.stringify(obj)}` : `[INFO] ${msg}`);
|
|
20845
|
-
},
|
|
20846
|
-
warn: (msg, obj) => {
|
|
20847
|
-
if (customLogger) {
|
|
20848
|
-
customLogger.warn(msg, obj);
|
|
20849
|
-
return;
|
|
20850
|
-
}
|
|
20851
|
-
if (shouldLog("warn"))
|
|
20852
|
-
console.warn(obj ? `[WARN] ${msg} ${JSON.stringify(obj)}` : `[WARN] ${msg}`);
|
|
20853
|
-
},
|
|
20854
|
-
error: (msg, obj) => {
|
|
20855
|
-
if (customLogger) {
|
|
20856
|
-
customLogger.error(msg, obj);
|
|
20857
|
-
return;
|
|
20858
|
-
}
|
|
20859
|
-
if (shouldLog("error"))
|
|
20860
|
-
console.error(obj ? `[ERROR] ${msg} ${JSON.stringify(obj)}` : `[ERROR] ${msg}`);
|
|
20861
|
-
},
|
|
20862
|
-
fatal: (msg, obj) => {
|
|
20863
|
-
if (customLogger) {
|
|
20864
|
-
customLogger.fatal(msg, obj);
|
|
20865
|
-
return;
|
|
20866
|
-
}
|
|
20867
|
-
if (shouldLog("fatal"))
|
|
20868
|
-
console.error(obj ? `[FATAL] ${msg} ${JSON.stringify(obj)}` : `[FATAL] ${msg}`);
|
|
20869
|
-
},
|
|
20870
|
-
isLevelEnabled: (level) => {
|
|
20871
|
-
return shouldLog(level);
|
|
20872
|
-
}
|
|
20873
|
-
};
|
|
20874
|
-
|
|
20875
20921
|
// ../circle-ir/dist/analysis/passes/cross-file-pass.js
|
|
20876
20922
|
class CrossFilePass {
|
|
20877
20923
|
run(projectGraph, sourceLines, options = {}) {
|
|
@@ -25016,7 +25062,12 @@ var TIER_1_BY_SUPERTYPE = new Map([
|
|
|
25016
25062
|
["HandlerInterceptor", new Set(["preHandle", "postHandle", "afterCompletion"])],
|
|
25017
25063
|
["AsyncHandlerInterceptor", new Set(["preHandle", "postHandle", "afterCompletion", "afterConcurrentHandlingStarted"])],
|
|
25018
25064
|
["CommandLineRunner", new Set(["run"])],
|
|
25019
|
-
["ApplicationRunner", new Set(["run"])]
|
|
25065
|
+
["ApplicationRunner", new Set(["run"])],
|
|
25066
|
+
["SimpleChannelInboundHandler", new Set(["channelRead0", "messageReceived"])],
|
|
25067
|
+
["ChannelInboundHandler", new Set(["channelRead", "channelReadComplete"])],
|
|
25068
|
+
["ChannelInboundHandlerAdapter", new Set(["channelRead", "channelReadComplete"])],
|
|
25069
|
+
["ChannelDuplexHandler", new Set(["channelRead", "channelReadComplete"])],
|
|
25070
|
+
["NettyRequestProcessor", new Set(["process"])]
|
|
25020
25071
|
]);
|
|
25021
25072
|
var TIER_3_CLASS_SUFFIXES = [
|
|
25022
25073
|
"Util",
|
|
@@ -25164,6 +25215,10 @@ function shouldGateInterproceduralParam(sourceType, enclosingMethod, enclosingTy
|
|
|
25164
25215
|
class InterproceduralPass {
|
|
25165
25216
|
name = "interprocedural";
|
|
25166
25217
|
category = "security";
|
|
25218
|
+
enableEntryPointGate;
|
|
25219
|
+
constructor(options) {
|
|
25220
|
+
this.enableEntryPointGate = options?.enableEntryPointGate ?? true;
|
|
25221
|
+
}
|
|
25167
25222
|
run(ctx) {
|
|
25168
25223
|
const { graph } = ctx;
|
|
25169
25224
|
const constProp = ctx.getResult("constant-propagation");
|
|
@@ -25222,7 +25277,7 @@ class InterproceduralPass {
|
|
|
25222
25277
|
continue;
|
|
25223
25278
|
if (source.type === "interprocedural_param" && source.confidence < 0.6)
|
|
25224
25279
|
continue;
|
|
25225
|
-
if (source.type === "interprocedural_param" && source.in_method) {
|
|
25280
|
+
if (this.enableEntryPointGate && source.type === "interprocedural_param" && source.in_method) {
|
|
25226
25281
|
const enclosing = methodNameIndex.get(source.in_method);
|
|
25227
25282
|
if (shouldGateInterproceduralParam(source.type, enclosing?.method, enclosing?.type, { language, types: graph.ir.types })) {
|
|
25228
25283
|
continue;
|
|
@@ -34212,7 +34267,9 @@ async function analyze(code, filePath, language, options = {}) {
|
|
|
34212
34267
|
pipeline.add(new LanguageSourcesPass);
|
|
34213
34268
|
pipeline.add(new SinkFilterPass);
|
|
34214
34269
|
pipeline.add(new TaintPropagationPass);
|
|
34215
|
-
pipeline.add(new InterproceduralPass
|
|
34270
|
+
pipeline.add(new InterproceduralPass({
|
|
34271
|
+
enableEntryPointGate: options.enableEntryPointGate ?? true
|
|
34272
|
+
}));
|
|
34216
34273
|
if (!disabledPasses.has("scan-secrets"))
|
|
34217
34274
|
pipeline.add(new ScanSecretsPass);
|
|
34218
34275
|
if (!disabledPasses.has("dead-code"))
|
|
@@ -34342,6 +34399,8 @@ async function analyze(code, filePath, language, options = {}) {
|
|
|
34342
34399
|
unresolvedItems: unresolved.length
|
|
34343
34400
|
});
|
|
34344
34401
|
emitFindingsInstrumentation(filePath, findings, taint);
|
|
34402
|
+
const verifiedFindings = applyConfidenceFilter(findings, options.includeSpeculative === true);
|
|
34403
|
+
const cappedFindings = applyPerFileFindingCap(filePath, verifiedFindings, options.perFileFindingCap ?? DEFAULT_PER_FILE_FINDING_CAP);
|
|
34345
34404
|
return {
|
|
34346
34405
|
meta,
|
|
34347
34406
|
types,
|
|
@@ -34353,7 +34412,7 @@ async function analyze(code, filePath, language, options = {}) {
|
|
|
34353
34412
|
exports,
|
|
34354
34413
|
unresolved,
|
|
34355
34414
|
enriched,
|
|
34356
|
-
findings:
|
|
34415
|
+
findings: cappedFindings.length > 0 ? cappedFindings : undefined,
|
|
34357
34416
|
metrics: { file: filePath, metrics: metricValues },
|
|
34358
34417
|
runtime_registrations: runtimeRegistrations.length > 0 ? runtimeRegistrations : undefined,
|
|
34359
34418
|
parse_status: parseStatus
|
|
@@ -34520,7 +34579,7 @@ var colors = {
|
|
|
34520
34579
|
};
|
|
34521
34580
|
|
|
34522
34581
|
// src/version.ts
|
|
34523
|
-
var version = "3.
|
|
34582
|
+
var version = "3.95.0";
|
|
34524
34583
|
|
|
34525
34584
|
// src/formatters.ts
|
|
34526
34585
|
var SINK_SEVERITY = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cognium-dev",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.95.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.
|
|
68
|
+
"circle-ir": "^3.95.0"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
71
|
"@types/node": "^25.5.0",
|