cognium-dev 3.70.0 → 3.71.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 +105 -2
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -21228,6 +21228,13 @@ function findOopFieldReadSources(types, sourceCode, language) {
|
|
|
21228
21228
|
let returnedField = null;
|
|
21229
21229
|
let returnStatementCount = 0;
|
|
21230
21230
|
const returnRe = new RegExp(`\\breturn\\s+${SELF}\\.([A-Za-z_]\\w*)\\s*[;}]?`);
|
|
21231
|
+
const guardRePy = /\bif\s+[\w.]+\s+(?:not\s+)?in\s+(?:self\.)?[A-Z_][A-Z0-9_]*\s*:/;
|
|
21232
|
+
const guardThrowRePy = /^\s*(?:raise\b|abort\b|return\s+(?:None\b|''|""|\)?$))/;
|
|
21233
|
+
const guardReJv = /\bif\s*\(\s*!\s*(?:this\.)?[A-Z_][A-Z0-9_]*\s*\.\s*(?:contains|includes|has|matches)\s*\(/;
|
|
21234
|
+
const guardThrowReJv = /^\s*(?:throw\b|return\s+null\b)/;
|
|
21235
|
+
const guardRe = isPython ? guardRePy : guardReJv;
|
|
21236
|
+
const guardThrowRe = isPython ? guardThrowRePy : guardThrowReJv;
|
|
21237
|
+
let hasAllowlistGuard = false;
|
|
21231
21238
|
for (let i2 = mStart - 1;i2 < Math.min(mEnd, lines.length); i2++) {
|
|
21232
21239
|
const raw = lines[i2] ?? "";
|
|
21233
21240
|
const trimmed = raw.trim();
|
|
@@ -21243,8 +21250,17 @@ function findOopFieldReadSources(types, sourceCode, language) {
|
|
|
21243
21250
|
returnStatementCount = 99;
|
|
21244
21251
|
break;
|
|
21245
21252
|
}
|
|
21253
|
+
if (guardRe.test(trimmed)) {
|
|
21254
|
+
for (let j = i2 + 1;j < Math.min(i2 + 4, mEnd, lines.length); j++) {
|
|
21255
|
+
const next = lines[j] ?? "";
|
|
21256
|
+
if (guardThrowRe.test(next)) {
|
|
21257
|
+
hasAllowlistGuard = true;
|
|
21258
|
+
break;
|
|
21259
|
+
}
|
|
21260
|
+
}
|
|
21261
|
+
}
|
|
21246
21262
|
}
|
|
21247
|
-
if (returnStatementCount === 1 && returnedField && fieldTaint.has(returnedField)) {
|
|
21263
|
+
if (returnStatementCount === 1 && returnedField && fieldTaint.has(returnedField) && !hasAllowlistGuard) {
|
|
21248
21264
|
const fieldInfo = fieldTaint.get(returnedField);
|
|
21249
21265
|
const getterVar = isPython ? `${SELF}.${m.name}` : m.name;
|
|
21250
21266
|
sources.push({
|
|
@@ -22835,6 +22851,23 @@ class TaintPropagationPass {
|
|
|
22835
22851
|
return false;
|
|
22836
22852
|
});
|
|
22837
22853
|
}
|
|
22854
|
+
if (typeof ctx.code === "string") {
|
|
22855
|
+
const sinkByLine = new Map;
|
|
22856
|
+
for (const s of sinks) {
|
|
22857
|
+
if (s.type === "nosql_injection")
|
|
22858
|
+
sinkByLine.set(s.line, s);
|
|
22859
|
+
}
|
|
22860
|
+
if (sinkByLine.size > 0) {
|
|
22861
|
+
finalFlows = finalFlows.filter((f) => {
|
|
22862
|
+
if (f.sink_type !== "nosql_injection")
|
|
22863
|
+
return true;
|
|
22864
|
+
const sink = sinkByLine.get(f.sink_line);
|
|
22865
|
+
if (!sink || !sink.code || !sink.method)
|
|
22866
|
+
return true;
|
|
22867
|
+
return !isMongoValueBoundFilter(sink.code, sink.method);
|
|
22868
|
+
});
|
|
22869
|
+
}
|
|
22870
|
+
}
|
|
22838
22871
|
if (finalFlows.length > 1) {
|
|
22839
22872
|
const bestByKey = new Map;
|
|
22840
22873
|
for (const f of finalFlows) {
|
|
@@ -22852,6 +22885,76 @@ class TaintPropagationPass {
|
|
|
22852
22885
|
return { flows: finalFlows };
|
|
22853
22886
|
}
|
|
22854
22887
|
}
|
|
22888
|
+
function isMongoValueBoundFilter(sinkCode, sinkMethod) {
|
|
22889
|
+
if (!sinkCode || !sinkMethod)
|
|
22890
|
+
return false;
|
|
22891
|
+
const callIdx = sinkCode.indexOf(`${sinkMethod}(`);
|
|
22892
|
+
if (callIdx < 0)
|
|
22893
|
+
return false;
|
|
22894
|
+
const openIdx = callIdx + sinkMethod.length;
|
|
22895
|
+
let depth = 0;
|
|
22896
|
+
let braceDepth = 0;
|
|
22897
|
+
let bracketDepth = 0;
|
|
22898
|
+
let inString = null;
|
|
22899
|
+
let firstArgEnd = -1;
|
|
22900
|
+
let firstArgComma = -1;
|
|
22901
|
+
const limit = Math.min(sinkCode.length, openIdx + 4096);
|
|
22902
|
+
for (let i2 = openIdx;i2 < limit; i2++) {
|
|
22903
|
+
const ch = sinkCode[i2];
|
|
22904
|
+
if (inString) {
|
|
22905
|
+
if (ch === "\\" && i2 + 1 < limit) {
|
|
22906
|
+
i2++;
|
|
22907
|
+
continue;
|
|
22908
|
+
}
|
|
22909
|
+
if (ch === inString)
|
|
22910
|
+
inString = null;
|
|
22911
|
+
continue;
|
|
22912
|
+
}
|
|
22913
|
+
if (ch === '"' || ch === "'" || ch === "`") {
|
|
22914
|
+
inString = ch;
|
|
22915
|
+
continue;
|
|
22916
|
+
}
|
|
22917
|
+
if (ch === "(")
|
|
22918
|
+
depth++;
|
|
22919
|
+
else if (ch === ")") {
|
|
22920
|
+
depth--;
|
|
22921
|
+
if (depth === 0) {
|
|
22922
|
+
firstArgEnd = i2;
|
|
22923
|
+
break;
|
|
22924
|
+
}
|
|
22925
|
+
} else if (ch === "{")
|
|
22926
|
+
braceDepth++;
|
|
22927
|
+
else if (ch === "}")
|
|
22928
|
+
braceDepth--;
|
|
22929
|
+
else if (ch === "[")
|
|
22930
|
+
bracketDepth++;
|
|
22931
|
+
else if (ch === "]")
|
|
22932
|
+
bracketDepth--;
|
|
22933
|
+
else if (ch === "," && depth === 1 && braceDepth === 0 && bracketDepth === 0) {
|
|
22934
|
+
if (firstArgComma < 0)
|
|
22935
|
+
firstArgComma = i2;
|
|
22936
|
+
}
|
|
22937
|
+
}
|
|
22938
|
+
if (firstArgEnd < 0)
|
|
22939
|
+
return false;
|
|
22940
|
+
const argEnd = firstArgComma >= 0 ? firstArgComma : firstArgEnd;
|
|
22941
|
+
const firstArg = sinkCode.slice(openIdx + 1, argEnd).trim();
|
|
22942
|
+
if (!firstArg)
|
|
22943
|
+
return false;
|
|
22944
|
+
if (firstArg[0] !== "{" || firstArg[firstArg.length - 1] !== "}")
|
|
22945
|
+
return false;
|
|
22946
|
+
const body2 = firstArg.slice(1, -1).trim();
|
|
22947
|
+
if (!body2)
|
|
22948
|
+
return false;
|
|
22949
|
+
const stripped = body2.replace(/(['"`])(?:\\.|(?!\1).)*\1/g, '""');
|
|
22950
|
+
if (/\.\.\./.test(stripped))
|
|
22951
|
+
return false;
|
|
22952
|
+
if (/(^|[,{\s])\$[A-Za-z_]\w*\s*:/.test(stripped))
|
|
22953
|
+
return false;
|
|
22954
|
+
if (/(['"])\$[A-Za-z_]\w*\1\s*:/.test(body2))
|
|
22955
|
+
return false;
|
|
22956
|
+
return true;
|
|
22957
|
+
}
|
|
22855
22958
|
function isInJavaSanitizedMethod(code, types, sinkLine, sinkType) {
|
|
22856
22959
|
if (!types || types.length === 0)
|
|
22857
22960
|
return false;
|
|
@@ -31898,7 +32001,7 @@ var colors = {
|
|
|
31898
32001
|
};
|
|
31899
32002
|
|
|
31900
32003
|
// src/version.ts
|
|
31901
|
-
var version = "3.
|
|
32004
|
+
var version = "3.71.0";
|
|
31902
32005
|
|
|
31903
32006
|
// src/formatters.ts
|
|
31904
32007
|
var SINK_SEVERITY = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cognium-dev",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.71.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.71.0"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
71
|
"@types/node": "^25.5.0",
|