cognium-dev 3.77.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.
Files changed (2) hide show
  1. package/dist/cli.js +71 -5
  2. 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 = literalAlgo(call, 0);
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") {
@@ -32540,7 +32606,7 @@ var colors = {
32540
32606
  };
32541
32607
 
32542
32608
  // src/version.ts
32543
- var version = "3.77.0";
32609
+ var version = "3.78.0";
32544
32610
 
32545
32611
  // src/formatters.ts
32546
32612
  var SINK_SEVERITY = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cognium-dev",
3
- "version": "3.77.0",
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.77.0"
68
+ "circle-ir": "^3.78.0"
69
69
  },
70
70
  "devDependencies": {
71
71
  "@types/node": "^25.5.0",