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.
- package/dist/cli.js +124 -1
- 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.
|
|
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.
|
|
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.
|
|
68
|
+
"circle-ir": "^3.59.0"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
71
|
"@types/node": "^25.5.0",
|