cognium-dev 3.210.0 → 3.213.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 +125 -73
- 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;
|
|
@@ -24784,6 +24782,7 @@ class LanguageSourcesPass {
|
|
|
24784
24782
|
additionalSanitizers.push(...findJavaSafeJsonParseSanitizers(code));
|
|
24785
24783
|
additionalSanitizers.push(...findJavaPathNormalizeStartsWithGuardSanitizers(code));
|
|
24786
24784
|
additionalSanitizers.push(...findJavaPathGetFileNameSanitizers(code));
|
|
24785
|
+
additionalSanitizers.push(...findJavaCanonicalPathStartsWithGuardSanitizers(code));
|
|
24787
24786
|
additionalSanitizers.push(...findJavaInlineCrlfStripLogSanitizers(code));
|
|
24788
24787
|
additionalSanitizers.push(...findJavaArgvFormExecSanitizers(code));
|
|
24789
24788
|
for (const finding of findJavaPatternFindings(code, graph.ir.meta.file)) {
|
|
@@ -27640,6 +27639,58 @@ function findJavaPathNormalizeStartsWithGuardSanitizers(code) {
|
|
|
27640
27639
|
}
|
|
27641
27640
|
return sanitizers;
|
|
27642
27641
|
}
|
|
27642
|
+
function findJavaCanonicalPathStartsWithGuardSanitizers(code) {
|
|
27643
|
+
const sanitizers = [];
|
|
27644
|
+
const lines = code.split(`
|
|
27645
|
+
`);
|
|
27646
|
+
const guardRe = /\bif\s*\(\s*!\s*([A-Za-z_]\w*)\s*\.\s*getCanonicalPath\s*\(\s*\)\s*\.\s*startsWith\s*\(/;
|
|
27647
|
+
const terminatorRe = /\b(throw|return)\b/;
|
|
27648
|
+
const assignRe = /^\s*(?:[A-Za-z_][\w.<>[\]]*\s+)?([A-Za-z_]\w*)\s*=(?!=)\s*(.*)$/;
|
|
27649
|
+
for (let i2 = 0;i2 < lines.length; i2++) {
|
|
27650
|
+
const m = guardRe.exec(lines[i2]);
|
|
27651
|
+
if (!m)
|
|
27652
|
+
continue;
|
|
27653
|
+
let hasTerminator = terminatorRe.test(lines[i2]);
|
|
27654
|
+
if (!hasTerminator) {
|
|
27655
|
+
for (let j = i2 + 1;j < Math.min(lines.length, i2 + 6); j++) {
|
|
27656
|
+
if (terminatorRe.test(lines[j])) {
|
|
27657
|
+
hasTerminator = true;
|
|
27658
|
+
break;
|
|
27659
|
+
}
|
|
27660
|
+
if (lines[j].includes("}"))
|
|
27661
|
+
break;
|
|
27662
|
+
}
|
|
27663
|
+
}
|
|
27664
|
+
if (!hasTerminator)
|
|
27665
|
+
continue;
|
|
27666
|
+
const guarded = new Set([m[1]]);
|
|
27667
|
+
const mentions = (t) => {
|
|
27668
|
+
for (const n of guarded)
|
|
27669
|
+
if (new RegExp(`\\b${n}\\b`).test(t))
|
|
27670
|
+
return true;
|
|
27671
|
+
return false;
|
|
27672
|
+
};
|
|
27673
|
+
for (let l = 0;l < lines.length; l++) {
|
|
27674
|
+
const lt = lines[l];
|
|
27675
|
+
const a = assignRe.exec(lt);
|
|
27676
|
+
if (a) {
|
|
27677
|
+
if (mentions(a[2]))
|
|
27678
|
+
guarded.add(a[1]);
|
|
27679
|
+
else if (a[1] !== m[1])
|
|
27680
|
+
guarded.delete(a[1]);
|
|
27681
|
+
}
|
|
27682
|
+
if (mentions(lt)) {
|
|
27683
|
+
sanitizers.push({
|
|
27684
|
+
type: "java_canonical_startswith_guard",
|
|
27685
|
+
method: "getCanonicalPath",
|
|
27686
|
+
line: l + 1,
|
|
27687
|
+
sanitizes: ["path_traversal", "external_taint_escape"]
|
|
27688
|
+
});
|
|
27689
|
+
}
|
|
27690
|
+
}
|
|
27691
|
+
}
|
|
27692
|
+
return sanitizers;
|
|
27693
|
+
}
|
|
27643
27694
|
function findJavaPathGetFileNameSanitizers(code) {
|
|
27644
27695
|
const sanitizers = [];
|
|
27645
27696
|
const lines = code.split(`
|
|
@@ -27647,15 +27698,16 @@ function findJavaPathGetFileNameSanitizers(code) {
|
|
|
27647
27698
|
const assignmentRe = /^\s*(?:(?:final\s+)?[A-Za-z_][\w.<>?,\s\[\]]*?\s+)?([A-Za-z_]\w*)\s*=\s*(.+?);\s*$/;
|
|
27648
27699
|
const rhsHasGetFileNameRe = /\.\s*getFileName\s*\(\s*\)/;
|
|
27649
27700
|
const rhsHasPathsChainRe = /\b(?:Paths\s*\.\s*get|Path\s*\.\s*of)\s*\(/;
|
|
27701
|
+
const rhsNewFileGetNameRe = /\bnew\s+File\s*\([\s\S]*\)\s*\.\s*getName\s*\(\s*\)/;
|
|
27650
27702
|
const candidates = [];
|
|
27651
27703
|
for (let i2 = 0;i2 < lines.length; i2++) {
|
|
27652
27704
|
const m = assignmentRe.exec(lines[i2]);
|
|
27653
27705
|
if (!m)
|
|
27654
27706
|
continue;
|
|
27655
27707
|
const rhs = m[2];
|
|
27656
|
-
|
|
27657
|
-
|
|
27658
|
-
if (!
|
|
27708
|
+
const isNioGetFileName = rhsHasGetFileNameRe.test(rhs) && rhsHasPathsChainRe.test(rhs);
|
|
27709
|
+
const isNewFileGetName = rhsNewFileGetNameRe.test(rhs);
|
|
27710
|
+
if (!isNioGetFileName && !isNewFileGetName)
|
|
27659
27711
|
continue;
|
|
27660
27712
|
candidates.push({ line: i2 + 1, boundVar: m[1] });
|
|
27661
27713
|
}
|
|
@@ -47084,7 +47136,7 @@ var colors = {
|
|
|
47084
47136
|
};
|
|
47085
47137
|
|
|
47086
47138
|
// src/version.ts
|
|
47087
|
-
var version = "3.
|
|
47139
|
+
var version = "3.213.0";
|
|
47088
47140
|
|
|
47089
47141
|
// src/formatters.ts
|
|
47090
47142
|
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.213.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.213.0"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
72
|
"@types/node": "^25.5.0",
|