cognium-dev 3.126.0 → 3.128.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 +152 -1
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -22607,6 +22607,7 @@ class LanguageSourcesPass {
|
|
|
22607
22607
|
additionalSanitizers.push(...findPythonRegexAllowlistWrapperSanitizers(code));
|
|
22608
22608
|
additionalSanitizers.push(...findPythonSetMembershipXssGuardSanitizers(code));
|
|
22609
22609
|
additionalSanitizers.push(...findPythonDefusedXmlSanitizers(code));
|
|
22610
|
+
additionalSanitizers.push(...findPythonJinjaAutoescapeSanitizers(code));
|
|
22610
22611
|
const pyMisconfigFindings = findPythonPatternFindings(code, graph.ir.meta.file);
|
|
22611
22612
|
for (const finding of pyMisconfigFindings) {
|
|
22612
22613
|
ctx.addFinding(finding);
|
|
@@ -22615,6 +22616,7 @@ class LanguageSourcesPass {
|
|
|
22615
22616
|
if (language === "rust") {
|
|
22616
22617
|
additionalSanitizers.push(...findRustSetAllowlistGuardSanitizers(code));
|
|
22617
22618
|
additionalSanitizers.push(...findRustCanonicalizeGuardSanitizers(code));
|
|
22619
|
+
additionalSanitizers.push(...findRustArgvCommandSanitizers(code));
|
|
22618
22620
|
const rustMisconfigFindings = findRustPatternFindings(code, graph.ir.meta.file);
|
|
22619
22621
|
for (const finding of rustMisconfigFindings) {
|
|
22620
22622
|
ctx.addFinding(finding);
|
|
@@ -22629,6 +22631,9 @@ class LanguageSourcesPass {
|
|
|
22629
22631
|
}
|
|
22630
22632
|
if (language === "java") {
|
|
22631
22633
|
additionalSanitizers.push(...findJavaSafeJsonParseSanitizers(code));
|
|
22634
|
+
additionalSanitizers.push(...findJavaPathNormalizeStartsWithGuardSanitizers(code));
|
|
22635
|
+
additionalSanitizers.push(...findJavaInlineCrlfStripLogSanitizers(code));
|
|
22636
|
+
additionalSanitizers.push(...findJavaArgvFormExecSanitizers(code));
|
|
22632
22637
|
}
|
|
22633
22638
|
if (language === "python" || language === "javascript" || language === "typescript" || language === "go") {
|
|
22634
22639
|
const exfilFindings = findExternalSecretExfiltrationFindings(code, graph.ir.meta.file, language);
|
|
@@ -24580,6 +24585,152 @@ function findJsSsrfAllowlistGuardSanitizers(code) {
|
|
|
24580
24585
|
}
|
|
24581
24586
|
return sanitizers;
|
|
24582
24587
|
}
|
|
24588
|
+
function findJavaPathNormalizeStartsWithGuardSanitizers(code) {
|
|
24589
|
+
const sanitizers = [];
|
|
24590
|
+
const lines = code.split(`
|
|
24591
|
+
`);
|
|
24592
|
+
const resolveNormalizeRe = /\b([A-Za-z_]\w*)\s*=\s*([A-Za-z_]\w*)\s*\.\s*resolve\s*\([^)]*\)\s*\.\s*normalize\s*\(\s*\)/;
|
|
24593
|
+
const startsWithGuardRe = (varName, rootName) => new RegExp(`if\\s*\\(\\s*!\\s*${varName}\\s*\\.\\s*startsWith\\s*\\(\\s*${rootName}\\s*\\)\\s*\\)`);
|
|
24594
|
+
const terminatorRe = /\b(throw|return)\b/;
|
|
24595
|
+
const candidates = [];
|
|
24596
|
+
for (let i2 = 0;i2 < lines.length; i2++) {
|
|
24597
|
+
const m = resolveNormalizeRe.exec(lines[i2]);
|
|
24598
|
+
if (!m)
|
|
24599
|
+
continue;
|
|
24600
|
+
candidates.push({ line: i2 + 1, fullVar: m[1], rootVar: m[2] });
|
|
24601
|
+
}
|
|
24602
|
+
if (candidates.length === 0)
|
|
24603
|
+
return sanitizers;
|
|
24604
|
+
for (const c of candidates) {
|
|
24605
|
+
const guardRe = startsWithGuardRe(c.fullVar, c.rootVar);
|
|
24606
|
+
let guardLine = -1;
|
|
24607
|
+
for (let l = c.line;l < Math.min(lines.length, c.line + 6); l++) {
|
|
24608
|
+
if (!guardRe.test(lines[l]))
|
|
24609
|
+
continue;
|
|
24610
|
+
if (terminatorRe.test(lines[l]) || l + 1 < lines.length && terminatorRe.test(lines[l + 1])) {
|
|
24611
|
+
guardLine = l + 1;
|
|
24612
|
+
break;
|
|
24613
|
+
}
|
|
24614
|
+
}
|
|
24615
|
+
if (guardLine < 0)
|
|
24616
|
+
continue;
|
|
24617
|
+
const varRefRe = new RegExp(`\\b${c.fullVar}\\b`);
|
|
24618
|
+
sanitizers.push({
|
|
24619
|
+
type: "java_path_normalize_startswith_guard",
|
|
24620
|
+
method: "normalize",
|
|
24621
|
+
line: c.line,
|
|
24622
|
+
sanitizes: ["path_traversal", "external_taint_escape"]
|
|
24623
|
+
});
|
|
24624
|
+
for (let l = c.line;l < lines.length; l++) {
|
|
24625
|
+
if (!varRefRe.test(lines[l]))
|
|
24626
|
+
continue;
|
|
24627
|
+
sanitizers.push({
|
|
24628
|
+
type: "java_path_normalize_startswith_guard",
|
|
24629
|
+
method: "normalize",
|
|
24630
|
+
line: l + 1,
|
|
24631
|
+
sanitizes: ["path_traversal", "external_taint_escape"]
|
|
24632
|
+
});
|
|
24633
|
+
}
|
|
24634
|
+
}
|
|
24635
|
+
return sanitizers;
|
|
24636
|
+
}
|
|
24637
|
+
function findJavaInlineCrlfStripLogSanitizers(code) {
|
|
24638
|
+
const sanitizers = [];
|
|
24639
|
+
const lines = code.split(`
|
|
24640
|
+
`);
|
|
24641
|
+
const logCallStart = /\b(?:log|logger|LOG|LOGGER|slog|LOGGER_)\s*\.\s*(?:info|warn|error|debug|trace|fatal|severe|warning|fine|finer|finest|config)\s*\(/;
|
|
24642
|
+
const crlfReplaceAll = /\.\s*replaceAll\s*\(\s*"\[[^"]*\\\\?[rnt][^"]*\]"/;
|
|
24643
|
+
const crlfReplaceChar = /\.\s*replace\s*\(\s*'(?:\\\\?[rnt])'\s*,/;
|
|
24644
|
+
for (let i2 = 0;i2 < lines.length; i2++) {
|
|
24645
|
+
const text = lines[i2];
|
|
24646
|
+
if (!logCallStart.test(text))
|
|
24647
|
+
continue;
|
|
24648
|
+
if (!crlfReplaceAll.test(text) && !crlfReplaceChar.test(text))
|
|
24649
|
+
continue;
|
|
24650
|
+
sanitizers.push({
|
|
24651
|
+
type: "java_inline_crlf_strip_log",
|
|
24652
|
+
method: "replaceAll",
|
|
24653
|
+
line: i2 + 1,
|
|
24654
|
+
sanitizes: ["log_injection", "external_taint_escape"]
|
|
24655
|
+
});
|
|
24656
|
+
}
|
|
24657
|
+
return sanitizers;
|
|
24658
|
+
}
|
|
24659
|
+
function findJavaArgvFormExecSanitizers(code) {
|
|
24660
|
+
const sanitizers = [];
|
|
24661
|
+
const lines = code.split(`
|
|
24662
|
+
`);
|
|
24663
|
+
const argvExecRe = /\.\s*exec\s*\(\s*new\s+String\s*\[\s*\]\s*\{/;
|
|
24664
|
+
const argvPbRe = /\bnew\s+ProcessBuilder\s*\(\s*new\s+String\s*\[\s*\]\s*\{/;
|
|
24665
|
+
for (let i2 = 0;i2 < lines.length; i2++) {
|
|
24666
|
+
const text = lines[i2];
|
|
24667
|
+
if (!argvExecRe.test(text) && !argvPbRe.test(text))
|
|
24668
|
+
continue;
|
|
24669
|
+
sanitizers.push({
|
|
24670
|
+
type: "java_argv_form_exec",
|
|
24671
|
+
method: "exec",
|
|
24672
|
+
line: i2 + 1,
|
|
24673
|
+
sanitizes: ["command_injection", "external_taint_escape"]
|
|
24674
|
+
});
|
|
24675
|
+
}
|
|
24676
|
+
return sanitizers;
|
|
24677
|
+
}
|
|
24678
|
+
function findRustArgvCommandSanitizers(code) {
|
|
24679
|
+
const sanitizers = [];
|
|
24680
|
+
const lines = code.split(`
|
|
24681
|
+
`);
|
|
24682
|
+
const argvCommandRe = /\bCommand\s*::\s*new\s*\(\s*"[^"]*"\s*\)\s*\.\s*arg\s*\(/;
|
|
24683
|
+
const shellArgvRe = /\bCommand\s*::\s*new\s*\(\s*"(?:sh|bash|zsh|ksh|dash|cmd(?:\.exe)?|powershell|pwsh)"\s*\)\s*\.\s*arg\s*\(\s*"-c"/;
|
|
24684
|
+
for (let i2 = 0;i2 < lines.length; i2++) {
|
|
24685
|
+
const text = lines[i2];
|
|
24686
|
+
if (!argvCommandRe.test(text))
|
|
24687
|
+
continue;
|
|
24688
|
+
if (shellArgvRe.test(text))
|
|
24689
|
+
continue;
|
|
24690
|
+
sanitizers.push({
|
|
24691
|
+
type: "rust_argv_command",
|
|
24692
|
+
method: "arg",
|
|
24693
|
+
line: i2 + 1,
|
|
24694
|
+
sanitizes: ["command_injection", "external_taint_escape"]
|
|
24695
|
+
});
|
|
24696
|
+
}
|
|
24697
|
+
return sanitizers;
|
|
24698
|
+
}
|
|
24699
|
+
function findPythonJinjaAutoescapeSanitizers(code) {
|
|
24700
|
+
const sanitizers = [];
|
|
24701
|
+
const lines = code.split(`
|
|
24702
|
+
`);
|
|
24703
|
+
const envAssignRe = /\b([A-Za-z_]\w*)\s*=\s*Environment\s*\(/;
|
|
24704
|
+
const autoescapeOnRe = /\bautoescape\s*=/;
|
|
24705
|
+
const autoescapeOffRe = /\bautoescape\s*=\s*(?:False|None|0)\b/;
|
|
24706
|
+
const envVars = new Set;
|
|
24707
|
+
for (let i2 = 0;i2 < lines.length; i2++) {
|
|
24708
|
+
const m = envAssignRe.exec(lines[i2]);
|
|
24709
|
+
if (!m)
|
|
24710
|
+
continue;
|
|
24711
|
+
if (!autoescapeOnRe.test(lines[i2]))
|
|
24712
|
+
continue;
|
|
24713
|
+
if (autoescapeOffRe.test(lines[i2]))
|
|
24714
|
+
continue;
|
|
24715
|
+
envVars.add(m[1]);
|
|
24716
|
+
}
|
|
24717
|
+
if (envVars.size === 0)
|
|
24718
|
+
return sanitizers;
|
|
24719
|
+
for (const envVar of envVars) {
|
|
24720
|
+
const renderChainRe = new RegExp(`\\b${envVar}\\s*\\.\\s*get_template\\s*\\([^)]*\\)\\s*\\.\\s*render\\s*\\(`);
|
|
24721
|
+
for (let i2 = 0;i2 < lines.length; i2++) {
|
|
24722
|
+
if (!renderChainRe.test(lines[i2]))
|
|
24723
|
+
continue;
|
|
24724
|
+
sanitizers.push({
|
|
24725
|
+
type: "python_jinja_autoescape",
|
|
24726
|
+
method: "render",
|
|
24727
|
+
line: i2 + 1,
|
|
24728
|
+
sanitizes: ["xss", "external_taint_escape"]
|
|
24729
|
+
});
|
|
24730
|
+
}
|
|
24731
|
+
}
|
|
24732
|
+
return sanitizers;
|
|
24733
|
+
}
|
|
24583
24734
|
function collectEnvSecretVars(lines, language) {
|
|
24584
24735
|
const out2 = new Map;
|
|
24585
24736
|
for (let i2 = 0;i2 < lines.length; i2++) {
|
|
@@ -38121,7 +38272,7 @@ var colors = {
|
|
|
38121
38272
|
};
|
|
38122
38273
|
|
|
38123
38274
|
// src/version.ts
|
|
38124
|
-
var version = "3.
|
|
38275
|
+
var version = "3.128.0";
|
|
38125
38276
|
|
|
38126
38277
|
// src/formatters.ts
|
|
38127
38278
|
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.128.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.128.0"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
72
|
"@types/node": "^25.5.0",
|