cognium-dev 3.75.0 → 3.78.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 +114 -6
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -23733,6 +23733,48 @@ function detectExpressionScanFlows(calls, sources, sinks, sanitizers, unreachabl
|
|
|
23733
23733
|
}
|
|
23734
23734
|
}
|
|
23735
23735
|
}
|
|
23736
|
+
const aliasChains = [];
|
|
23737
|
+
{
|
|
23738
|
+
const codeLines2 = code.split(`
|
|
23739
|
+
`);
|
|
23740
|
+
for (let i2 = 0;i2 < codeLines2.length; i2++) {
|
|
23741
|
+
const ln = codeLines2[i2];
|
|
23742
|
+
if (ln.trimStart().startsWith("#"))
|
|
23743
|
+
continue;
|
|
23744
|
+
const m = ln.match(/^\s*([\p{L}\p{N}_]+)\s*=\s*([\p{L}\p{N}_]+)\s*$/u);
|
|
23745
|
+
if (!m)
|
|
23746
|
+
continue;
|
|
23747
|
+
const lineNum = i2 + 1;
|
|
23748
|
+
const lhs = m[1];
|
|
23749
|
+
if (derived.get(lhs) !== lineNum)
|
|
23750
|
+
continue;
|
|
23751
|
+
aliasChains.push({ lhs, upstream: m[2], line: lineNum });
|
|
23752
|
+
}
|
|
23753
|
+
}
|
|
23754
|
+
if (aliasChains.length > 0) {
|
|
23755
|
+
let changed = true;
|
|
23756
|
+
let guard = 0;
|
|
23757
|
+
while (changed && guard < aliasChains.length + 2) {
|
|
23758
|
+
changed = false;
|
|
23759
|
+
guard++;
|
|
23760
|
+
for (const { lhs, upstream } of aliasChains) {
|
|
23761
|
+
const upCov = aliasSanitizedFor.get(upstream);
|
|
23762
|
+
if (!upCov || upCov.size === 0)
|
|
23763
|
+
continue;
|
|
23764
|
+
let downCov = aliasSanitizedFor.get(lhs);
|
|
23765
|
+
if (!downCov) {
|
|
23766
|
+
downCov = new Set;
|
|
23767
|
+
aliasSanitizedFor.set(lhs, downCov);
|
|
23768
|
+
}
|
|
23769
|
+
for (const t of upCov) {
|
|
23770
|
+
if (!downCov.has(t)) {
|
|
23771
|
+
downCov.add(t);
|
|
23772
|
+
changed = true;
|
|
23773
|
+
}
|
|
23774
|
+
}
|
|
23775
|
+
}
|
|
23776
|
+
}
|
|
23777
|
+
}
|
|
23736
23778
|
}
|
|
23737
23779
|
}
|
|
23738
23780
|
if (language === "rust" && typeof code === "string" && sourcesWithVar.length > 0) {
|
|
@@ -29292,6 +29334,17 @@ var COMMONS_DIGEST_METHODS = new Set([
|
|
|
29292
29334
|
"sha",
|
|
29293
29335
|
"shaHex"
|
|
29294
29336
|
]);
|
|
29337
|
+
var COMMONS_DIGEST_GETTERS = {
|
|
29338
|
+
getMd2Digest: "md2",
|
|
29339
|
+
getMd5Digest: "md5",
|
|
29340
|
+
getSha1Digest: "sha1",
|
|
29341
|
+
getShaDigest: "sha1"
|
|
29342
|
+
};
|
|
29343
|
+
var COMMONS_ALGO_CONSTANTS = {
|
|
29344
|
+
"MessageDigestAlgorithms.MD2": "md2",
|
|
29345
|
+
"MessageDigestAlgorithms.MD5": "md5",
|
|
29346
|
+
"MessageDigestAlgorithms.SHA_1": "sha1"
|
|
29347
|
+
};
|
|
29295
29348
|
var PY_HASHLIB_WEAK = new Set(["md5", "sha1", "md4", "md2", "new"]);
|
|
29296
29349
|
function stripQuotes4(s) {
|
|
29297
29350
|
const trimmed = s.trim();
|
|
@@ -29308,16 +29361,68 @@ function literalAlgo(call, position) {
|
|
|
29308
29361
|
const cleaned = stripQuotes4(raw).toLowerCase();
|
|
29309
29362
|
return cleaned || null;
|
|
29310
29363
|
}
|
|
29364
|
+
function resolveJavaAlgo(call, position, constProp, javaBindings) {
|
|
29365
|
+
const arg = call.arguments.find((a) => a.position === position);
|
|
29366
|
+
if (!arg)
|
|
29367
|
+
return null;
|
|
29368
|
+
if (arg.literal) {
|
|
29369
|
+
const cleaned = stripQuotes4(arg.literal).toLowerCase();
|
|
29370
|
+
if (cleaned)
|
|
29371
|
+
return cleaned;
|
|
29372
|
+
}
|
|
29373
|
+
const expr = (arg.expression ?? "").trim();
|
|
29374
|
+
if (expr.startsWith('"') || expr.startsWith("`") || expr.startsWith("'")) {
|
|
29375
|
+
const cleaned = stripQuotes4(expr).toLowerCase();
|
|
29376
|
+
if (cleaned)
|
|
29377
|
+
return cleaned;
|
|
29378
|
+
}
|
|
29379
|
+
if (COMMONS_ALGO_CONSTANTS[expr])
|
|
29380
|
+
return COMMONS_ALGO_CONSTANTS[expr];
|
|
29381
|
+
const tail = expr.split(".").slice(-2).join(".");
|
|
29382
|
+
if (COMMONS_ALGO_CONSTANTS[tail])
|
|
29383
|
+
return COMMONS_ALGO_CONSTANTS[tail];
|
|
29384
|
+
if (arg.variable && constProp) {
|
|
29385
|
+
const sym = constProp.symbols?.get(arg.variable);
|
|
29386
|
+
if (sym && sym.type === "string" && typeof sym.value === "string") {
|
|
29387
|
+
const cleaned = stripQuotes4(sym.value).toLowerCase();
|
|
29388
|
+
if (cleaned)
|
|
29389
|
+
return cleaned;
|
|
29390
|
+
}
|
|
29391
|
+
}
|
|
29392
|
+
if (arg.variable) {
|
|
29393
|
+
const bound = javaBindings.get(arg.variable);
|
|
29394
|
+
if (bound) {
|
|
29395
|
+
const cleaned = stripQuotes4(bound).toLowerCase();
|
|
29396
|
+
if (cleaned)
|
|
29397
|
+
return cleaned;
|
|
29398
|
+
}
|
|
29399
|
+
}
|
|
29400
|
+
return null;
|
|
29401
|
+
}
|
|
29402
|
+
function scanJavaStringBindings(code) {
|
|
29403
|
+
const out2 = new Map;
|
|
29404
|
+
if (!code)
|
|
29405
|
+
return out2;
|
|
29406
|
+
const re = /^[ \t]*(?:(?:public|private|protected|static|final|volatile)\s+){0,5}String\s+([A-Za-z_][A-Za-z0-9_]*)\s*=\s*("[^"]*")\s*;/gm;
|
|
29407
|
+
let m;
|
|
29408
|
+
while ((m = re.exec(code)) !== null) {
|
|
29409
|
+
if (m[1] && m[2])
|
|
29410
|
+
out2.set(m[1], m[2]);
|
|
29411
|
+
}
|
|
29412
|
+
return out2;
|
|
29413
|
+
}
|
|
29311
29414
|
|
|
29312
29415
|
class WeakHashPass {
|
|
29313
29416
|
name = "weak-hash";
|
|
29314
29417
|
category = "security";
|
|
29315
29418
|
run(ctx) {
|
|
29316
|
-
const { graph, language } = ctx;
|
|
29419
|
+
const { graph, language, code } = ctx;
|
|
29317
29420
|
const file = graph.ir.meta.file;
|
|
29318
29421
|
const findings = [];
|
|
29422
|
+
const constProp = ctx.hasResult("constant-propagation") ? ctx.getResult("constant-propagation") : null;
|
|
29423
|
+
const javaBindings = language === "java" ? scanJavaStringBindings(code) : new Map;
|
|
29319
29424
|
for (const call of graph.ir.calls) {
|
|
29320
|
-
const detection = this.detect(call, language);
|
|
29425
|
+
const detection = this.detect(call, language, constProp, javaBindings);
|
|
29321
29426
|
if (!detection)
|
|
29322
29427
|
continue;
|
|
29323
29428
|
const { algorithm, api } = detection;
|
|
@@ -29340,12 +29445,12 @@ class WeakHashPass {
|
|
|
29340
29445
|
}
|
|
29341
29446
|
return { findings };
|
|
29342
29447
|
}
|
|
29343
|
-
detect(call, language) {
|
|
29448
|
+
detect(call, language, constProp, javaBindings) {
|
|
29344
29449
|
const method = call.method_name;
|
|
29345
29450
|
const receiver = call.receiver ?? "";
|
|
29346
29451
|
if (language === "java") {
|
|
29347
29452
|
if (method === "getInstance" && (receiver === "MessageDigest" || receiver.endsWith(".MessageDigest"))) {
|
|
29348
|
-
const algo =
|
|
29453
|
+
const algo = resolveJavaAlgo(call, 0, constProp, javaBindings);
|
|
29349
29454
|
if (algo && WEAK_HASH_NAMES.has(algo)) {
|
|
29350
29455
|
return { algorithm: algo, api: "MessageDigest.getInstance" };
|
|
29351
29456
|
}
|
|
@@ -29355,6 +29460,9 @@ class WeakHashPass {
|
|
|
29355
29460
|
const normalized = algoFromMethod === "sha" ? "sha1" : algoFromMethod;
|
|
29356
29461
|
return { algorithm: normalized, api: `DigestUtils.${method}` };
|
|
29357
29462
|
}
|
|
29463
|
+
if (COMMONS_DIGEST_GETTERS[method] && (receiver === "DigestUtils" || receiver.endsWith(".DigestUtils"))) {
|
|
29464
|
+
return { algorithm: COMMONS_DIGEST_GETTERS[method], api: `DigestUtils.${method}` };
|
|
29465
|
+
}
|
|
29358
29466
|
return null;
|
|
29359
29467
|
}
|
|
29360
29468
|
if (language === "python") {
|
|
@@ -30789,7 +30897,7 @@ class JwtVerifyDisabledPass {
|
|
|
30789
30897
|
out2.push({ pattern: "Algorithm.none()", api: "JWT.require" });
|
|
30790
30898
|
}
|
|
30791
30899
|
}
|
|
30792
|
-
if (method === "parse" && receiver
|
|
30900
|
+
if (method === "parse" && /\bJwts\s*\.\s*parser\s*\(/.test(receiver)) {
|
|
30793
30901
|
out2.push({ pattern: "parse() instead of parseClaimsJws()", api: "Jwts.parser().parse" });
|
|
30794
30902
|
}
|
|
30795
30903
|
return out2;
|
|
@@ -32498,7 +32606,7 @@ var colors = {
|
|
|
32498
32606
|
};
|
|
32499
32607
|
|
|
32500
32608
|
// src/version.ts
|
|
32501
|
-
var version = "3.
|
|
32609
|
+
var version = "3.78.0";
|
|
32502
32610
|
|
|
32503
32611
|
// src/formatters.ts
|
|
32504
32612
|
var SINK_SEVERITY = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cognium-dev",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.78.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.78.0"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
71
|
"@types/node": "^25.5.0",
|