cognium-dev 3.77.0 → 3.79.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 +82 -7
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -29334,6 +29334,17 @@ var COMMONS_DIGEST_METHODS = new Set([
|
|
|
29334
29334
|
"sha",
|
|
29335
29335
|
"shaHex"
|
|
29336
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
|
+
};
|
|
29337
29348
|
var PY_HASHLIB_WEAK = new Set(["md5", "sha1", "md4", "md2", "new"]);
|
|
29338
29349
|
function stripQuotes4(s) {
|
|
29339
29350
|
const trimmed = s.trim();
|
|
@@ -29350,16 +29361,68 @@ function literalAlgo(call, position) {
|
|
|
29350
29361
|
const cleaned = stripQuotes4(raw).toLowerCase();
|
|
29351
29362
|
return cleaned || null;
|
|
29352
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
|
+
}
|
|
29353
29414
|
|
|
29354
29415
|
class WeakHashPass {
|
|
29355
29416
|
name = "weak-hash";
|
|
29356
29417
|
category = "security";
|
|
29357
29418
|
run(ctx) {
|
|
29358
|
-
const { graph, language } = ctx;
|
|
29419
|
+
const { graph, language, code } = ctx;
|
|
29359
29420
|
const file = graph.ir.meta.file;
|
|
29360
29421
|
const findings = [];
|
|
29422
|
+
const constProp = ctx.hasResult("constant-propagation") ? ctx.getResult("constant-propagation") : null;
|
|
29423
|
+
const javaBindings = language === "java" ? scanJavaStringBindings(code) : new Map;
|
|
29361
29424
|
for (const call of graph.ir.calls) {
|
|
29362
|
-
const detection = this.detect(call, language);
|
|
29425
|
+
const detection = this.detect(call, language, constProp, javaBindings);
|
|
29363
29426
|
if (!detection)
|
|
29364
29427
|
continue;
|
|
29365
29428
|
const { algorithm, api } = detection;
|
|
@@ -29382,12 +29445,12 @@ class WeakHashPass {
|
|
|
29382
29445
|
}
|
|
29383
29446
|
return { findings };
|
|
29384
29447
|
}
|
|
29385
|
-
detect(call, language) {
|
|
29448
|
+
detect(call, language, constProp, javaBindings) {
|
|
29386
29449
|
const method = call.method_name;
|
|
29387
29450
|
const receiver = call.receiver ?? "";
|
|
29388
29451
|
if (language === "java") {
|
|
29389
29452
|
if (method === "getInstance" && (receiver === "MessageDigest" || receiver.endsWith(".MessageDigest"))) {
|
|
29390
|
-
const algo =
|
|
29453
|
+
const algo = resolveJavaAlgo(call, 0, constProp, javaBindings);
|
|
29391
29454
|
if (algo && WEAK_HASH_NAMES.has(algo)) {
|
|
29392
29455
|
return { algorithm: algo, api: "MessageDigest.getInstance" };
|
|
29393
29456
|
}
|
|
@@ -29397,6 +29460,9 @@ class WeakHashPass {
|
|
|
29397
29460
|
const normalized = algoFromMethod === "sha" ? "sha1" : algoFromMethod;
|
|
29398
29461
|
return { algorithm: normalized, api: `DigestUtils.${method}` };
|
|
29399
29462
|
}
|
|
29463
|
+
if (COMMONS_DIGEST_GETTERS[method] && (receiver === "DigestUtils" || receiver.endsWith(".DigestUtils"))) {
|
|
29464
|
+
return { algorithm: COMMONS_DIGEST_GETTERS[method], api: `DigestUtils.${method}` };
|
|
29465
|
+
}
|
|
29400
29466
|
return null;
|
|
29401
29467
|
}
|
|
29402
29468
|
if (language === "python") {
|
|
@@ -29706,8 +29772,9 @@ class WeakCryptoPass {
|
|
|
29706
29772
|
const receiver = call.receiver ?? "";
|
|
29707
29773
|
const out2 = [];
|
|
29708
29774
|
if (language === "java") {
|
|
29709
|
-
const
|
|
29710
|
-
|
|
29775
|
+
const isCipherInstance = method === "getInstance" && (receiver === "Cipher" || receiver.endsWith(".Cipher"));
|
|
29776
|
+
const isKeyGenInstance = method === "getInstance" && (receiver === "KeyGenerator" || receiver.endsWith(".KeyGenerator"));
|
|
29777
|
+
if (isCipherInstance) {
|
|
29711
29778
|
const spec = literalAlgo2(call, 0);
|
|
29712
29779
|
if (spec) {
|
|
29713
29780
|
const { weakBase, ecb } = classifyJavaCipherSpec(spec);
|
|
@@ -29717,6 +29784,14 @@ class WeakCryptoPass {
|
|
|
29717
29784
|
if (ecb)
|
|
29718
29785
|
out2.push({ issue: "ecb-mode", detail: spec, api });
|
|
29719
29786
|
}
|
|
29787
|
+
} else if (isKeyGenInstance) {
|
|
29788
|
+
const spec = literalAlgo2(call, 0);
|
|
29789
|
+
if (spec) {
|
|
29790
|
+
const { weakBase } = classifyJavaCipherSpec(spec);
|
|
29791
|
+
const api = `${receiver}.getInstance`;
|
|
29792
|
+
if (weakBase)
|
|
29793
|
+
out2.push({ issue: "weak-cipher", detail: weakBase, api });
|
|
29794
|
+
}
|
|
29720
29795
|
}
|
|
29721
29796
|
if (method === "IvParameterSpec" && isJavaCtor(call, "IvParameterSpec")) {
|
|
29722
29797
|
const ivDetail = detectStaticIvJava(call);
|
|
@@ -32540,7 +32615,7 @@ var colors = {
|
|
|
32540
32615
|
};
|
|
32541
32616
|
|
|
32542
32617
|
// src/version.ts
|
|
32543
|
-
var version = "3.
|
|
32618
|
+
var version = "3.79.0";
|
|
32544
32619
|
|
|
32545
32620
|
// src/formatters.ts
|
|
32546
32621
|
var SINK_SEVERITY = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cognium-dev",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.79.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.79.0"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
71
|
"@types/node": "^25.5.0",
|