cognium-dev 3.212.0 → 3.214.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 +85 -29
  2. package/package.json +2 -2
package/dist/cli.js CHANGED
@@ -12752,31 +12752,33 @@ function findSources(calls, types, patterns, sourceLines, language) {
12752
12752
  }
12753
12753
  }
12754
12754
  const RUST_EXTRACTOR_KIND = /(?:^|::)(Json|Form|Query|Path|Extension|Multipart|Body|Bytes)(?:<|$)/;
12755
- for (const type of types) {
12756
- for (const method of type.methods) {
12757
- for (const param of method.parameters) {
12758
- if (!param.type)
12759
- continue;
12760
- const kindMatch = RUST_EXTRACTOR_KIND.exec(param.type);
12761
- if (!kindMatch)
12762
- continue;
12763
- const kind = kindMatch[1];
12764
- if (kind === "Extension")
12765
- continue;
12766
- const sourceType = kind === "Form" || kind === "Query" || kind === "Path" ? "http_param" : "http_body";
12767
- const paramLine = param.line ?? method.start_line;
12768
- const alreadyExists = sources.some((s) => s.line === paramLine && s.variable === param.name);
12769
- if (alreadyExists)
12770
- continue;
12771
- sources.push({
12772
- type: sourceType,
12773
- location: `${param.type} ${param.name} in ${method.name}`,
12774
- severity: "high",
12775
- line: paramLine,
12776
- confidence: 1,
12777
- variable: param.name,
12778
- in_method: method.name
12779
- });
12755
+ if (language === "rust") {
12756
+ for (const type of types) {
12757
+ for (const method of type.methods) {
12758
+ for (const param of method.parameters) {
12759
+ if (!param.type)
12760
+ continue;
12761
+ const kindMatch = RUST_EXTRACTOR_KIND.exec(param.type);
12762
+ if (!kindMatch)
12763
+ continue;
12764
+ const kind = kindMatch[1];
12765
+ if (kind === "Extension")
12766
+ continue;
12767
+ const sourceType = kind === "Form" || kind === "Query" || kind === "Path" ? "http_param" : "http_body";
12768
+ const paramLine = param.line ?? method.start_line;
12769
+ const alreadyExists = sources.some((s) => s.line === paramLine && s.variable === param.name);
12770
+ if (alreadyExists)
12771
+ continue;
12772
+ sources.push({
12773
+ type: sourceType,
12774
+ location: `${param.type} ${param.name} in ${method.name}`,
12775
+ severity: "high",
12776
+ line: paramLine,
12777
+ confidence: 1,
12778
+ variable: param.name,
12779
+ in_method: method.name
12780
+ });
12781
+ }
12780
12782
  }
12781
12783
  }
12782
12784
  }
@@ -24782,6 +24784,7 @@ class LanguageSourcesPass {
24782
24784
  additionalSanitizers.push(...findJavaSafeJsonParseSanitizers(code));
24783
24785
  additionalSanitizers.push(...findJavaPathNormalizeStartsWithGuardSanitizers(code));
24784
24786
  additionalSanitizers.push(...findJavaPathGetFileNameSanitizers(code));
24787
+ additionalSanitizers.push(...findJavaCanonicalPathStartsWithGuardSanitizers(code));
24785
24788
  additionalSanitizers.push(...findJavaInlineCrlfStripLogSanitizers(code));
24786
24789
  additionalSanitizers.push(...findJavaArgvFormExecSanitizers(code));
24787
24790
  for (const finding of findJavaPatternFindings(code, graph.ir.meta.file)) {
@@ -27638,6 +27641,58 @@ function findJavaPathNormalizeStartsWithGuardSanitizers(code) {
27638
27641
  }
27639
27642
  return sanitizers;
27640
27643
  }
27644
+ function findJavaCanonicalPathStartsWithGuardSanitizers(code) {
27645
+ const sanitizers = [];
27646
+ const lines = code.split(`
27647
+ `);
27648
+ const guardRe = /\bif\s*\(\s*!\s*([A-Za-z_]\w*)\s*\.\s*getCanonicalPath\s*\(\s*\)\s*\.\s*startsWith\s*\(/;
27649
+ const terminatorRe = /\b(throw|return)\b/;
27650
+ const assignRe = /^\s*(?:[A-Za-z_][\w.<>[\]]*\s+)?([A-Za-z_]\w*)\s*=(?!=)\s*(.*)$/;
27651
+ for (let i2 = 0;i2 < lines.length; i2++) {
27652
+ const m = guardRe.exec(lines[i2]);
27653
+ if (!m)
27654
+ continue;
27655
+ let hasTerminator = terminatorRe.test(lines[i2]);
27656
+ if (!hasTerminator) {
27657
+ for (let j = i2 + 1;j < Math.min(lines.length, i2 + 6); j++) {
27658
+ if (terminatorRe.test(lines[j])) {
27659
+ hasTerminator = true;
27660
+ break;
27661
+ }
27662
+ if (lines[j].includes("}"))
27663
+ break;
27664
+ }
27665
+ }
27666
+ if (!hasTerminator)
27667
+ continue;
27668
+ const guarded = new Set([m[1]]);
27669
+ const mentions = (t) => {
27670
+ for (const n of guarded)
27671
+ if (new RegExp(`\\b${n}\\b`).test(t))
27672
+ return true;
27673
+ return false;
27674
+ };
27675
+ for (let l = 0;l < lines.length; l++) {
27676
+ const lt = lines[l];
27677
+ const a = assignRe.exec(lt);
27678
+ if (a) {
27679
+ if (mentions(a[2]))
27680
+ guarded.add(a[1]);
27681
+ else if (a[1] !== m[1])
27682
+ guarded.delete(a[1]);
27683
+ }
27684
+ if (mentions(lt)) {
27685
+ sanitizers.push({
27686
+ type: "java_canonical_startswith_guard",
27687
+ method: "getCanonicalPath",
27688
+ line: l + 1,
27689
+ sanitizes: ["path_traversal", "external_taint_escape"]
27690
+ });
27691
+ }
27692
+ }
27693
+ }
27694
+ return sanitizers;
27695
+ }
27641
27696
  function findJavaPathGetFileNameSanitizers(code) {
27642
27697
  const sanitizers = [];
27643
27698
  const lines = code.split(`
@@ -27645,15 +27700,16 @@ function findJavaPathGetFileNameSanitizers(code) {
27645
27700
  const assignmentRe = /^\s*(?:(?:final\s+)?[A-Za-z_][\w.<>?,\s\[\]]*?\s+)?([A-Za-z_]\w*)\s*=\s*(.+?);\s*$/;
27646
27701
  const rhsHasGetFileNameRe = /\.\s*getFileName\s*\(\s*\)/;
27647
27702
  const rhsHasPathsChainRe = /\b(?:Paths\s*\.\s*get|Path\s*\.\s*of)\s*\(/;
27703
+ const rhsNewFileGetNameRe = /\bnew\s+File\s*\([\s\S]*\)\s*\.\s*getName\s*\(\s*\)/;
27648
27704
  const candidates = [];
27649
27705
  for (let i2 = 0;i2 < lines.length; i2++) {
27650
27706
  const m = assignmentRe.exec(lines[i2]);
27651
27707
  if (!m)
27652
27708
  continue;
27653
27709
  const rhs = m[2];
27654
- if (!rhsHasGetFileNameRe.test(rhs))
27655
- continue;
27656
- if (!rhsHasPathsChainRe.test(rhs))
27710
+ const isNioGetFileName = rhsHasGetFileNameRe.test(rhs) && rhsHasPathsChainRe.test(rhs);
27711
+ const isNewFileGetName = rhsNewFileGetNameRe.test(rhs);
27712
+ if (!isNioGetFileName && !isNewFileGetName)
27657
27713
  continue;
27658
27714
  candidates.push({ line: i2 + 1, boundVar: m[1] });
27659
27715
  }
@@ -47082,7 +47138,7 @@ var colors = {
47082
47138
  };
47083
47139
 
47084
47140
  // src/version.ts
47085
- var version = "3.212.0";
47141
+ var version = "3.214.0";
47086
47142
 
47087
47143
  // src/formatters.ts
47088
47144
  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.212.0",
3
+ "version": "3.214.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.212.0"
69
+ "circle-ir": "^3.214.0"
70
70
  },
71
71
  "devDependencies": {
72
72
  "@types/node": "^25.5.0",