cognium-dev 3.125.0 → 3.126.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 +94 -1
  2. package/package.json +2 -2
package/dist/cli.js CHANGED
@@ -22625,6 +22625,7 @@ class LanguageSourcesPass {
22625
22625
  additionalSanitizers.push(...findJsCryptoHashSanitizers(code));
22626
22626
  additionalSanitizers.push(...findJsCsvFormulaPrefixSanitizers(code));
22627
22627
  additionalSanitizers.push(...findJsWrapperFunctionSanitizers(code));
22628
+ additionalSanitizers.push(...findJsSsrfAllowlistGuardSanitizers(code));
22628
22629
  }
22629
22630
  if (language === "java") {
22630
22631
  additionalSanitizers.push(...findJavaSafeJsonParseSanitizers(code));
@@ -24487,6 +24488,98 @@ function findJsWrapperFunctionSanitizers(code) {
24487
24488
  }
24488
24489
  return sanitizers;
24489
24490
  }
24491
+ function findJsSsrfAllowlistGuardSanitizers(code) {
24492
+ const sanitizers = [];
24493
+ const lines = code.split(`
24494
+ `);
24495
+ const urlAliasToHostAlias = new Map;
24496
+ const urlAliasDecl = /\b(?:const|let|var)\s+([A-Za-z_]\w*)\s*=\s*new\s+URL\s*\(\s*([A-Za-z_][\w.[\]'"`]*)\s*\)/;
24497
+ const hostAliasDecl = /\b(?:const|let|var)\s+([A-Za-z_]\w*)\s*=\s*([A-Za-z_]\w*)\.(?:hostname|host)\b/;
24498
+ const hostFromUrl = new Map;
24499
+ for (const line of lines) {
24500
+ const ua = urlAliasDecl.exec(line);
24501
+ if (ua)
24502
+ urlAliasToHostAlias.set(ua[1], ua[2]);
24503
+ const ha = hostAliasDecl.exec(line);
24504
+ if (ha)
24505
+ hostFromUrl.set(ha[1], ha[2]);
24506
+ }
24507
+ const allowlistName = /^(?:[A-Z][A-Z0-9_]+|.*?(allowed|accepted|whitelist|permitted|valid|approved).*)$/i;
24508
+ const guardHas = /if\s*\(\s*!\s*([A-Za-z_]\w*)\s*\.\s*(?:has|includes)\s*\(\s*([A-Za-z_]\w*)(?:\s*\.\s*(?:hostname|host))?\s*\)\s*\)/;
24509
+ const guardIndexOf = /if\s*\(\s*([A-Za-z_]\w*)\s*\.\s*indexOf\s*\(\s*([A-Za-z_]\w*)(?:\s*\.\s*(?:hostname|host))?\s*\)\s*<\s*0\s*\)/;
24510
+ const terminator = /\b(return|throw|res\s*\.\s*status\s*\([^)]*\)\s*\.\s*(?:send|end|json)\s*\()/;
24511
+ for (let i2 = 0;i2 < lines.length; i2++) {
24512
+ const line = lines[i2];
24513
+ let m = guardHas.exec(line);
24514
+ let allow = null;
24515
+ let guardedVar = null;
24516
+ if (m) {
24517
+ allow = m[1];
24518
+ guardedVar = m[2];
24519
+ } else {
24520
+ m = guardIndexOf.exec(line);
24521
+ if (m) {
24522
+ allow = m[1];
24523
+ guardedVar = m[2];
24524
+ }
24525
+ }
24526
+ if (!allow || !guardedVar)
24527
+ continue;
24528
+ if (!allowlistName.test(allow))
24529
+ continue;
24530
+ let bodyHasTerminator = false;
24531
+ let blockEnd = -1;
24532
+ const maxScan = Math.min(lines.length, i2 + 26);
24533
+ let braceDepth = 0;
24534
+ let started = false;
24535
+ for (let j = i2;j < maxScan; j++) {
24536
+ const ln = lines[j];
24537
+ for (const ch of ln) {
24538
+ if (ch === "{") {
24539
+ braceDepth++;
24540
+ started = true;
24541
+ } else if (ch === "}") {
24542
+ braceDepth--;
24543
+ if (started && braceDepth === 0) {
24544
+ blockEnd = j;
24545
+ break;
24546
+ }
24547
+ }
24548
+ }
24549
+ if (started && j > i2 && terminator.test(ln))
24550
+ bodyHasTerminator = true;
24551
+ if (blockEnd !== -1)
24552
+ break;
24553
+ }
24554
+ if (!started)
24555
+ continue;
24556
+ if (blockEnd === -1)
24557
+ continue;
24558
+ if (!bodyHasTerminator)
24559
+ continue;
24560
+ const safeNames = new Set([guardedVar]);
24561
+ if (hostFromUrl.has(guardedVar)) {
24562
+ safeNames.add(hostFromUrl.get(guardedVar));
24563
+ }
24564
+ for (const [hostName, urlName] of hostFromUrl) {
24565
+ if (urlName === guardedVar)
24566
+ safeNames.add(hostName);
24567
+ }
24568
+ const refRes = [...safeNames].map((n) => new RegExp(`\\b${n}\\b`));
24569
+ for (let l = blockEnd + 2;l <= lines.length; l++) {
24570
+ const lineText = lines[l - 1];
24571
+ if (!refRes.some((re) => re.test(lineText)))
24572
+ continue;
24573
+ sanitizers.push({
24574
+ type: "js_ssrf_allowlist_guard",
24575
+ method: "if",
24576
+ line: l,
24577
+ sanitizes: ["ssrf", "external_taint_escape"]
24578
+ });
24579
+ }
24580
+ }
24581
+ return sanitizers;
24582
+ }
24490
24583
  function collectEnvSecretVars(lines, language) {
24491
24584
  const out2 = new Map;
24492
24585
  for (let i2 = 0;i2 < lines.length; i2++) {
@@ -38028,7 +38121,7 @@ var colors = {
38028
38121
  };
38029
38122
 
38030
38123
  // src/version.ts
38031
- var version = "3.125.0";
38124
+ var version = "3.126.0";
38032
38125
 
38033
38126
  // src/formatters.ts
38034
38127
  var LIBRARY_API_SURFACE_TAG2 = "library-api-surface:caller-responsibility";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cognium-dev",
3
- "version": "3.125.0",
3
+ "version": "3.126.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",
@@ -66,7 +66,7 @@
66
66
  },
67
67
  "dependencies": {
68
68
  "@cognium/project-profile-detect": "^1.1.0",
69
- "circle-ir": "^3.125.0"
69
+ "circle-ir": "^3.126.0"
70
70
  },
71
71
  "devDependencies": {
72
72
  "@types/node": "^25.5.0",