cognium-dev 3.209.0 → 3.212.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 +120 -70
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -11840,8 +11840,6 @@ var DEFAULT_SINKS = [
|
|
|
11840
11840
|
{ method: "setVariable", class: "Context", type: "xss", cwe: "CWE-79", severity: "medium", arg_positions: [1] },
|
|
11841
11841
|
{ method: "clean", class: "AntiSamy", type: "xss", cwe: "CWE-79", severity: "medium", arg_positions: [0] },
|
|
11842
11842
|
{ method: "getValidSafeHTML", class: "ESAPI", type: "xss", cwe: "CWE-79", severity: "medium", arg_positions: [0] },
|
|
11843
|
-
{ method: "getAttribute", class: "HttpServletRequest", type: "xss", cwe: "CWE-79", severity: "medium", arg_positions: [] },
|
|
11844
|
-
{ method: "getAttribute", class: "HttpSession", type: "xss", cwe: "CWE-79", severity: "medium", arg_positions: [] },
|
|
11845
11843
|
{ method: "spawn", class: "Command", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
11846
11844
|
{ method: "output", class: "Command", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
11847
11845
|
{ method: "status", class: "Command", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0] },
|
|
@@ -14479,6 +14477,73 @@ function isNonExecutablePython(trimmed) {
|
|
|
14479
14477
|
return false;
|
|
14480
14478
|
}
|
|
14481
14479
|
|
|
14480
|
+
// ../circle-ir/dist/analysis/sanitizer-index.js
|
|
14481
|
+
var SANITIZER_SET_CACHE = new WeakMap;
|
|
14482
|
+
function getSanitizesSet(san) {
|
|
14483
|
+
let s = SANITIZER_SET_CACHE.get(san);
|
|
14484
|
+
if (!s) {
|
|
14485
|
+
s = new Set(san.sanitizes);
|
|
14486
|
+
SANITIZER_SET_CACHE.set(san, s);
|
|
14487
|
+
}
|
|
14488
|
+
return s;
|
|
14489
|
+
}
|
|
14490
|
+
function sanitizerCoversSink(san, sinkType) {
|
|
14491
|
+
return getSanitizesSet(san).has(sinkType);
|
|
14492
|
+
}
|
|
14493
|
+
|
|
14494
|
+
// ../circle-ir/dist/analysis/dfg-walk.js
|
|
14495
|
+
var walkBackwardDefsMemo = new WeakMap;
|
|
14496
|
+
function walkBackwardDefs(startDefId, chainsByToDef, defById, options = {}) {
|
|
14497
|
+
const maxHops = options.maxHops ?? 32;
|
|
14498
|
+
let perFile = walkBackwardDefsMemo.get(chainsByToDef);
|
|
14499
|
+
if (perFile !== undefined) {
|
|
14500
|
+
const key = `${startDefId}|${maxHops}`;
|
|
14501
|
+
const hit = perFile.get(key);
|
|
14502
|
+
if (hit !== undefined)
|
|
14503
|
+
return hit;
|
|
14504
|
+
}
|
|
14505
|
+
const visited = new Set;
|
|
14506
|
+
const lines = new Set;
|
|
14507
|
+
let hopCapReached = false;
|
|
14508
|
+
const startDef = defById.get(startDefId);
|
|
14509
|
+
if (!startDef) {
|
|
14510
|
+
return { visited, lines, hopCapReached: false };
|
|
14511
|
+
}
|
|
14512
|
+
visited.add(startDefId);
|
|
14513
|
+
lines.add(startDef.line);
|
|
14514
|
+
const queue = [startDefId];
|
|
14515
|
+
let hops = 0;
|
|
14516
|
+
while (queue.length > 0) {
|
|
14517
|
+
if (hops >= maxHops) {
|
|
14518
|
+
hopCapReached = true;
|
|
14519
|
+
break;
|
|
14520
|
+
}
|
|
14521
|
+
hops++;
|
|
14522
|
+
const currentId = queue.shift();
|
|
14523
|
+
const incoming = chainsByToDef.get(currentId);
|
|
14524
|
+
if (!incoming)
|
|
14525
|
+
continue;
|
|
14526
|
+
for (const chain of incoming) {
|
|
14527
|
+
const fromId = chain.from_def;
|
|
14528
|
+
if (visited.has(fromId))
|
|
14529
|
+
continue;
|
|
14530
|
+
visited.add(fromId);
|
|
14531
|
+
const fromDef = defById.get(fromId);
|
|
14532
|
+
if (fromDef) {
|
|
14533
|
+
lines.add(fromDef.line);
|
|
14534
|
+
}
|
|
14535
|
+
queue.push(fromId);
|
|
14536
|
+
}
|
|
14537
|
+
}
|
|
14538
|
+
const result = { visited, lines, hopCapReached };
|
|
14539
|
+
if (perFile === undefined) {
|
|
14540
|
+
perFile = new Map;
|
|
14541
|
+
walkBackwardDefsMemo.set(chainsByToDef, perFile);
|
|
14542
|
+
}
|
|
14543
|
+
perFile.set(`${startDefId}|${maxHops}`, result);
|
|
14544
|
+
return result;
|
|
14545
|
+
}
|
|
14546
|
+
|
|
14482
14547
|
// ../circle-ir/dist/analysis/findings.js
|
|
14483
14548
|
function canSourceReachSink(sourceType, sinkType) {
|
|
14484
14549
|
const sourceToSinkMapping = {
|
|
@@ -16765,73 +16830,6 @@ class AnalysisPipeline {
|
|
|
16765
16830
|
return { results, findings };
|
|
16766
16831
|
}
|
|
16767
16832
|
}
|
|
16768
|
-
// ../circle-ir/dist/analysis/dfg-walk.js
|
|
16769
|
-
var walkBackwardDefsMemo = new WeakMap;
|
|
16770
|
-
function walkBackwardDefs(startDefId, chainsByToDef, defById, options = {}) {
|
|
16771
|
-
const maxHops = options.maxHops ?? 32;
|
|
16772
|
-
let perFile = walkBackwardDefsMemo.get(chainsByToDef);
|
|
16773
|
-
if (perFile !== undefined) {
|
|
16774
|
-
const key = `${startDefId}|${maxHops}`;
|
|
16775
|
-
const hit = perFile.get(key);
|
|
16776
|
-
if (hit !== undefined)
|
|
16777
|
-
return hit;
|
|
16778
|
-
}
|
|
16779
|
-
const visited = new Set;
|
|
16780
|
-
const lines = new Set;
|
|
16781
|
-
let hopCapReached = false;
|
|
16782
|
-
const startDef = defById.get(startDefId);
|
|
16783
|
-
if (!startDef) {
|
|
16784
|
-
return { visited, lines, hopCapReached: false };
|
|
16785
|
-
}
|
|
16786
|
-
visited.add(startDefId);
|
|
16787
|
-
lines.add(startDef.line);
|
|
16788
|
-
const queue = [startDefId];
|
|
16789
|
-
let hops = 0;
|
|
16790
|
-
while (queue.length > 0) {
|
|
16791
|
-
if (hops >= maxHops) {
|
|
16792
|
-
hopCapReached = true;
|
|
16793
|
-
break;
|
|
16794
|
-
}
|
|
16795
|
-
hops++;
|
|
16796
|
-
const currentId = queue.shift();
|
|
16797
|
-
const incoming = chainsByToDef.get(currentId);
|
|
16798
|
-
if (!incoming)
|
|
16799
|
-
continue;
|
|
16800
|
-
for (const chain of incoming) {
|
|
16801
|
-
const fromId = chain.from_def;
|
|
16802
|
-
if (visited.has(fromId))
|
|
16803
|
-
continue;
|
|
16804
|
-
visited.add(fromId);
|
|
16805
|
-
const fromDef = defById.get(fromId);
|
|
16806
|
-
if (fromDef) {
|
|
16807
|
-
lines.add(fromDef.line);
|
|
16808
|
-
}
|
|
16809
|
-
queue.push(fromId);
|
|
16810
|
-
}
|
|
16811
|
-
}
|
|
16812
|
-
const result = { visited, lines, hopCapReached };
|
|
16813
|
-
if (perFile === undefined) {
|
|
16814
|
-
perFile = new Map;
|
|
16815
|
-
walkBackwardDefsMemo.set(chainsByToDef, perFile);
|
|
16816
|
-
}
|
|
16817
|
-
perFile.set(`${startDefId}|${maxHops}`, result);
|
|
16818
|
-
return result;
|
|
16819
|
-
}
|
|
16820
|
-
|
|
16821
|
-
// ../circle-ir/dist/analysis/sanitizer-index.js
|
|
16822
|
-
var SANITIZER_SET_CACHE = new WeakMap;
|
|
16823
|
-
function getSanitizesSet(san) {
|
|
16824
|
-
let s = SANITIZER_SET_CACHE.get(san);
|
|
16825
|
-
if (!s) {
|
|
16826
|
-
s = new Set(san.sanitizes);
|
|
16827
|
-
SANITIZER_SET_CACHE.set(san, s);
|
|
16828
|
-
}
|
|
16829
|
-
return s;
|
|
16830
|
-
}
|
|
16831
|
-
function sanitizerCoversSink(san, sinkType) {
|
|
16832
|
-
return getSanitizesSet(san).has(sinkType);
|
|
16833
|
-
}
|
|
16834
|
-
|
|
16835
16833
|
// ../circle-ir/dist/analysis/taint-propagation.js
|
|
16836
16834
|
function buildSanitizersByLine(sanitizers) {
|
|
16837
16835
|
const out2 = new Map;
|
|
@@ -31801,6 +31799,52 @@ var SQL_EXEC_METHODS = new Set([
|
|
|
31801
31799
|
var JAVA_SQL_ASSIGN_RE_TEMPLATE = "\\b(?:String|CharSequence|final\\s+String|var)\\s+SQLVAR\\b\\s*=\\s*(.+?);";
|
|
31802
31800
|
var REPLACE_ALL_TO_PLACEHOLDER_RE = /\.replaceAll\s*\([\s\S]*?,\s*"[\s,?]*\?[\s,?]*"\s*\)/;
|
|
31803
31801
|
var HTML_CONTENT_TYPE_RE = /text\/html|TEXT_HTML/;
|
|
31802
|
+
function javaTraversalRejectGuardedLines(code) {
|
|
31803
|
+
const covered = new Set;
|
|
31804
|
+
const lines = code.split(`
|
|
31805
|
+
`);
|
|
31806
|
+
const guardOpen = /\bif\s*\(\s*([A-Za-z_]\w*)\s*\.\s*contains\s*\(\s*"[^"]*\.\.[^"]*"\s*\)/;
|
|
31807
|
+
const terminatorRe = /\b(throw|return)\b/;
|
|
31808
|
+
const assignRe = /^\s*(?:[A-Za-z_][\w.<>[\]]*\s+)?([A-Za-z_]\w*)\s*=(?!=)\s*(.*)$/;
|
|
31809
|
+
for (let i2 = 0;i2 < lines.length; i2++) {
|
|
31810
|
+
const m = guardOpen.exec(lines[i2]);
|
|
31811
|
+
if (!m)
|
|
31812
|
+
continue;
|
|
31813
|
+
let hasTerminator = terminatorRe.test(lines[i2]);
|
|
31814
|
+
if (!hasTerminator) {
|
|
31815
|
+
for (let j = i2 + 1;j < Math.min(lines.length, i2 + 6); j++) {
|
|
31816
|
+
if (terminatorRe.test(lines[j])) {
|
|
31817
|
+
hasTerminator = true;
|
|
31818
|
+
break;
|
|
31819
|
+
}
|
|
31820
|
+
if (lines[j].includes("}"))
|
|
31821
|
+
break;
|
|
31822
|
+
}
|
|
31823
|
+
}
|
|
31824
|
+
if (!hasTerminator)
|
|
31825
|
+
continue;
|
|
31826
|
+
const guarded = new Set([m[1]]);
|
|
31827
|
+
const mentionsGuarded = (text) => {
|
|
31828
|
+
for (const name2 of guarded)
|
|
31829
|
+
if (new RegExp(`\\b${name2}\\b`).test(text))
|
|
31830
|
+
return true;
|
|
31831
|
+
return false;
|
|
31832
|
+
};
|
|
31833
|
+
for (let l = i2 + 1;l < lines.length; l++) {
|
|
31834
|
+
const lineText = lines[l];
|
|
31835
|
+
const assign = assignRe.exec(lineText);
|
|
31836
|
+
if (assign) {
|
|
31837
|
+
if (mentionsGuarded(assign[2]))
|
|
31838
|
+
guarded.add(assign[1]);
|
|
31839
|
+
else if (assign[1] !== m[1])
|
|
31840
|
+
guarded.delete(assign[1]);
|
|
31841
|
+
}
|
|
31842
|
+
if (mentionsGuarded(lineText))
|
|
31843
|
+
covered.add(l + 1);
|
|
31844
|
+
}
|
|
31845
|
+
}
|
|
31846
|
+
return covered;
|
|
31847
|
+
}
|
|
31804
31848
|
var JAVA_INLINE_MATCHES_RE = /\.\s*matches\s*\(\s*"((?:[^"\\]|\\.)*)"\s*\)/g;
|
|
31805
31849
|
function resolveJavaReceiverType(receiver, sinkLine, sourceLines) {
|
|
31806
31850
|
if (!receiver || !/^[A-Za-z_]\w*$/.test(receiver))
|
|
@@ -32580,6 +32624,12 @@ class SinkFilterPass {
|
|
|
32580
32624
|
if (language === "java" && !HTML_CONTENT_TYPE_RE.test(ctx.code)) {
|
|
32581
32625
|
filtered = filtered.filter((sink) => !(sink.type === "xss" && sink.method === "body"));
|
|
32582
32626
|
}
|
|
32627
|
+
if (language === "java") {
|
|
32628
|
+
const guardedLines = javaTraversalRejectGuardedLines(ctx.code);
|
|
32629
|
+
if (guardedLines.size > 0) {
|
|
32630
|
+
filtered = filtered.filter((sink) => !(sink.type === "path_traversal" && guardedLines.has(sink.line)));
|
|
32631
|
+
}
|
|
32632
|
+
}
|
|
32583
32633
|
if (["javascript", "typescript"].includes(language)) {
|
|
32584
32634
|
const sourceLines = ctx.code.split(`
|
|
32585
32635
|
`);
|
|
@@ -47032,7 +47082,7 @@ var colors = {
|
|
|
47032
47082
|
};
|
|
47033
47083
|
|
|
47034
47084
|
// src/version.ts
|
|
47035
|
-
var version = "3.
|
|
47085
|
+
var version = "3.212.0";
|
|
47036
47086
|
|
|
47037
47087
|
// src/formatters.ts
|
|
47038
47088
|
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.
|
|
3
|
+
"version": "3.212.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.
|
|
69
|
+
"circle-ir": "^3.212.0"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
72
|
"@types/node": "^25.5.0",
|