cognium-dev 3.72.0 → 3.74.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 +416 -10
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -11437,11 +11437,17 @@ var DEFAULT_SANITIZERS = [
|
|
|
11437
11437
|
{ method: "toRealPath", class: "Path", removes: ["path_traversal"] },
|
|
11438
11438
|
{ method: "file_name", removes: ["path_traversal"] },
|
|
11439
11439
|
{ method: "canonicalize", removes: ["path_traversal"] },
|
|
11440
|
-
{ method: "Base", class: "filepath", removes: ["path_traversal"] },
|
|
11441
|
-
{ method: "Base", class: "path", removes: ["path_traversal"] },
|
|
11442
|
-
{ method: "Clean", class: "filepath", removes: ["path_traversal"] },
|
|
11443
|
-
{ method: "Clean", class: "path", removes: ["path_traversal"] },
|
|
11444
|
-
{ method: "EvalSymlinks", class: "filepath", removes: ["path_traversal"] },
|
|
11440
|
+
{ method: "Base", class: "filepath", removes: ["path_traversal", "external_taint_escape"] },
|
|
11441
|
+
{ method: "Base", class: "path", removes: ["path_traversal", "external_taint_escape"] },
|
|
11442
|
+
{ method: "Clean", class: "filepath", removes: ["path_traversal", "external_taint_escape"] },
|
|
11443
|
+
{ method: "Clean", class: "path", removes: ["path_traversal", "external_taint_escape"] },
|
|
11444
|
+
{ method: "EvalSymlinks", class: "filepath", removes: ["path_traversal", "external_taint_escape"] },
|
|
11445
|
+
{ method: "EscapeString", class: "html", removes: ["xss", "external_taint_escape", "log_injection", "open_redirect"] },
|
|
11446
|
+
{ method: "HTMLEscapeString", class: "template", removes: ["xss", "external_taint_escape", "log_injection", "open_redirect"] },
|
|
11447
|
+
{ method: "JSEscapeString", class: "template", removes: ["xss", "external_taint_escape", "log_injection"] },
|
|
11448
|
+
{ method: "URLQueryEscaper", class: "template", removes: ["xss", "external_taint_escape", "open_redirect"] },
|
|
11449
|
+
{ method: "QueryEscape", class: "url", removes: ["xss", "external_taint_escape", "open_redirect"] },
|
|
11450
|
+
{ method: "PathEscape", class: "url", removes: ["xss", "external_taint_escape", "open_redirect"] },
|
|
11445
11451
|
{ method: "replace", removes: ["log_injection"] },
|
|
11446
11452
|
{ method: "encodeForLDAP", removes: ["ldap_injection"] },
|
|
11447
11453
|
{ method: "encodeForDN", removes: ["ldap_injection"] },
|
|
@@ -11865,6 +11871,17 @@ function findSources(calls, types, patterns, sourceLines, language) {
|
|
|
11865
11871
|
s.variable = m[1];
|
|
11866
11872
|
}
|
|
11867
11873
|
}
|
|
11874
|
+
if (language === "go" && sourceLines) {
|
|
11875
|
+
const GO_ASSIGN_LHS = /^\s*(?:var\s+)?([A-Za-z_]\w*)(?:\s*,\s*[A-Za-z_]\w*)*\s*(?::\s*[A-Za-z_][\w.]*\s*)?(?::?=)(?!=)/;
|
|
11876
|
+
for (const s of result) {
|
|
11877
|
+
if (s.variable && s.variable.length > 0)
|
|
11878
|
+
continue;
|
|
11879
|
+
const lineText = sourceLines[s.line - 1] ?? "";
|
|
11880
|
+
const m = GO_ASSIGN_LHS.exec(lineText);
|
|
11881
|
+
if (m)
|
|
11882
|
+
s.variable = m[1];
|
|
11883
|
+
}
|
|
11884
|
+
}
|
|
11868
11885
|
return result;
|
|
11869
11886
|
}
|
|
11870
11887
|
function isInterproceduralTaintableType(typeName) {
|
|
@@ -11981,6 +11998,48 @@ function isSafePythonSubprocessCall(call, pattern, language) {
|
|
|
11981
11998
|
}
|
|
11982
11999
|
return true;
|
|
11983
12000
|
}
|
|
12001
|
+
function isSafeGoExecCommandCall(call, pattern, language) {
|
|
12002
|
+
if (language !== "go")
|
|
12003
|
+
return false;
|
|
12004
|
+
if (pattern.type !== "command_injection")
|
|
12005
|
+
return false;
|
|
12006
|
+
if (pattern.class !== "exec")
|
|
12007
|
+
return false;
|
|
12008
|
+
if (pattern.method !== "Command" && pattern.method !== "CommandContext")
|
|
12009
|
+
return false;
|
|
12010
|
+
const programArgPos = pattern.method === "CommandContext" ? 1 : 0;
|
|
12011
|
+
const programArg = call.arguments.find((a) => a.position === programArgPos);
|
|
12012
|
+
if (!programArg)
|
|
12013
|
+
return false;
|
|
12014
|
+
let program;
|
|
12015
|
+
if (programArg.literal !== null && programArg.literal !== undefined) {
|
|
12016
|
+
program = String(programArg.literal).split("/").pop() ?? String(programArg.literal);
|
|
12017
|
+
} else {
|
|
12018
|
+
const expr = (programArg.expression ?? "").trim();
|
|
12019
|
+
if (!(expr.startsWith('"') || expr.startsWith("`") || expr.startsWith("'"))) {
|
|
12020
|
+
return false;
|
|
12021
|
+
}
|
|
12022
|
+
const stripped = expr.slice(1, -1);
|
|
12023
|
+
program = stripped.split("/").pop() ?? stripped;
|
|
12024
|
+
}
|
|
12025
|
+
const SHELL_PROGRAMS = new Set([
|
|
12026
|
+
"sh",
|
|
12027
|
+
"bash",
|
|
12028
|
+
"zsh",
|
|
12029
|
+
"dash",
|
|
12030
|
+
"ash",
|
|
12031
|
+
"ksh",
|
|
12032
|
+
"cmd",
|
|
12033
|
+
"cmd.exe",
|
|
12034
|
+
"powershell",
|
|
12035
|
+
"pwsh",
|
|
12036
|
+
"powershell.exe",
|
|
12037
|
+
"pwsh.exe"
|
|
12038
|
+
]);
|
|
12039
|
+
if (SHELL_PROGRAMS.has(program))
|
|
12040
|
+
return false;
|
|
12041
|
+
return true;
|
|
12042
|
+
}
|
|
11984
12043
|
var CLASS_LITERAL_RE = /^(?:[A-Za-z_][\w]*\.)*[A-Z][\w]*(?:\[\])*\.class$/;
|
|
11985
12044
|
function argIsClassLiteral(call, position) {
|
|
11986
12045
|
const arg = call.arguments.find((a) => a.position === position);
|
|
@@ -12002,6 +12061,9 @@ function findSinks(calls, patterns, typeHierarchy, language, sourceLines) {
|
|
|
12002
12061
|
if (isSafePythonSubprocessCall(call, pattern, language)) {
|
|
12003
12062
|
continue;
|
|
12004
12063
|
}
|
|
12064
|
+
if (isSafeGoExecCommandCall(call, pattern, language)) {
|
|
12065
|
+
continue;
|
|
12066
|
+
}
|
|
12005
12067
|
if (pattern.safe_if_class_literal_at !== undefined && argIsClassLiteral(call, pattern.safe_if_class_literal_at)) {
|
|
12006
12068
|
continue;
|
|
12007
12069
|
}
|
|
@@ -17863,7 +17925,7 @@ class GoPlugin extends BaseLanguagePlugin {
|
|
|
17863
17925
|
type: "command_injection",
|
|
17864
17926
|
cwe: "CWE-78",
|
|
17865
17927
|
severity: "critical",
|
|
17866
|
-
argPositions: [
|
|
17928
|
+
argPositions: []
|
|
17867
17929
|
},
|
|
17868
17930
|
{
|
|
17869
17931
|
method: "CommandContext",
|
|
@@ -17871,7 +17933,7 @@ class GoPlugin extends BaseLanguagePlugin {
|
|
|
17871
17933
|
type: "command_injection",
|
|
17872
17934
|
cwe: "CWE-78",
|
|
17873
17935
|
severity: "critical",
|
|
17874
|
-
argPositions: [
|
|
17936
|
+
argPositions: []
|
|
17875
17937
|
},
|
|
17876
17938
|
{
|
|
17877
17939
|
method: "Open",
|
|
@@ -17960,6 +18022,110 @@ class GoPlugin extends BaseLanguagePlugin {
|
|
|
17960
18022
|
cwe: "CWE-502",
|
|
17961
18023
|
severity: "medium",
|
|
17962
18024
|
argPositions: [0]
|
|
18025
|
+
},
|
|
18026
|
+
{
|
|
18027
|
+
method: "Print",
|
|
18028
|
+
class: "log",
|
|
18029
|
+
type: "log_injection",
|
|
18030
|
+
cwe: "CWE-117",
|
|
18031
|
+
severity: "medium",
|
|
18032
|
+
argPositions: []
|
|
18033
|
+
},
|
|
18034
|
+
{
|
|
18035
|
+
method: "Println",
|
|
18036
|
+
class: "log",
|
|
18037
|
+
type: "log_injection",
|
|
18038
|
+
cwe: "CWE-117",
|
|
18039
|
+
severity: "medium",
|
|
18040
|
+
argPositions: []
|
|
18041
|
+
},
|
|
18042
|
+
{
|
|
18043
|
+
method: "Printf",
|
|
18044
|
+
class: "log",
|
|
18045
|
+
type: "log_injection",
|
|
18046
|
+
cwe: "CWE-117",
|
|
18047
|
+
severity: "medium",
|
|
18048
|
+
argPositions: []
|
|
18049
|
+
},
|
|
18050
|
+
{
|
|
18051
|
+
method: "Fatal",
|
|
18052
|
+
class: "log",
|
|
18053
|
+
type: "log_injection",
|
|
18054
|
+
cwe: "CWE-117",
|
|
18055
|
+
severity: "medium",
|
|
18056
|
+
argPositions: []
|
|
18057
|
+
},
|
|
18058
|
+
{
|
|
18059
|
+
method: "Fatalln",
|
|
18060
|
+
class: "log",
|
|
18061
|
+
type: "log_injection",
|
|
18062
|
+
cwe: "CWE-117",
|
|
18063
|
+
severity: "medium",
|
|
18064
|
+
argPositions: []
|
|
18065
|
+
},
|
|
18066
|
+
{
|
|
18067
|
+
method: "Fatalf",
|
|
18068
|
+
class: "log",
|
|
18069
|
+
type: "log_injection",
|
|
18070
|
+
cwe: "CWE-117",
|
|
18071
|
+
severity: "medium",
|
|
18072
|
+
argPositions: []
|
|
18073
|
+
},
|
|
18074
|
+
{
|
|
18075
|
+
method: "Panic",
|
|
18076
|
+
class: "log",
|
|
18077
|
+
type: "log_injection",
|
|
18078
|
+
cwe: "CWE-117",
|
|
18079
|
+
severity: "medium",
|
|
18080
|
+
argPositions: []
|
|
18081
|
+
},
|
|
18082
|
+
{
|
|
18083
|
+
method: "Panicln",
|
|
18084
|
+
class: "log",
|
|
18085
|
+
type: "log_injection",
|
|
18086
|
+
cwe: "CWE-117",
|
|
18087
|
+
severity: "medium",
|
|
18088
|
+
argPositions: []
|
|
18089
|
+
},
|
|
18090
|
+
{
|
|
18091
|
+
method: "Panicf",
|
|
18092
|
+
class: "log",
|
|
18093
|
+
type: "log_injection",
|
|
18094
|
+
cwe: "CWE-117",
|
|
18095
|
+
severity: "medium",
|
|
18096
|
+
argPositions: []
|
|
18097
|
+
},
|
|
18098
|
+
{
|
|
18099
|
+
method: "Parse",
|
|
18100
|
+
class: "Template",
|
|
18101
|
+
type: "code_injection",
|
|
18102
|
+
cwe: "CWE-94",
|
|
18103
|
+
severity: "high",
|
|
18104
|
+
argPositions: [0]
|
|
18105
|
+
},
|
|
18106
|
+
{
|
|
18107
|
+
method: "ParseFiles",
|
|
18108
|
+
class: "template",
|
|
18109
|
+
type: "code_injection",
|
|
18110
|
+
cwe: "CWE-94",
|
|
18111
|
+
severity: "high",
|
|
18112
|
+
argPositions: []
|
|
18113
|
+
},
|
|
18114
|
+
{
|
|
18115
|
+
method: "ParseGlob",
|
|
18116
|
+
class: "template",
|
|
18117
|
+
type: "code_injection",
|
|
18118
|
+
cwe: "CWE-94",
|
|
18119
|
+
severity: "high",
|
|
18120
|
+
argPositions: [0]
|
|
18121
|
+
},
|
|
18122
|
+
{
|
|
18123
|
+
method: "ParseFS",
|
|
18124
|
+
class: "template",
|
|
18125
|
+
type: "code_injection",
|
|
18126
|
+
cwe: "CWE-94",
|
|
18127
|
+
severity: "high",
|
|
18128
|
+
argPositions: []
|
|
17963
18129
|
}
|
|
17964
18130
|
];
|
|
17965
18131
|
}
|
|
@@ -21124,6 +21290,11 @@ class LanguageSourcesPass {
|
|
|
21124
21290
|
ctx.addFinding(finding);
|
|
21125
21291
|
}
|
|
21126
21292
|
additionalSanitizers.push(...findBashRegexAllowlistSanitizers(code));
|
|
21293
|
+
additionalSanitizers.push(...findBashRealpathPrefixGuardSanitizers(code));
|
|
21294
|
+
}
|
|
21295
|
+
if (language === "go") {
|
|
21296
|
+
additionalSanitizers.push(...findGoMapAllowlistGuardSanitizers(code));
|
|
21297
|
+
additionalSanitizers.push(...findGoHtmlTemplateImportSanitizers(code));
|
|
21127
21298
|
}
|
|
21128
21299
|
attachSourceLineCode(additionalSources, additionalSinks, code);
|
|
21129
21300
|
return { additionalSources, additionalSinks, additionalSanitizers, pyTaintedVars, pySanitizedVars, jsTaintedVars };
|
|
@@ -22093,6 +22264,152 @@ function isSafeBashAllowlistRegex(literal) {
|
|
|
22093
22264
|
}
|
|
22094
22265
|
return consumed === body2.length;
|
|
22095
22266
|
}
|
|
22267
|
+
function findBashRealpathPrefixGuardSanitizers(code) {
|
|
22268
|
+
const sanitizers = [];
|
|
22269
|
+
const lines = code.split(`
|
|
22270
|
+
`);
|
|
22271
|
+
const caseOpen = /^\s*case\s+"?\$\{?\w+\}?"?\s+in\b/;
|
|
22272
|
+
const esacClose = /^\s*esac\b/;
|
|
22273
|
+
const armOpener = /^\s*([^)\s][^)]*?)\)/;
|
|
22274
|
+
const prefixArm = /^(?:"\$\{?\w+\}?"|"[^"]*"|\/[\w\-./]+|\$\{?\w+\}?|[\w\-./]+)(?:\/|\*)/;
|
|
22275
|
+
const catchAllArm = /^(?:\*|\\\*)$/;
|
|
22276
|
+
let i2 = 0;
|
|
22277
|
+
while (i2 < lines.length) {
|
|
22278
|
+
if (!caseOpen.test(lines[i2])) {
|
|
22279
|
+
i2++;
|
|
22280
|
+
continue;
|
|
22281
|
+
}
|
|
22282
|
+
let caseEnd = -1;
|
|
22283
|
+
for (let j = i2 + 1;j < lines.length; j++) {
|
|
22284
|
+
if (esacClose.test(lines[j])) {
|
|
22285
|
+
caseEnd = j;
|
|
22286
|
+
break;
|
|
22287
|
+
}
|
|
22288
|
+
}
|
|
22289
|
+
if (caseEnd === -1) {
|
|
22290
|
+
i2++;
|
|
22291
|
+
continue;
|
|
22292
|
+
}
|
|
22293
|
+
let hasPrefixArm = false;
|
|
22294
|
+
let hasTerminalCatchAll = false;
|
|
22295
|
+
for (let j = i2 + 1;j < caseEnd; j++) {
|
|
22296
|
+
const armMatch = armOpener.exec(lines[j]);
|
|
22297
|
+
if (!armMatch)
|
|
22298
|
+
continue;
|
|
22299
|
+
const pattern = armMatch[1].trim();
|
|
22300
|
+
if (catchAllArm.test(pattern)) {
|
|
22301
|
+
let bodyEnd = caseEnd;
|
|
22302
|
+
for (let k = j + 1;k < caseEnd; k++) {
|
|
22303
|
+
if (armOpener.test(lines[k])) {
|
|
22304
|
+
bodyEnd = k;
|
|
22305
|
+
break;
|
|
22306
|
+
}
|
|
22307
|
+
}
|
|
22308
|
+
const armBody = lines.slice(j, bodyEnd).join(" ");
|
|
22309
|
+
if (/\b(exit|return|die)\b/.test(armBody)) {
|
|
22310
|
+
hasTerminalCatchAll = true;
|
|
22311
|
+
}
|
|
22312
|
+
} else if (prefixArm.test(pattern)) {
|
|
22313
|
+
hasPrefixArm = true;
|
|
22314
|
+
}
|
|
22315
|
+
}
|
|
22316
|
+
if (hasPrefixArm && hasTerminalCatchAll) {
|
|
22317
|
+
for (let l = i2 + 1;l <= caseEnd + 1; l++) {
|
|
22318
|
+
sanitizers.push({
|
|
22319
|
+
type: "realpath_prefix_guard",
|
|
22320
|
+
method: "case",
|
|
22321
|
+
line: l,
|
|
22322
|
+
sanitizes: [
|
|
22323
|
+
"path_traversal",
|
|
22324
|
+
"command_injection",
|
|
22325
|
+
"code_injection",
|
|
22326
|
+
"ssrf",
|
|
22327
|
+
"open_redirect",
|
|
22328
|
+
"log_injection"
|
|
22329
|
+
]
|
|
22330
|
+
});
|
|
22331
|
+
}
|
|
22332
|
+
}
|
|
22333
|
+
i2 = caseEnd + 1;
|
|
22334
|
+
}
|
|
22335
|
+
return sanitizers;
|
|
22336
|
+
}
|
|
22337
|
+
function findGoMapAllowlistGuardSanitizers(code) {
|
|
22338
|
+
const sanitizers = [];
|
|
22339
|
+
const lines = code.split(`
|
|
22340
|
+
`);
|
|
22341
|
+
const guardOpen = /^\s*if\s+!\s*([A-Za-z_][A-Za-z0-9_]*)\s*\[\s*[A-Za-z_][A-Za-z0-9_]*\s*\]\s*\{/;
|
|
22342
|
+
const allowlistName = /^(?:[A-Z][A-Z0-9_]+|.*?(allowed|accepted|whitelist|permitted|valid|approved).*)$/i;
|
|
22343
|
+
for (let i2 = 0;i2 < lines.length; i2++) {
|
|
22344
|
+
const m = guardOpen.exec(lines[i2]);
|
|
22345
|
+
if (!m)
|
|
22346
|
+
continue;
|
|
22347
|
+
const mapName = m[1];
|
|
22348
|
+
if (!allowlistName.test(mapName))
|
|
22349
|
+
continue;
|
|
22350
|
+
let depth = 1;
|
|
22351
|
+
let closeLine = -1;
|
|
22352
|
+
let bodyHasTerminator = false;
|
|
22353
|
+
const maxScan = Math.min(lines.length, i2 + 26);
|
|
22354
|
+
for (let j = i2 + 1;j < maxScan; j++) {
|
|
22355
|
+
const line = lines[j];
|
|
22356
|
+
if (/\b(return|panic\s*\(|os\.Exit\s*\()/.test(line)) {
|
|
22357
|
+
bodyHasTerminator = true;
|
|
22358
|
+
}
|
|
22359
|
+
for (const ch of line) {
|
|
22360
|
+
if (ch === "{")
|
|
22361
|
+
depth++;
|
|
22362
|
+
else if (ch === "}")
|
|
22363
|
+
depth--;
|
|
22364
|
+
}
|
|
22365
|
+
if (depth === 0) {
|
|
22366
|
+
closeLine = j;
|
|
22367
|
+
break;
|
|
22368
|
+
}
|
|
22369
|
+
}
|
|
22370
|
+
if (closeLine === -1 || !bodyHasTerminator)
|
|
22371
|
+
continue;
|
|
22372
|
+
for (let l = closeLine + 2;l <= lines.length; l++) {
|
|
22373
|
+
sanitizers.push({
|
|
22374
|
+
type: "go_map_allowlist_guard",
|
|
22375
|
+
method: "if",
|
|
22376
|
+
line: l,
|
|
22377
|
+
sanitizes: [
|
|
22378
|
+
"ssrf",
|
|
22379
|
+
"open_redirect",
|
|
22380
|
+
"path_traversal",
|
|
22381
|
+
"sql_injection",
|
|
22382
|
+
"command_injection",
|
|
22383
|
+
"external_taint_escape"
|
|
22384
|
+
]
|
|
22385
|
+
});
|
|
22386
|
+
}
|
|
22387
|
+
}
|
|
22388
|
+
return sanitizers;
|
|
22389
|
+
}
|
|
22390
|
+
function findGoHtmlTemplateImportSanitizers(code) {
|
|
22391
|
+
const sanitizers = [];
|
|
22392
|
+
const hasHtmlTemplate = /["\s]html\/template["\s]/.test(code);
|
|
22393
|
+
const hasTextTemplate = /["\s]text\/template["\s]/.test(code);
|
|
22394
|
+
if (!hasHtmlTemplate)
|
|
22395
|
+
return sanitizers;
|
|
22396
|
+
if (hasTextTemplate)
|
|
22397
|
+
return sanitizers;
|
|
22398
|
+
const lines = code.split(`
|
|
22399
|
+
`);
|
|
22400
|
+
const execCall = /\.(Execute|ExecuteTemplate)\s*\(/;
|
|
22401
|
+
for (let i2 = 0;i2 < lines.length; i2++) {
|
|
22402
|
+
if (!execCall.test(lines[i2]))
|
|
22403
|
+
continue;
|
|
22404
|
+
sanitizers.push({
|
|
22405
|
+
type: "html_template_auto_escape",
|
|
22406
|
+
method: "Execute",
|
|
22407
|
+
line: i2 + 1,
|
|
22408
|
+
sanitizes: ["xss", "external_taint_escape", "open_redirect"]
|
|
22409
|
+
});
|
|
22410
|
+
}
|
|
22411
|
+
return sanitizers;
|
|
22412
|
+
}
|
|
22096
22413
|
|
|
22097
22414
|
// ../circle-ir/dist/analysis/passes/sink-filter-pass.js
|
|
22098
22415
|
var JS_XSS_SANITIZERS = [
|
|
@@ -22917,6 +23234,40 @@ class TaintPropagationPass {
|
|
|
22917
23234
|
}
|
|
22918
23235
|
return true;
|
|
22919
23236
|
});
|
|
23237
|
+
if (sanitizers && sanitizers.length > 0) {
|
|
23238
|
+
const sanitizersByLine = new Map;
|
|
23239
|
+
for (const san of sanitizers) {
|
|
23240
|
+
const arr = sanitizersByLine.get(san.line) ?? [];
|
|
23241
|
+
arr.push(san);
|
|
23242
|
+
sanitizersByLine.set(san.line, arr);
|
|
23243
|
+
}
|
|
23244
|
+
finalFlows = finalFlows.filter((f) => {
|
|
23245
|
+
if (f.sink_type === "external_taint_escape") {
|
|
23246
|
+
const lo = Math.min(f.source_line, f.sink_line);
|
|
23247
|
+
const hi = Math.max(f.source_line, f.sink_line);
|
|
23248
|
+
for (let line = lo;line <= hi; line++) {
|
|
23249
|
+
const sansAtLine = sanitizersByLine.get(line);
|
|
23250
|
+
if (!sansAtLine)
|
|
23251
|
+
continue;
|
|
23252
|
+
for (const san of sansAtLine) {
|
|
23253
|
+
if (san.sanitizes.includes(f.sink_type)) {
|
|
23254
|
+
return false;
|
|
23255
|
+
}
|
|
23256
|
+
}
|
|
23257
|
+
}
|
|
23258
|
+
return true;
|
|
23259
|
+
}
|
|
23260
|
+
const sansAtSink = sanitizersByLine.get(f.sink_line);
|
|
23261
|
+
if (!sansAtSink || sansAtSink.length === 0)
|
|
23262
|
+
return true;
|
|
23263
|
+
for (const san of sansAtSink) {
|
|
23264
|
+
if (san.sanitizes.includes(f.sink_type)) {
|
|
23265
|
+
return false;
|
|
23266
|
+
}
|
|
23267
|
+
}
|
|
23268
|
+
return true;
|
|
23269
|
+
});
|
|
23270
|
+
}
|
|
22920
23271
|
if (ctx.language === "java" && typeof ctx.code === "string") {
|
|
22921
23272
|
finalFlows = finalFlows.filter((f) => {
|
|
22922
23273
|
if (f.sink_type !== "path_traversal" && f.sink_type !== "xxe")
|
|
@@ -23710,7 +24061,19 @@ function analyzeInterprocedural2(graphOrTypes, callsOrSources, dfgOrSinks, sourc
|
|
|
23710
24061
|
"BufferedWriter",
|
|
23711
24062
|
"PrintStream",
|
|
23712
24063
|
"PrintWriter",
|
|
23713
|
-
"ObjectOutputStream"
|
|
24064
|
+
"ObjectOutputStream",
|
|
24065
|
+
"Query",
|
|
24066
|
+
"QueryRow",
|
|
24067
|
+
"QueryContext",
|
|
24068
|
+
"QueryRowContext",
|
|
24069
|
+
"Exec",
|
|
24070
|
+
"ExecContext",
|
|
24071
|
+
"EscapeString",
|
|
24072
|
+
"HTMLEscapeString",
|
|
24073
|
+
"JSEscapeString",
|
|
24074
|
+
"URLQueryEscaper",
|
|
24075
|
+
"Command",
|
|
24076
|
+
"CommandContext"
|
|
23714
24077
|
]);
|
|
23715
24078
|
const sanitizerMethods = new Set;
|
|
23716
24079
|
for (const san of sanitizers) {
|
|
@@ -24128,7 +24491,50 @@ class InterproceduralPass {
|
|
|
24128
24491
|
if (additionalSinks.length > 0) {
|
|
24129
24492
|
attachSourceLineCode([], additionalSinks, ctx.code);
|
|
24130
24493
|
}
|
|
24131
|
-
|
|
24494
|
+
let filteredAdditionalFlows = additionalFlows;
|
|
24495
|
+
let filteredAdditionalSinks = additionalSinks;
|
|
24496
|
+
if (sanitizers && sanitizers.length > 0) {
|
|
24497
|
+
const sanitizersByLine = new Map;
|
|
24498
|
+
for (const san of sanitizers) {
|
|
24499
|
+
const arr = sanitizersByLine.get(san.line) ?? [];
|
|
24500
|
+
arr.push(san);
|
|
24501
|
+
sanitizersByLine.set(san.line, arr);
|
|
24502
|
+
}
|
|
24503
|
+
const sanitizedSinkKeys = new Set;
|
|
24504
|
+
filteredAdditionalFlows = additionalFlows.filter((f) => {
|
|
24505
|
+
if (f.sink_type === "external_taint_escape") {
|
|
24506
|
+
const lo = Math.min(f.source_line, f.sink_line);
|
|
24507
|
+
const hi = Math.max(f.source_line, f.sink_line);
|
|
24508
|
+
for (let line = lo;line <= hi; line++) {
|
|
24509
|
+
const sansAtLine = sanitizersByLine.get(line);
|
|
24510
|
+
if (!sansAtLine)
|
|
24511
|
+
continue;
|
|
24512
|
+
for (const san of sansAtLine) {
|
|
24513
|
+
if (san.sanitizes.includes(f.sink_type)) {
|
|
24514
|
+
sanitizedSinkKeys.add(`${f.sink_line}:${f.sink_type}`);
|
|
24515
|
+
return false;
|
|
24516
|
+
}
|
|
24517
|
+
}
|
|
24518
|
+
}
|
|
24519
|
+
return true;
|
|
24520
|
+
}
|
|
24521
|
+
const sansAtSink = sanitizersByLine.get(f.sink_line);
|
|
24522
|
+
if (!sansAtSink || sansAtSink.length === 0)
|
|
24523
|
+
return true;
|
|
24524
|
+
for (const san of sansAtSink) {
|
|
24525
|
+
if (san.sanitizes.includes(f.sink_type)) {
|
|
24526
|
+
return false;
|
|
24527
|
+
}
|
|
24528
|
+
}
|
|
24529
|
+
return true;
|
|
24530
|
+
});
|
|
24531
|
+
filteredAdditionalSinks = additionalSinks.filter((s) => {
|
|
24532
|
+
if (s.type !== "external_taint_escape")
|
|
24533
|
+
return true;
|
|
24534
|
+
return !sanitizedSinkKeys.has(`${s.line}:${s.type}`);
|
|
24535
|
+
});
|
|
24536
|
+
}
|
|
24537
|
+
return { additionalSinks: filteredAdditionalSinks, additionalFlows: filteredAdditionalFlows, interprocedural };
|
|
24132
24538
|
}
|
|
24133
24539
|
}
|
|
24134
24540
|
|
|
@@ -32076,7 +32482,7 @@ var colors = {
|
|
|
32076
32482
|
};
|
|
32077
32483
|
|
|
32078
32484
|
// src/version.ts
|
|
32079
|
-
var version = "3.
|
|
32485
|
+
var version = "3.74.0";
|
|
32080
32486
|
|
|
32081
32487
|
// src/formatters.ts
|
|
32082
32488
|
var SINK_SEVERITY = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cognium-dev",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.74.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.74.0"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
71
|
"@types/node": "^25.5.0",
|