cognium-dev 3.84.0 → 3.85.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 +140 -6
  2. package/package.json +2 -2
package/dist/cli.js CHANGED
@@ -28957,6 +28957,11 @@ var TEST_FILENAME_RE = /(?:\.(?:test|spec)\.[cm]?[jt]sx?|_test\.go|_test\.py|Tes
28957
28957
  function isTestFile(file) {
28958
28958
  return TEST_PATH_RE3.test(file) || TEST_FILENAME_RE.test(file);
28959
28959
  }
28960
+ var GENERATED_PATH_RE = /(?:^|[\\/])(?:gen|generated|build[\\/]generated|src[\\/](?:main|test)[\\/]generated|target[\\/]generated-sources|target[\\/]generated-test-sources|node_modules[\\/]\.cache)(?:[\\/]|$)/i;
28961
+ var GENERATED_FILENAME_RE = /__[ch]\.java$|\.pb\.go$|_pb2\.py$|\.generated\.[cm]?[jt]sx?$/i;
28962
+ function isGeneratedFile(file) {
28963
+ return GENERATED_PATH_RE.test(file) || GENERATED_FILENAME_RE.test(file);
28964
+ }
28960
28965
  var PROVIDER_PATTERNS = [
28961
28966
  {
28962
28967
  name: "AWS access key",
@@ -29137,6 +29142,126 @@ function shannonEntropy(s) {
29137
29142
  return h;
29138
29143
  }
29139
29144
  var CREDENTIAL_NAME_RE = /(?:key|secret|token|password|passwd|credential|api[_-]?key)/i;
29145
+ function findAnnotationLineRanges(code) {
29146
+ const lines = code.split(`
29147
+ `);
29148
+ const inAnnotation = new Set;
29149
+ const OPEN_RE = /(?:@[A-Za-z_]\w*(?:\.[A-Za-z_]\w*)*\s*\(|#\[)/g;
29150
+ for (let i2 = 0;i2 < lines.length; i2++) {
29151
+ OPEN_RE.lastIndex = 0;
29152
+ let m;
29153
+ while ((m = OPEN_RE.exec(lines[i2])) !== null) {
29154
+ const isRustAttr = m[0].startsWith("#[");
29155
+ const openCh = isRustAttr ? "[" : "(";
29156
+ const closeCh = isRustAttr ? "]" : ")";
29157
+ let depth = 1;
29158
+ let li = i2;
29159
+ let col = m.index + m[0].length;
29160
+ let lineBudget = 200;
29161
+ inAnnotation.add(li + 1);
29162
+ while (depth > 0 && li < lines.length && lineBudget > 0) {
29163
+ const ln = lines[li];
29164
+ let inStr = null;
29165
+ while (col < ln.length && depth > 0) {
29166
+ const ch = ln[col];
29167
+ if (inStr !== null) {
29168
+ if (ch === "\\") {
29169
+ col += 2;
29170
+ continue;
29171
+ }
29172
+ if (ch === inStr)
29173
+ inStr = null;
29174
+ } else if (ch === '"' || ch === "'" || ch === "`") {
29175
+ inStr = ch;
29176
+ } else if (ch === openCh) {
29177
+ depth++;
29178
+ } else if (ch === closeCh) {
29179
+ depth--;
29180
+ }
29181
+ col++;
29182
+ }
29183
+ if (depth > 0) {
29184
+ li++;
29185
+ col = 0;
29186
+ lineBudget--;
29187
+ if (li < lines.length)
29188
+ inAnnotation.add(li + 1);
29189
+ }
29190
+ }
29191
+ }
29192
+ }
29193
+ return inAnnotation;
29194
+ }
29195
+ function findStringArrayLineRanges(code) {
29196
+ const lines = code.split(`
29197
+ `);
29198
+ const inArray = new Set;
29199
+ const OPEN_RE = /=\s*([{\[])/g;
29200
+ const STR_LITERAL_COUNT_RE = /(["'`])(?:\\.|(?!\1).)*\1/g;
29201
+ for (let i2 = 0;i2 < lines.length; i2++) {
29202
+ OPEN_RE.lastIndex = 0;
29203
+ let m;
29204
+ while ((m = OPEN_RE.exec(lines[i2])) !== null) {
29205
+ const openCh = m[1];
29206
+ const closeCh = openCh === "{" ? "}" : "]";
29207
+ let depth = 1;
29208
+ let li = i2;
29209
+ let col = m.index + m[0].length;
29210
+ let lineBudget = 500;
29211
+ const spanLines = [li + 1];
29212
+ let spanText = "";
29213
+ while (depth > 0 && li < lines.length && lineBudget > 0) {
29214
+ const ln = lines[li];
29215
+ let inStr = null;
29216
+ const start2 = col;
29217
+ while (col < ln.length && depth > 0) {
29218
+ const ch = ln[col];
29219
+ if (inStr !== null) {
29220
+ if (ch === "\\") {
29221
+ col += 2;
29222
+ continue;
29223
+ }
29224
+ if (ch === inStr)
29225
+ inStr = null;
29226
+ } else if (ch === '"' || ch === "'" || ch === "`") {
29227
+ inStr = ch;
29228
+ } else if (ch === openCh) {
29229
+ depth++;
29230
+ } else if (ch === closeCh) {
29231
+ depth--;
29232
+ }
29233
+ col++;
29234
+ }
29235
+ spanText += ln.substring(start2, col) + `
29236
+ `;
29237
+ if (depth > 0) {
29238
+ li++;
29239
+ col = 0;
29240
+ lineBudget--;
29241
+ if (li < lines.length)
29242
+ spanLines.push(li + 1);
29243
+ }
29244
+ }
29245
+ STR_LITERAL_COUNT_RE.lastIndex = 0;
29246
+ let strCount = 0;
29247
+ while (STR_LITERAL_COUNT_RE.exec(spanText) !== null) {
29248
+ strCount++;
29249
+ if (strCount >= 3)
29250
+ break;
29251
+ }
29252
+ if (strCount >= 3) {
29253
+ for (const ln of spanLines)
29254
+ inArray.add(ln);
29255
+ }
29256
+ }
29257
+ }
29258
+ return inArray;
29259
+ }
29260
+ var FIELD_ASSIGN_RE = /(?:^|[\s,(])([A-Za-z_$][\w$]*)\s*[:=]\s*["'`]/;
29261
+ function extractEnclosingFieldName(lineText) {
29262
+ const m = FIELD_ASSIGN_RE.exec(lineText);
29263
+ return m ? m[1] : null;
29264
+ }
29140
29265
  var TEST_CALL_RE = /\b(?:expect|assert|describe|it|test)\s*\(/;
29141
29266
  var COMMENT_EXAMPLE_RE = /(?:\/\/|#)\s*(?:example|sample|test|fixture)/i;
29142
29267
 
@@ -29145,7 +29270,7 @@ class ScanSecretsPass {
29145
29270
  category = "security";
29146
29271
  run(ctx) {
29147
29272
  const file = ctx.graph.ir.meta.file;
29148
- if (isTestFile(file)) {
29273
+ if (isTestFile(file) || isGeneratedFile(file)) {
29149
29274
  return { providerFindings: 0, entropyFindings: 0 };
29150
29275
  }
29151
29276
  const lines = ctx.code.split(`
@@ -29159,6 +29284,8 @@ class ScanSecretsPass {
29159
29284
  seen.add(`${f.line}:${f.rule_id}`);
29160
29285
  }
29161
29286
  }
29287
+ const annotationLines = findAnnotationLineRanges(ctx.code);
29288
+ const arrayLines = findStringArrayLineRanges(ctx.code);
29162
29289
  let providerFindings = 0;
29163
29290
  let entropyFindings = 0;
29164
29291
  for (let i2 = 0;i2 < lines.length; i2++) {
@@ -29225,12 +29352,18 @@ class ScanSecretsPass {
29225
29352
  continue;
29226
29353
  if (COMMENT_EXAMPLE_RE.test(lineText))
29227
29354
  continue;
29355
+ if (annotationLines.has(lineNum))
29356
+ continue;
29357
+ if (arrayLines.has(lineNum))
29358
+ continue;
29228
29359
  STRING_LITERAL_RE.lastIndex = 0;
29229
29360
  let match;
29230
29361
  while ((match = STRING_LITERAL_RE.exec(lineText)) !== null) {
29231
29362
  const value = match[2];
29232
29363
  if (!this.isCandidate(value))
29233
29364
  continue;
29365
+ if (value.length < 32)
29366
+ continue;
29234
29367
  if (!this.passesEntropyGate(value, lineText))
29235
29368
  continue;
29236
29369
  const key = `${lineNum}:hardcoded-credential-entropy`;
@@ -29277,11 +29410,12 @@ class ScanSecretsPass {
29277
29410
  return true;
29278
29411
  }
29279
29412
  passesEntropyGate(value, lineText) {
29413
+ const fieldName = extractEnclosingFieldName(lineText);
29414
+ if (fieldName === null || !CREDENTIAL_NAME_RE.test(fieldName))
29415
+ return false;
29280
29416
  const isHex = HEXISH_RE.test(value);
29281
- const boost = CREDENTIAL_NAME_RE.test(lineText) ? 0.2 : 0;
29282
- const threshold = isHex ? 3.5 - boost : 4.3 - boost;
29283
- const h = shannonEntropy(value);
29284
- return h >= threshold;
29417
+ const threshold = isHex ? 3.3 : 4.1;
29418
+ return shannonEntropy(value) >= threshold;
29285
29419
  }
29286
29420
  }
29287
29421
 
@@ -33856,7 +33990,7 @@ var colors = {
33856
33990
  };
33857
33991
 
33858
33992
  // src/version.ts
33859
- var version = "3.84.0";
33993
+ var version = "3.85.0";
33860
33994
 
33861
33995
  // src/formatters.ts
33862
33996
  var SINK_SEVERITY = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cognium-dev",
3
- "version": "3.84.0",
3
+ "version": "3.85.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.84.0"
68
+ "circle-ir": "^3.85.0"
69
69
  },
70
70
  "devDependencies": {
71
71
  "@types/node": "^25.5.0",