cognium-dev 3.58.0 → 3.59.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 +124 -1
  2. package/package.json +2 -2
package/dist/cli.js CHANGED
@@ -20638,6 +20638,7 @@ class LanguageSourcesPass {
20638
20638
  const additionalSources = [];
20639
20639
  const additionalSinks = [];
20640
20640
  additionalSources.push(...findGetterSources(types, constProp.instanceFieldTaint, code));
20641
+ additionalSources.push(...findOopFieldReadSources(types, code, language));
20641
20642
  additionalSources.push(...findJavaScriptAssignmentSources(code, language));
20642
20643
  const jsDOMSinks = findJavaScriptDOMSinks(code, language);
20643
20644
  for (const s of jsDOMSinks) {
@@ -20743,6 +20744,128 @@ function findGetterSources(types, instanceFieldTaint, _sourceCode) {
20743
20744
  }
20744
20745
  return sources;
20745
20746
  }
20747
+ function findOopFieldReadSources(types, sourceCode, language) {
20748
+ if (language !== "java" && language !== "python")
20749
+ return [];
20750
+ const sources = [];
20751
+ const lines = sourceCode.split(`
20752
+ `);
20753
+ const isPython = language === "python";
20754
+ const SELF = isPython ? "self" : "this";
20755
+ const javaHttpPattern = /\b(?:req|request|httpRequest|servletRequest|httpServletRequest)\.(?:getParameter|getParameterValues|getParameterMap|getHeader|getHeaders|getCookies|getQueryString|getPathInfo|getRequestURI|getRequestURL|getInputStream|getReader)\b/;
20756
+ const fieldAssignRe = new RegExp(`^\\s*${SELF}\\.([A-Za-z_]\\w*)\\s*=\\s*(.+?)(?:;\\s*)?$`);
20757
+ const commentPrefix = isPython ? "#" : "//";
20758
+ for (const type of types) {
20759
+ if (type.kind !== "class")
20760
+ continue;
20761
+ if (type.name === "<module>")
20762
+ continue;
20763
+ let ctor;
20764
+ for (const m of type.methods) {
20765
+ if (isPython) {
20766
+ if (m.name === "__init__") {
20767
+ ctor = m;
20768
+ break;
20769
+ }
20770
+ } else {
20771
+ if (m.name === type.name) {
20772
+ ctor = m;
20773
+ break;
20774
+ }
20775
+ }
20776
+ }
20777
+ if (!ctor)
20778
+ continue;
20779
+ const paramNames = new Set;
20780
+ for (const p of ctor.parameters) {
20781
+ if (p.name === "self" || p.name === "this")
20782
+ continue;
20783
+ paramNames.add(p.name);
20784
+ }
20785
+ const fieldTaint = new Map;
20786
+ const ctorStart = ctor.start_line;
20787
+ const ctorEnd = ctor.end_line;
20788
+ for (let i2 = ctorStart - 1;i2 < Math.min(ctorEnd, lines.length); i2++) {
20789
+ const line = lines[i2] ?? "";
20790
+ if (line.trim().startsWith(commentPrefix))
20791
+ continue;
20792
+ const m = line.match(fieldAssignRe);
20793
+ if (!m)
20794
+ continue;
20795
+ const fieldName = m[1];
20796
+ const rhs = m[2].trim().replace(/;\s*$/, "");
20797
+ let sourceType = null;
20798
+ if (paramNames.has(rhs)) {
20799
+ sourceType = "interprocedural_param";
20800
+ } else if (!isPython && javaHttpPattern.test(rhs)) {
20801
+ sourceType = "http_param";
20802
+ } else if (isPython) {
20803
+ for (const { pattern, type: type2 } of PYTHON_TAINTED_PATTERNS2) {
20804
+ if (pattern.test(rhs)) {
20805
+ sourceType = type2;
20806
+ break;
20807
+ }
20808
+ }
20809
+ }
20810
+ if (sourceType) {
20811
+ fieldTaint.set(fieldName, { line: i2 + 1, type: sourceType });
20812
+ }
20813
+ }
20814
+ if (fieldTaint.size === 0)
20815
+ continue;
20816
+ for (const [fieldName, info2] of fieldTaint) {
20817
+ sources.push({
20818
+ type: info2.type,
20819
+ location: `${type.name}.${SELF}.${fieldName} (constructor-injected field, #78)`,
20820
+ severity: "high",
20821
+ line: info2.line,
20822
+ confidence: 0.85,
20823
+ variable: `${SELF}.${fieldName}`
20824
+ });
20825
+ }
20826
+ for (const m of type.methods) {
20827
+ if (m === ctor)
20828
+ continue;
20829
+ const nonSelfParams = m.parameters.filter((p) => p.name !== "self" && p.name !== "this");
20830
+ if (nonSelfParams.length !== 0)
20831
+ continue;
20832
+ const mStart = m.start_line;
20833
+ const mEnd = m.end_line;
20834
+ let returnedField = null;
20835
+ let returnStatementCount = 0;
20836
+ const returnRe = new RegExp(`\\breturn\\s+${SELF}\\.([A-Za-z_]\\w*)\\s*[;}]?`);
20837
+ for (let i2 = mStart - 1;i2 < Math.min(mEnd, lines.length); i2++) {
20838
+ const raw = lines[i2] ?? "";
20839
+ const trimmed = raw.trim();
20840
+ if (!trimmed)
20841
+ continue;
20842
+ if (trimmed.startsWith(commentPrefix))
20843
+ continue;
20844
+ const rm = trimmed.match(returnRe);
20845
+ if (rm) {
20846
+ returnedField = rm[1];
20847
+ returnStatementCount++;
20848
+ } else if (/\breturn\b/.test(trimmed)) {
20849
+ returnStatementCount = 99;
20850
+ break;
20851
+ }
20852
+ }
20853
+ if (returnStatementCount === 1 && returnedField && fieldTaint.has(returnedField)) {
20854
+ const fieldInfo = fieldTaint.get(returnedField);
20855
+ const getterVar = isPython ? `${SELF}.${m.name}` : m.name;
20856
+ sources.push({
20857
+ type: fieldInfo.type,
20858
+ location: `${type.name}.${m.name} returns tainted field '${returnedField}' (#78)`,
20859
+ severity: "high",
20860
+ line: m.start_line,
20861
+ confidence: 0.85,
20862
+ variable: getterVar
20863
+ });
20864
+ }
20865
+ }
20866
+ }
20867
+ return sources;
20868
+ }
20746
20869
  function findJavaScriptAssignmentSources(sourceCode, language) {
20747
20870
  if (!["javascript", "typescript"].includes(language))
20748
20871
  return [];
@@ -30440,7 +30563,7 @@ var colors = {
30440
30563
  };
30441
30564
 
30442
30565
  // src/version.ts
30443
- var version = "3.58.0";
30566
+ var version = "3.59.0";
30444
30567
 
30445
30568
  // src/formatters.ts
30446
30569
  var SINK_SEVERITY = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cognium-dev",
3
- "version": "3.58.0",
3
+ "version": "3.59.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.58.0"
68
+ "circle-ir": "^3.59.0"
69
69
  },
70
70
  "devDependencies": {
71
71
  "@types/node": "^25.5.0",