cognium-dev 4.9.11 → 4.9.13
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 +252 -45
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -5,7 +5,7 @@ var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
|
5
5
|
// src/cli.ts
|
|
6
6
|
import { readFileSync, existsSync, writeFileSync } from "fs";
|
|
7
7
|
import { stat as stat2, readdir as readdir2 } from "fs/promises";
|
|
8
|
-
import { join as join2, dirname as
|
|
8
|
+
import { join as join2, dirname as dirname3, extname, resolve as resolve2, relative as relative4, basename } from "path";
|
|
9
9
|
import { createRequire as createRequire2 } from "module";
|
|
10
10
|
|
|
11
11
|
// ../../node_modules/web-tree-sitter/web-tree-sitter.js
|
|
@@ -13192,6 +13192,22 @@ var PYTHON_TAINTED_PATTERNS = [
|
|
|
13192
13192
|
{ pattern: /\brequest\.path_params\b/, sourceType: "http_param" },
|
|
13193
13193
|
{ pattern: /\binput\s*\(/, sourceType: "io_input" }
|
|
13194
13194
|
];
|
|
13195
|
+
function dropCSharpObjectCarriedWaypoints(sinks, calls) {
|
|
13196
|
+
const zeroArgCtors = new Set;
|
|
13197
|
+
for (const call of calls) {
|
|
13198
|
+
if (call.is_constructor && call.arguments.length === 0) {
|
|
13199
|
+
zeroArgCtors.add(`${call.location.line}:${call.method_name}`);
|
|
13200
|
+
}
|
|
13201
|
+
}
|
|
13202
|
+
return sinks.filter((sink) => {
|
|
13203
|
+
if (sink.type !== "sql_injection")
|
|
13204
|
+
return true;
|
|
13205
|
+
if (sink.method && zeroArgCtors.has(`${sink.line}:${sink.method}`)) {
|
|
13206
|
+
return false;
|
|
13207
|
+
}
|
|
13208
|
+
return true;
|
|
13209
|
+
});
|
|
13210
|
+
}
|
|
13195
13211
|
function analyzeTaint(calls, types, config = getDefaultConfig(), typeHierarchy, language, code) {
|
|
13196
13212
|
const sourceLines = code !== undefined ? code.split(`
|
|
13197
13213
|
`) : undefined;
|
|
@@ -13199,8 +13215,9 @@ function analyzeTaint(calls, types, config = getDefaultConfig(), typeHierarchy,
|
|
|
13199
13215
|
let sinkPatterns = expandPromisifyAliases(config.sinks, sourceLines, language);
|
|
13200
13216
|
sinkPatterns = expandIndirectEvalAliases(sinkPatterns, sourceLines, language);
|
|
13201
13217
|
const sinks = findSinks(calls, sinkPatterns, typeHierarchy, language, sourceLines, types);
|
|
13218
|
+
const gatedSinks = language === "csharp" ? dropCSharpObjectCarriedWaypoints(sinks, calls) : sinks;
|
|
13202
13219
|
const sanitizers = findSanitizers(calls, types, config.sanitizers, sourceLines);
|
|
13203
|
-
return { sources, sinks, sanitizers };
|
|
13220
|
+
return { sources, sinks: gatedSinks, sanitizers };
|
|
13204
13221
|
}
|
|
13205
13222
|
function sinkPatternAppliesTo(pattern, language) {
|
|
13206
13223
|
if (language === undefined)
|
|
@@ -13485,7 +13502,7 @@ function findSources(calls, types, patterns, sourceLines, language) {
|
|
|
13485
13502
|
}
|
|
13486
13503
|
const sourceMap = new Map;
|
|
13487
13504
|
for (const source of sources) {
|
|
13488
|
-
const key = `${source.line}:${source.type}`;
|
|
13505
|
+
const key = source.type === "interprocedural_param" && source.variable ? `${source.line}:${source.type}:${source.variable}` : `${source.line}:${source.type}`;
|
|
13489
13506
|
const existing = sourceMap.get(key);
|
|
13490
13507
|
if (!existing || source.confidence > existing.confidence) {
|
|
13491
13508
|
sourceMap.set(key, source);
|
|
@@ -14163,6 +14180,19 @@ var CWE_78_RECEIVER_ALLOWLIST = new Set([
|
|
|
14163
14180
|
"ProcessExecutor",
|
|
14164
14181
|
"RuntimeUtil"
|
|
14165
14182
|
]);
|
|
14183
|
+
function isRegexReceiver(receiver, sourceLines) {
|
|
14184
|
+
const r = (receiver ?? "").trim();
|
|
14185
|
+
if (r.length === 0)
|
|
14186
|
+
return false;
|
|
14187
|
+
if (r.startsWith("/") && /\/[a-z]*$/.test(r))
|
|
14188
|
+
return true;
|
|
14189
|
+
if (/^(?:new\s+)?RegExp\s*\(/.test(r))
|
|
14190
|
+
return true;
|
|
14191
|
+
if (!/^[A-Za-z_$][\w$]*$/.test(r) || !sourceLines)
|
|
14192
|
+
return false;
|
|
14193
|
+
const decl = new RegExp(`(?:const|let|var)\\s+${escapeRe(r)}\\s*=\\s*(?:/|(?:new\\s+)?RegExp\\s*\\()`);
|
|
14194
|
+
return sourceLines.some((l) => decl.test(l));
|
|
14195
|
+
}
|
|
14166
14196
|
function isFunctionCallbackArgument(arg) {
|
|
14167
14197
|
if (arg.literal !== null && arg.literal !== undefined)
|
|
14168
14198
|
return false;
|
|
@@ -14370,6 +14400,12 @@ function findSinks(calls, patterns, typeHierarchy, language, sourceLines, types)
|
|
|
14370
14400
|
continue;
|
|
14371
14401
|
}
|
|
14372
14402
|
}
|
|
14403
|
+
if (pattern.type === "command_injection" && call.method_name === "exec" && (language === "javascript" || language === "typescript") && isRegexReceiver(call.receiver, sourceLines)) {
|
|
14404
|
+
continue;
|
|
14405
|
+
}
|
|
14406
|
+
if (pattern.type === "code_injection" && language === "python" && call.method_name === "compile" && call.receiver && call.receiver !== "builtins") {
|
|
14407
|
+
continue;
|
|
14408
|
+
}
|
|
14373
14409
|
if (isSafeGoJsonUnmarshalCall(call, pattern, language, sourceLines)) {
|
|
14374
14410
|
continue;
|
|
14375
14411
|
}
|
|
@@ -17887,6 +17923,9 @@ function findInitialTaint(sources, callsByLine, defsByLine) {
|
|
|
17887
17923
|
for (const source of sources) {
|
|
17888
17924
|
const defsOnLine = defsByLine.get(source.line) ?? [];
|
|
17889
17925
|
for (const def of defsOnLine) {
|
|
17926
|
+
if (source.type === "interprocedural_param" && source.variable && def.kind === "param" && def.variable !== source.variable) {
|
|
17927
|
+
continue;
|
|
17928
|
+
}
|
|
17890
17929
|
tainted.push({
|
|
17891
17930
|
variable: def.variable,
|
|
17892
17931
|
defId: def.id,
|
|
@@ -35817,7 +35856,7 @@ class TaintPropagationPass {
|
|
|
35817
35856
|
for (const f of paramFlows) {
|
|
35818
35857
|
pushIfNew(f);
|
|
35819
35858
|
}
|
|
35820
|
-
const exprScanFlows = detectExpressionScanFlows(calls, sources, sinks, sanitizers, constProp.unreachableLines, constProp.tainted, ctx.code, ctx.language) ?? [];
|
|
35859
|
+
const exprScanFlows = detectExpressionScanFlows(calls, sources, sinks, sanitizers, constProp.unreachableLines, constProp.tainted, ctx.code, ctx.language, types) ?? [];
|
|
35821
35860
|
for (const f of exprScanFlows) {
|
|
35822
35861
|
if (flowKeys.has(flowKey(f)))
|
|
35823
35862
|
continue;
|
|
@@ -35981,6 +36020,35 @@ class TaintPropagationPass {
|
|
|
35981
36020
|
return bestByKey.get(key) === f;
|
|
35982
36021
|
});
|
|
35983
36022
|
}
|
|
36023
|
+
if (ctx.language === "csharp" && finalFlows.length > 1) {
|
|
36024
|
+
const CSHARP_ADO_EXECUTE = /^Execute(?:Reader|NonQuery|Scalar)(?:Async)?$/;
|
|
36025
|
+
const commandTextReceiverByLine = new Map;
|
|
36026
|
+
const execLinesByReceiver = new Map;
|
|
36027
|
+
for (const call of calls) {
|
|
36028
|
+
const receiver = (call.receiver ?? "").trim();
|
|
36029
|
+
if (!receiver)
|
|
36030
|
+
continue;
|
|
36031
|
+
if (call.method_name === "CommandText") {
|
|
36032
|
+
commandTextReceiverByLine.set(call.location.line, receiver);
|
|
36033
|
+
} else if (CSHARP_ADO_EXECUTE.test(call.method_name)) {
|
|
36034
|
+
const lines = execLinesByReceiver.get(receiver) ?? [];
|
|
36035
|
+
lines.push(call.location.line);
|
|
36036
|
+
execLinesByReceiver.set(receiver, lines);
|
|
36037
|
+
}
|
|
36038
|
+
}
|
|
36039
|
+
if (commandTextReceiverByLine.size > 0) {
|
|
36040
|
+
const reportedSqlSinkLines = new Set(finalFlows.filter((f) => f.sink_type === "sql_injection").map((f) => f.sink_line));
|
|
36041
|
+
finalFlows = finalFlows.filter((f) => {
|
|
36042
|
+
if (f.sink_type !== "sql_injection")
|
|
36043
|
+
return true;
|
|
36044
|
+
const receiver = commandTextReceiverByLine.get(f.sink_line);
|
|
36045
|
+
if (receiver === undefined)
|
|
36046
|
+
return true;
|
|
36047
|
+
const execLines = execLinesByReceiver.get(receiver) ?? [];
|
|
36048
|
+
return !execLines.some((line) => line > f.sink_line && reportedSqlSinkLines.has(line));
|
|
36049
|
+
});
|
|
36050
|
+
}
|
|
36051
|
+
}
|
|
35984
36052
|
return { flows: finalFlows };
|
|
35985
36053
|
}
|
|
35986
36054
|
}
|
|
@@ -36447,7 +36515,7 @@ function isReassignedToLiteralBetween(code, variable, srcLine, sinkLine) {
|
|
|
36447
36515
|
}
|
|
36448
36516
|
return false;
|
|
36449
36517
|
}
|
|
36450
|
-
function detectExpressionScanFlows(calls, sources, sinks, sanitizers, unreachableLines, tainted, code, language) {
|
|
36518
|
+
function detectExpressionScanFlows(calls, sources, sinks, sanitizers, unreachableLines, tainted, code, language, types) {
|
|
36451
36519
|
const flows = [];
|
|
36452
36520
|
const sourcesWithVar = sources.filter((s) => typeof s.variable === "string" && s.variable.length > 0);
|
|
36453
36521
|
const aliasSanitizedFor = new Map;
|
|
@@ -36730,13 +36798,37 @@ function detectExpressionScanFlows(calls, sources, sinks, sanitizers, unreachabl
|
|
|
36730
36798
|
if (s.line < anchor.line)
|
|
36731
36799
|
anchor = s;
|
|
36732
36800
|
}
|
|
36801
|
+
const methodAt = (line) => {
|
|
36802
|
+
for (const t of types ?? []) {
|
|
36803
|
+
for (const m of t.methods) {
|
|
36804
|
+
if (line >= m.start_line && line <= m.end_line)
|
|
36805
|
+
return m.name;
|
|
36806
|
+
}
|
|
36807
|
+
}
|
|
36808
|
+
return null;
|
|
36809
|
+
};
|
|
36733
36810
|
const existingVars = new Set(sourcesWithVar.map((s) => s.variable));
|
|
36734
|
-
for (const [varName] of derived) {
|
|
36811
|
+
for (const [varName, derivedLine] of derived) {
|
|
36735
36812
|
if (!varName || existingVars.has(varName))
|
|
36736
36813
|
continue;
|
|
36814
|
+
const owner = methodAt(derivedLine);
|
|
36815
|
+
let scopedAnchor = anchor;
|
|
36816
|
+
if (owner) {
|
|
36817
|
+
let best;
|
|
36818
|
+
for (const s of sourcesWithVar) {
|
|
36819
|
+
const sOwner = s.in_method ?? methodAt(s.line);
|
|
36820
|
+
if (sOwner !== owner)
|
|
36821
|
+
continue;
|
|
36822
|
+
if (!best || s.line < best.line)
|
|
36823
|
+
best = s;
|
|
36824
|
+
}
|
|
36825
|
+
if (best)
|
|
36826
|
+
scopedAnchor = best;
|
|
36827
|
+
}
|
|
36737
36828
|
sourcesWithVar.push({
|
|
36738
|
-
...
|
|
36739
|
-
variable: varName
|
|
36829
|
+
...scopedAnchor,
|
|
36830
|
+
variable: varName,
|
|
36831
|
+
...owner ? { in_method: owner } : {}
|
|
36740
36832
|
});
|
|
36741
36833
|
existingVars.add(varName);
|
|
36742
36834
|
}
|
|
@@ -48298,14 +48390,14 @@ function toSpdx(deps, meta = {}) {
|
|
|
48298
48390
|
relationships
|
|
48299
48391
|
};
|
|
48300
48392
|
}
|
|
48301
|
-
//
|
|
48302
|
-
import { relative as
|
|
48393
|
+
// ../project-profile-detect/dist/index.js
|
|
48394
|
+
import { relative as relative3 } from "path";
|
|
48303
48395
|
|
|
48304
|
-
//
|
|
48396
|
+
// ../project-profile-detect/dist/walk.js
|
|
48305
48397
|
import { readdir, readFile, stat } from "fs/promises";
|
|
48306
|
-
import { join, relative } from "path";
|
|
48398
|
+
import { join, relative as relative2 } from "path";
|
|
48307
48399
|
|
|
48308
|
-
//
|
|
48400
|
+
// ../project-profile-detect/dist/maven-parse.js
|
|
48309
48401
|
var TAG = (name2) => new RegExp(`<${name2}\\b[^>]*>([\\s\\S]*?)<\\/${name2}>`, "i");
|
|
48310
48402
|
var ALL_TAGS = (name2) => new RegExp(`<${name2}\\b[^>]*>([\\s\\S]*?)<\\/${name2}>`, "gi");
|
|
48311
48403
|
function firstTag(xml, name2) {
|
|
@@ -48329,7 +48421,12 @@ var MAVEN_PLUGIN_MAP = {
|
|
|
48329
48421
|
"exec-maven-plugin": "application",
|
|
48330
48422
|
"maven-assembly-plugin": "application"
|
|
48331
48423
|
};
|
|
48424
|
+
var MAVEN_PUBLISH_PLUGIN_URLS = {
|
|
48425
|
+
"central-publishing-maven-plugin": "https://central.sonatype.com/",
|
|
48426
|
+
"nexus-staging-maven-plugin": "https://oss.sonatype.org/"
|
|
48427
|
+
};
|
|
48332
48428
|
function parseMavenPom(xml, moduleRoot, buildFile, directorySignals) {
|
|
48429
|
+
const parentRef = extractParentRef(xml);
|
|
48333
48430
|
const stripped = xml.replace(/<parent\b[\s\S]*?<\/parent>/i, "");
|
|
48334
48431
|
const groupId = firstTag(stripped, "groupId");
|
|
48335
48432
|
const artifactId = firstTag(stripped, "artifactId");
|
|
@@ -48338,10 +48435,15 @@ function parseMavenPom(xml, moduleRoot, buildFile, directorySignals) {
|
|
|
48338
48435
|
const buildBlock = firstTag(xml, "build") ?? "";
|
|
48339
48436
|
const pluginBlocks = allTags(buildBlock, "plugin");
|
|
48340
48437
|
const plugins = new Set;
|
|
48438
|
+
const publishUrls = new Set;
|
|
48341
48439
|
for (const p of pluginBlocks) {
|
|
48342
48440
|
const aid = firstTag(p, "artifactId");
|
|
48343
|
-
if (aid
|
|
48441
|
+
if (!aid)
|
|
48442
|
+
continue;
|
|
48443
|
+
if (MAVEN_PLUGIN_MAP[aid])
|
|
48344
48444
|
plugins.add(MAVEN_PLUGIN_MAP[aid]);
|
|
48445
|
+
if (MAVEN_PUBLISH_PLUGIN_URLS[aid])
|
|
48446
|
+
publishUrls.add(MAVEN_PUBLISH_PLUGIN_URLS[aid]);
|
|
48345
48447
|
}
|
|
48346
48448
|
if (/<parent\b[\s\S]*?<artifactId>\s*spring-boot-starter-parent\s*<\/artifactId>/i.test(xml)) {
|
|
48347
48449
|
plugins.add("spring-boot");
|
|
@@ -48354,7 +48456,8 @@ function parseMavenPom(xml, moduleRoot, buildFile, directorySignals) {
|
|
|
48354
48456
|
plugins.add("maven-plugin");
|
|
48355
48457
|
const distBlock = firstTag(xml, "distributionManagement") ?? "";
|
|
48356
48458
|
const urls = [
|
|
48357
|
-
...allTags(distBlock, "url")
|
|
48459
|
+
...allTags(distBlock, "url"),
|
|
48460
|
+
...publishUrls
|
|
48358
48461
|
].map((u) => u.trim()).filter(Boolean);
|
|
48359
48462
|
const signals = {
|
|
48360
48463
|
...directorySignals,
|
|
@@ -48369,11 +48472,36 @@ function parseMavenPom(xml, moduleRoot, buildFile, directorySignals) {
|
|
|
48369
48472
|
groupId,
|
|
48370
48473
|
artifactId,
|
|
48371
48474
|
version,
|
|
48372
|
-
signals
|
|
48475
|
+
signals,
|
|
48476
|
+
parentRef
|
|
48373
48477
|
};
|
|
48374
48478
|
}
|
|
48479
|
+
function extractParentRef(xml) {
|
|
48480
|
+
const block = TAG("parent").exec(xml);
|
|
48481
|
+
if (!block)
|
|
48482
|
+
return;
|
|
48483
|
+
const inner = block[1];
|
|
48484
|
+
const groupId = firstTag(inner, "groupId");
|
|
48485
|
+
const artifactId = firstTag(inner, "artifactId");
|
|
48486
|
+
const version = firstTag(inner, "version");
|
|
48487
|
+
let relativePath;
|
|
48488
|
+
let emptyRelativePath = false;
|
|
48489
|
+
const selfClosing = /<relativePath\b[^>]*\/\s*>/i.test(inner);
|
|
48490
|
+
if (selfClosing) {
|
|
48491
|
+
emptyRelativePath = true;
|
|
48492
|
+
} else {
|
|
48493
|
+
const rp = firstTag(inner, "relativePath");
|
|
48494
|
+
if (rp !== undefined) {
|
|
48495
|
+
if (rp.length === 0)
|
|
48496
|
+
emptyRelativePath = true;
|
|
48497
|
+
else
|
|
48498
|
+
relativePath = rp;
|
|
48499
|
+
}
|
|
48500
|
+
}
|
|
48501
|
+
return { groupId, artifactId, version, relativePath, emptyRelativePath };
|
|
48502
|
+
}
|
|
48375
48503
|
|
|
48376
|
-
//
|
|
48504
|
+
// ../project-profile-detect/dist/gradle-parse.js
|
|
48377
48505
|
var GRADLE_PLUGIN_MAP = {
|
|
48378
48506
|
"org.springframework.boot": "spring-boot",
|
|
48379
48507
|
"io.spring.dependency-management": "spring-boot",
|
|
@@ -48438,7 +48566,81 @@ function parseGradleBuild(text, moduleRoot, buildFile, buildSystem, directorySig
|
|
|
48438
48566
|
};
|
|
48439
48567
|
}
|
|
48440
48568
|
|
|
48441
|
-
//
|
|
48569
|
+
// ../project-profile-detect/dist/maven-inherit.js
|
|
48570
|
+
import { dirname as dirname2, isAbsolute, normalize, relative, resolve } from "path";
|
|
48571
|
+
var MAX_DEPTH = 6;
|
|
48572
|
+
var DEFAULT_RELATIVE_PATH = "../pom.xml";
|
|
48573
|
+
function mergeMavenInheritance(modules, scanRoot) {
|
|
48574
|
+
const normalizedScanRoot = normalize(scanRoot);
|
|
48575
|
+
const byBuildFile = new Map;
|
|
48576
|
+
for (const m of modules) {
|
|
48577
|
+
if (m.buildSystem === "maven") {
|
|
48578
|
+
byBuildFile.set(normalize(m.buildFile), m);
|
|
48579
|
+
}
|
|
48580
|
+
}
|
|
48581
|
+
const ownSignals = new Map;
|
|
48582
|
+
for (const [buildFile, m] of byBuildFile) {
|
|
48583
|
+
ownSignals.set(buildFile, {
|
|
48584
|
+
urls: [...m.signals.distributionUrls],
|
|
48585
|
+
plugins: [...m.signals.plugins]
|
|
48586
|
+
});
|
|
48587
|
+
}
|
|
48588
|
+
for (const child of modules) {
|
|
48589
|
+
if (child.buildSystem !== "maven")
|
|
48590
|
+
continue;
|
|
48591
|
+
if (!child.parentRef)
|
|
48592
|
+
continue;
|
|
48593
|
+
const inheritedUrls = new Set;
|
|
48594
|
+
const inheritedPlugins = new Set;
|
|
48595
|
+
walkParents(child, byBuildFile, ownSignals, normalizedScanRoot, inheritedUrls, inheritedPlugins);
|
|
48596
|
+
if (inheritedUrls.size === 0 && inheritedPlugins.size === 0)
|
|
48597
|
+
continue;
|
|
48598
|
+
const existingUrls = new Set(child.signals.distributionUrls);
|
|
48599
|
+
for (const u of inheritedUrls) {
|
|
48600
|
+
if (!existingUrls.has(u))
|
|
48601
|
+
child.signals.distributionUrls.push(u);
|
|
48602
|
+
}
|
|
48603
|
+
const existingPlugins = new Set(child.signals.plugins);
|
|
48604
|
+
for (const p of inheritedPlugins) {
|
|
48605
|
+
if (!existingPlugins.has(p))
|
|
48606
|
+
child.signals.plugins.push(p);
|
|
48607
|
+
}
|
|
48608
|
+
}
|
|
48609
|
+
}
|
|
48610
|
+
function walkParents(start2, byBuildFile, ownSignals, scanRoot, outUrls, outPlugins) {
|
|
48611
|
+
const visited = new Set([normalize(start2.buildFile)]);
|
|
48612
|
+
let current = start2;
|
|
48613
|
+
for (let depth = 0;depth < MAX_DEPTH; depth++) {
|
|
48614
|
+
const ref = current.parentRef;
|
|
48615
|
+
if (!ref)
|
|
48616
|
+
return;
|
|
48617
|
+
if (ref.emptyRelativePath)
|
|
48618
|
+
return;
|
|
48619
|
+
const childDir = dirname2(current.buildFile);
|
|
48620
|
+
const rel = ref.relativePath ?? DEFAULT_RELATIVE_PATH;
|
|
48621
|
+
const candidateAbs = normalize(isAbsolute(rel) ? rel : resolve(childDir, rel));
|
|
48622
|
+
const parentBuildFile = candidateAbs.endsWith("pom.xml") ? candidateAbs : normalize(resolve(candidateAbs, "pom.xml"));
|
|
48623
|
+
const relToRoot = relative(scanRoot, parentBuildFile);
|
|
48624
|
+
if (relToRoot.startsWith("..") || isAbsolute(relToRoot))
|
|
48625
|
+
return;
|
|
48626
|
+
if (visited.has(parentBuildFile))
|
|
48627
|
+
return;
|
|
48628
|
+
visited.add(parentBuildFile);
|
|
48629
|
+
const parent = byBuildFile.get(parentBuildFile);
|
|
48630
|
+
if (!parent)
|
|
48631
|
+
return;
|
|
48632
|
+
const parentOwn = ownSignals.get(parentBuildFile);
|
|
48633
|
+
if (parentOwn) {
|
|
48634
|
+
for (const u of parentOwn.urls)
|
|
48635
|
+
outUrls.add(u);
|
|
48636
|
+
for (const p of parentOwn.plugins)
|
|
48637
|
+
outPlugins.add(p);
|
|
48638
|
+
}
|
|
48639
|
+
current = parent;
|
|
48640
|
+
}
|
|
48641
|
+
}
|
|
48642
|
+
|
|
48643
|
+
// ../project-profile-detect/dist/walk.js
|
|
48442
48644
|
var BUILD_FILES = ["pom.xml", "build.gradle", "build.gradle.kts"];
|
|
48443
48645
|
var SKIP_DIRS = new Set([
|
|
48444
48646
|
"node_modules",
|
|
@@ -48458,6 +48660,7 @@ var SKIP_DIRS = new Set([
|
|
|
48458
48660
|
async function discoverBuildModules(scanRoot) {
|
|
48459
48661
|
const modules = [];
|
|
48460
48662
|
await walk(scanRoot, modules);
|
|
48663
|
+
mergeMavenInheritance(modules, scanRoot);
|
|
48461
48664
|
return modules;
|
|
48462
48665
|
}
|
|
48463
48666
|
async function walk(dir, out2) {
|
|
@@ -48599,7 +48802,7 @@ function ownerOf(file, modules) {
|
|
|
48599
48802
|
return best;
|
|
48600
48803
|
}
|
|
48601
48804
|
|
|
48602
|
-
//
|
|
48805
|
+
// ../project-profile-detect/dist/publication-detect.js
|
|
48603
48806
|
var PUBLIC_REGISTRY_HOSTS = new Set([
|
|
48604
48807
|
"repo.maven.apache.org",
|
|
48605
48808
|
"repo1.maven.org",
|
|
@@ -48624,7 +48827,7 @@ function isPubliclyPublished(urls) {
|
|
|
48624
48827
|
return false;
|
|
48625
48828
|
}
|
|
48626
48829
|
|
|
48627
|
-
//
|
|
48830
|
+
// ../project-profile-detect/dist/shape-resolve.js
|
|
48628
48831
|
function resolveShape(mod) {
|
|
48629
48832
|
const sig = mod.signals;
|
|
48630
48833
|
const has = (tag) => sig.plugins.includes(tag);
|
|
@@ -48665,11 +48868,15 @@ function resolveShape(mod) {
|
|
|
48665
48868
|
reasons.push(...libSignals, "no public-registry distribution (internal helper)");
|
|
48666
48869
|
return { shape: "application", reasons };
|
|
48667
48870
|
}
|
|
48871
|
+
if (isPubliclyPublished(sig.distributionUrls)) {
|
|
48872
|
+
reasons.push("public-registry distribution", "no application/server/plugin signals → implicit library");
|
|
48873
|
+
return { shape: "library", reasons };
|
|
48874
|
+
}
|
|
48668
48875
|
reasons.push("no shape signals");
|
|
48669
48876
|
return { shape: "unknown", reasons };
|
|
48670
48877
|
}
|
|
48671
48878
|
|
|
48672
|
-
//
|
|
48879
|
+
// ../project-profile-detect/dist/env-resolve.js
|
|
48673
48880
|
var TEST_RE = /(?:^|\/)tests?\//;
|
|
48674
48881
|
var SAMPLE_RE = /(?:^|\/)(?:samples?|examples?|demos?|fixtures?)\//;
|
|
48675
48882
|
var BENCHMARK_RE = /(?:^|\/)benchmarks?\//;
|
|
@@ -48687,7 +48894,7 @@ function resolveEnv(absoluteFile) {
|
|
|
48687
48894
|
return "dev";
|
|
48688
48895
|
}
|
|
48689
48896
|
|
|
48690
|
-
//
|
|
48897
|
+
// ../project-profile-detect/dist/overrides.js
|
|
48691
48898
|
function compileGlob(glob) {
|
|
48692
48899
|
let re = "";
|
|
48693
48900
|
let i2 = 0;
|
|
@@ -48734,7 +48941,7 @@ function applyOverrides(relativePath, compiled) {
|
|
|
48734
48941
|
return;
|
|
48735
48942
|
}
|
|
48736
48943
|
|
|
48737
|
-
//
|
|
48944
|
+
// ../project-profile-detect/dist/index.js
|
|
48738
48945
|
async function detectProjectProfiles(scanRoot, options = {}) {
|
|
48739
48946
|
const modules = await discoverBuildModules(scanRoot);
|
|
48740
48947
|
const files = await enumerateScanFiles(scanRoot);
|
|
@@ -48752,7 +48959,7 @@ async function detectProjectProfiles(scanRoot, options = {}) {
|
|
|
48752
48959
|
const profileByFile = new Map;
|
|
48753
48960
|
const unknownFiles = [];
|
|
48754
48961
|
for (const file of files) {
|
|
48755
|
-
const rel =
|
|
48962
|
+
const rel = relative3(scanRoot, file);
|
|
48756
48963
|
const ov = applyOverrides(rel, compiledOverrides);
|
|
48757
48964
|
if (ov) {
|
|
48758
48965
|
profileByFile.set(file, ov.profile);
|
|
@@ -48804,7 +49011,7 @@ var colors = {
|
|
|
48804
49011
|
};
|
|
48805
49012
|
|
|
48806
49013
|
// src/version.ts
|
|
48807
|
-
var version = "4.9.
|
|
49014
|
+
var version = "4.9.13";
|
|
48808
49015
|
|
|
48809
49016
|
// src/formatters.ts
|
|
48810
49017
|
var LIBRARY_API_SURFACE_TAG2 = "library-api-surface:caller-responsibility";
|
|
@@ -49357,8 +49564,8 @@ function generateSarifResults(results, crossFileData) {
|
|
|
49357
49564
|
|
|
49358
49565
|
// src/build-info.ts
|
|
49359
49566
|
var buildInfo = {
|
|
49360
|
-
gitSha: "
|
|
49361
|
-
builtAt: "2026-09-
|
|
49567
|
+
gitSha: "c7e3f20",
|
|
49568
|
+
builtAt: "2026-09-11T05:41:41.484Z"
|
|
49362
49569
|
};
|
|
49363
49570
|
|
|
49364
49571
|
// src/utils/args.ts
|
|
@@ -49646,7 +49853,7 @@ function applySuppressionsToResults(results, suppressions, basePath) {
|
|
|
49646
49853
|
if (suppressions.length === 0)
|
|
49647
49854
|
return results;
|
|
49648
49855
|
return results.map((result) => {
|
|
49649
|
-
const relativeFile =
|
|
49856
|
+
const relativeFile = relative4(basePath, result.file) || result.file;
|
|
49650
49857
|
const filteredVulns = result.vulnerabilities.filter((vuln) => {
|
|
49651
49858
|
for (const supp of suppressions) {
|
|
49652
49859
|
if (supp.pass !== vuln.type)
|
|
@@ -49752,7 +49959,7 @@ async function collectFiles(targetPath, options = {}) {
|
|
|
49752
49959
|
return files;
|
|
49753
49960
|
}
|
|
49754
49961
|
if (fileMatchesLanguage(targetPath, language)) {
|
|
49755
|
-
const relativePath = basePath ?
|
|
49962
|
+
const relativePath = basePath ? relative4(basePath, targetPath) : targetPath;
|
|
49756
49963
|
if (includePatterns && includePatterns.length > 0) {
|
|
49757
49964
|
if (!matchesAnyPattern(relativePath, includePatterns)) {
|
|
49758
49965
|
return files;
|
|
@@ -49771,7 +49978,7 @@ async function collectFiles(targetPath, options = {}) {
|
|
|
49771
49978
|
if (excludeTests && /^(test|tests|__tests__|spec|__mocks__)$/i.test(entry.name))
|
|
49772
49979
|
continue;
|
|
49773
49980
|
const fullPath = join2(targetPath, entry.name);
|
|
49774
|
-
const relativePath = basePath ?
|
|
49981
|
+
const relativePath = basePath ? relative4(basePath, fullPath) : fullPath;
|
|
49775
49982
|
if (excludePatterns && entry.isDirectory()) {
|
|
49776
49983
|
const dirPattern = relativePath + "/";
|
|
49777
49984
|
if (excludePatterns.some((p) => matchesGlob(dirPattern, p) || matchesGlob(relativePath, p))) {
|
|
@@ -49869,14 +50076,14 @@ async function scanProject(files, language, analyzeOpts, crossFileBudgetMs) {
|
|
|
49869
50076
|
async function initWasm(spin) {
|
|
49870
50077
|
const isStandalone = import.meta.url.includes("/$bunfs/");
|
|
49871
50078
|
if (isStandalone) {
|
|
49872
|
-
const { dirname:
|
|
49873
|
-
const binaryDir =
|
|
50079
|
+
const { dirname: dirname4, join: join3 } = await import("path");
|
|
50080
|
+
const binaryDir = dirname4(process.execPath);
|
|
49874
50081
|
const cwd = process.cwd();
|
|
49875
50082
|
let scriptDir = null;
|
|
49876
50083
|
if (!import.meta.url.includes("/$bunfs/")) {
|
|
49877
50084
|
try {
|
|
49878
50085
|
const { fileURLToPath } = await import("url");
|
|
49879
|
-
scriptDir =
|
|
50086
|
+
scriptDir = dirname4(fileURLToPath(import.meta.url));
|
|
49880
50087
|
} catch {}
|
|
49881
50088
|
}
|
|
49882
50089
|
const wasmLocations = [
|
|
@@ -49931,7 +50138,7 @@ Please ensure the wasm/ directory is located next to the binary or in your curre
|
|
|
49931
50138
|
} else {
|
|
49932
50139
|
const require2 = createRequire2(import.meta.url);
|
|
49933
50140
|
const circleIrPkg = require2.resolve("circle-ir/package.json");
|
|
49934
|
-
const wasmBasePath = join2(
|
|
50141
|
+
const wasmBasePath = join2(dirname3(circleIrPkg), "dist", "wasm") + "/";
|
|
49935
50142
|
await initAnalyzer({
|
|
49936
50143
|
wasmPath: wasmBasePath + "web-tree-sitter.wasm",
|
|
49937
50144
|
languagePaths: {
|
|
@@ -49962,7 +50169,7 @@ function buildProfileSummary(scanRoot, modules, resolvedProfiles) {
|
|
|
49962
50169
|
return {
|
|
49963
50170
|
scanRoot,
|
|
49964
50171
|
modules: modules.map((m) => ({
|
|
49965
|
-
root:
|
|
50172
|
+
root: relative4(scanRoot, m.module.root) || ".",
|
|
49966
50173
|
profile: m.profile,
|
|
49967
50174
|
reasons: m.reasons,
|
|
49968
50175
|
buildSystem: m.module.buildSystem
|
|
@@ -49991,9 +50198,9 @@ function printProfileExplain(scanRoot, detection) {
|
|
|
49991
50198
|
out2.push(" (no pom.xml, build.gradle, or build.gradle.kts found)");
|
|
49992
50199
|
} else {
|
|
49993
50200
|
for (const r of detection.modules) {
|
|
49994
|
-
const rel =
|
|
50201
|
+
const rel = relative4(scanRoot, r.module.root) || ".";
|
|
49995
50202
|
out2.push(` ${colors.cyan(rel || ".")} → ${colors.bold(r.profile)}`);
|
|
49996
|
-
out2.push(` build: ${r.module.buildSystem} (${
|
|
50203
|
+
out2.push(` build: ${r.module.buildSystem} (${relative4(scanRoot, r.module.buildFile)})`);
|
|
49997
50204
|
if (r.module.artifactId) {
|
|
49998
50205
|
out2.push(` coords: ${r.module.groupId ?? "?"}:${r.module.artifactId}:${r.module.version ?? "?"}`);
|
|
49999
50206
|
}
|
|
@@ -50038,7 +50245,7 @@ async function runScan(targetPath, options) {
|
|
|
50038
50245
|
await initWasm(spin);
|
|
50039
50246
|
if (spin)
|
|
50040
50247
|
spin.text = "Collecting files...";
|
|
50041
|
-
const absPath =
|
|
50248
|
+
const absPath = resolve2(targetPath);
|
|
50042
50249
|
if (!existsSync(absPath)) {
|
|
50043
50250
|
if (spin)
|
|
50044
50251
|
spin.fail(`Path not found: ${absPath}`);
|
|
@@ -50102,7 +50309,7 @@ async function runScan(targetPath, options) {
|
|
|
50102
50309
|
results = [];
|
|
50103
50310
|
let processed = 0;
|
|
50104
50311
|
const formatCurrentFile = (file) => {
|
|
50105
|
-
const rel =
|
|
50312
|
+
const rel = relative4(absPath, file) || file;
|
|
50106
50313
|
return rel.length > 80 ? `...${rel.slice(-77)}` : rel;
|
|
50107
50314
|
};
|
|
50108
50315
|
const concurrency = options.threads;
|
|
@@ -50278,7 +50485,7 @@ async function runMetrics(targetPath, options) {
|
|
|
50278
50485
|
await initWasm(spin);
|
|
50279
50486
|
if (spin)
|
|
50280
50487
|
spin.text = "Collecting files...";
|
|
50281
|
-
const absPath =
|
|
50488
|
+
const absPath = resolve2(targetPath);
|
|
50282
50489
|
if (!existsSync(absPath)) {
|
|
50283
50490
|
if (spin)
|
|
50284
50491
|
spin.fail(`Path not found: ${absPath}`);
|
|
@@ -50306,7 +50513,7 @@ async function runMetrics(targetPath, options) {
|
|
|
50306
50513
|
continue;
|
|
50307
50514
|
}
|
|
50308
50515
|
if (spin) {
|
|
50309
|
-
const rel =
|
|
50516
|
+
const rel = relative4(absPath, file) || file;
|
|
50310
50517
|
const maxLen = 80;
|
|
50311
50518
|
const label = rel.length > maxLen ? `...${rel.slice(-(maxLen - 3))}` : rel;
|
|
50312
50519
|
spin.text = `Analyzing ${label}... (${processed}/${totalFiles})`;
|
|
@@ -50351,7 +50558,7 @@ async function runMetrics(targetPath, options) {
|
|
|
50351
50558
|
} else {
|
|
50352
50559
|
const lines = [];
|
|
50353
50560
|
for (const fm of filtered) {
|
|
50354
|
-
const rel =
|
|
50561
|
+
const rel = relative4(absPath, fm.file) || fm.file;
|
|
50355
50562
|
lines.push(rel);
|
|
50356
50563
|
const byCategory = new Map;
|
|
50357
50564
|
for (const m of fm.metrics) {
|
|
@@ -50579,7 +50786,7 @@ async function collectManifestFiles(targetPath) {
|
|
|
50579
50786
|
return found;
|
|
50580
50787
|
}
|
|
50581
50788
|
async function runSbom(targetPath, options) {
|
|
50582
|
-
const absPath =
|
|
50789
|
+
const absPath = resolve2(targetPath);
|
|
50583
50790
|
if (!existsSync(absPath)) {
|
|
50584
50791
|
console.error(colors.red(`Error: path not found: ${targetPath}`));
|
|
50585
50792
|
process.exit(2);
|
|
@@ -50593,9 +50800,9 @@ async function runSbom(targetPath, options) {
|
|
|
50593
50800
|
for (const m of manifests) {
|
|
50594
50801
|
const superseded = SBOM_SUPERSEDES[basename(m)];
|
|
50595
50802
|
if (superseded)
|
|
50596
|
-
supersededInDir.add(`${
|
|
50803
|
+
supersededInDir.add(`${dirname3(m)}\x00${superseded}`);
|
|
50597
50804
|
}
|
|
50598
|
-
const effective = manifests.filter((m) => !supersededInDir.has(`${
|
|
50805
|
+
const effective = manifests.filter((m) => !supersededInDir.has(`${dirname3(m)}\x00${basename(m)}`));
|
|
50599
50806
|
let projectName = options.name;
|
|
50600
50807
|
let projectLicense;
|
|
50601
50808
|
{
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cognium-dev",
|
|
3
|
-
"version": "4.9.
|
|
3
|
+
"version": "4.9.13",
|
|
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.1",
|
|
69
|
-
"circle-ir": "4.9.
|
|
69
|
+
"circle-ir": "4.9.13"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
72
|
"@types/node": "^25.5.0",
|