cognium-dev 3.174.0 → 3.176.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 +159 -8
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -10553,6 +10553,33 @@ var DEFAULT_SOURCES = [
|
|
|
10553
10553
|
{ method: "decode", class: "JWT", type: "http_header", severity: "high", return_tainted: true, languages: ["java"] },
|
|
10554
10554
|
{ method: "ParseUnverified", class: "jwt", type: "http_header", severity: "high", return_tainted: true, languages: ["go"] }
|
|
10555
10555
|
];
|
|
10556
|
+
var OPEN_REDIRECT_FRAMEWORK_SINKS = [
|
|
10557
|
+
{ method: "HttpResponseRedirect", type: "open_redirect", cwe: "CWE-601", severity: "medium", arg_positions: [0], languages: ["python"] },
|
|
10558
|
+
{ method: "HttpResponsePermanentRedirect", type: "open_redirect", cwe: "CWE-601", severity: "medium", arg_positions: [0], languages: ["python"] },
|
|
10559
|
+
{ method: "RedirectResponse", type: "open_redirect", cwe: "CWE-601", severity: "medium", arg_positions: [0], languages: ["python"] },
|
|
10560
|
+
{ method: "redirect", class: "Context", type: "open_redirect", cwe: "CWE-601", severity: "medium", arg_positions: [0], languages: ["javascript", "typescript"] },
|
|
10561
|
+
{ method: "redirect", class: "FastifyReply", type: "open_redirect", cwe: "CWE-601", severity: "medium", arg_positions: [0], languages: ["javascript", "typescript"] },
|
|
10562
|
+
{ method: "location", class: "Response", type: "open_redirect", cwe: "CWE-601", severity: "medium", arg_positions: [0], languages: ["javascript", "typescript"] },
|
|
10563
|
+
{ method: "redirect", class: "NextResponse", type: "open_redirect", cwe: "CWE-601", severity: "medium", arg_positions: [0], languages: ["javascript", "typescript"] },
|
|
10564
|
+
{ method: "RedirectView", class: "RedirectView", type: "open_redirect", cwe: "CWE-601", severity: "high", arg_positions: [0], languages: ["java"] },
|
|
10565
|
+
{ method: "setUrl", class: "RedirectView", type: "open_redirect", cwe: "CWE-601", severity: "high", arg_positions: [0], languages: ["java"] },
|
|
10566
|
+
{ method: "seeOther", class: "Response", type: "open_redirect", cwe: "CWE-601", severity: "high", arg_positions: [0], languages: ["java"] },
|
|
10567
|
+
{ method: "temporaryRedirect", class: "Response", type: "open_redirect", cwe: "CWE-601", severity: "high", arg_positions: [0], languages: ["java"] },
|
|
10568
|
+
{ method: "Redirect", class: "Context", type: "open_redirect", cwe: "CWE-601", severity: "medium", arg_positions: [1], languages: ["go"] },
|
|
10569
|
+
{ method: "Redirect", class: "Ctx", type: "open_redirect", cwe: "CWE-601", severity: "medium", arg_positions: [0], languages: ["go"] }
|
|
10570
|
+
];
|
|
10571
|
+
var TRUST_BOUNDARY_FRAMEWORK_SINKS = [
|
|
10572
|
+
{ method: "set", class: "cache", type: "trust_boundary", cwe: "CWE-501", severity: "medium", arg_positions: [1], languages: ["python"] },
|
|
10573
|
+
{ method: "set_many", class: "cache", type: "trust_boundary", cwe: "CWE-501", severity: "medium", arg_positions: [0], languages: ["python"] },
|
|
10574
|
+
{ method: "setItem", class: "Storage", type: "trust_boundary", cwe: "CWE-501", severity: "medium", arg_positions: [1], languages: ["javascript", "typescript"] },
|
|
10575
|
+
{ method: "cookie", class: "Response", type: "trust_boundary", cwe: "CWE-501", severity: "medium", arg_positions: [1], languages: ["javascript", "typescript"] },
|
|
10576
|
+
{ method: "Cookie", class: "Cookie", type: "trust_boundary", cwe: "CWE-501", severity: "medium", arg_positions: [1], languages: ["java"] },
|
|
10577
|
+
{ method: "setValue", class: "Cookie", type: "trust_boundary", cwe: "CWE-501", severity: "medium", arg_positions: [0], languages: ["java"] },
|
|
10578
|
+
{ method: "setAuthentication", class: "SecurityContext", type: "trust_boundary", cwe: "CWE-501", severity: "high", arg_positions: [0], languages: ["java"] },
|
|
10579
|
+
{ method: "setProperty", class: "System", type: "trust_boundary", cwe: "CWE-501", severity: "high", arg_positions: [1], languages: ["java"] },
|
|
10580
|
+
{ method: "SetCookie", class: "http", type: "trust_boundary", cwe: "CWE-501", severity: "medium", arg_positions: [1], languages: ["go"] },
|
|
10581
|
+
{ method: "SetCookie", class: "Context", type: "trust_boundary", cwe: "CWE-501", severity: "medium", arg_positions: [1], languages: ["go"] }
|
|
10582
|
+
];
|
|
10556
10583
|
var DEFAULT_SINKS = [
|
|
10557
10584
|
{ method: "executeQuery", class: "Statement", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
|
|
10558
10585
|
{ method: "execute", class: "Statement", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
|
|
@@ -11459,7 +11486,7 @@ var DEFAULT_SINKS = [
|
|
|
11459
11486
|
{ method: "post", class: "ureq", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
|
|
11460
11487
|
{ method: "parse", class: "Uri", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0] },
|
|
11461
11488
|
{ method: "redirect", class: "HttpResponse", type: "open_redirect", cwe: "CWE-601", severity: "medium", arg_positions: [0] },
|
|
11462
|
-
{ method: "Redirect", type: "open_redirect", cwe: "CWE-601", severity: "medium", arg_positions: [0] },
|
|
11489
|
+
{ method: "Redirect", type: "open_redirect", cwe: "CWE-601", severity: "medium", arg_positions: [0], languages: ["rust"] },
|
|
11463
11490
|
{ method: "see_other", class: "Redirect", type: "open_redirect", cwe: "CWE-601", severity: "high", arg_positions: [0] },
|
|
11464
11491
|
{ method: "to", class: "Redirect", type: "open_redirect", cwe: "CWE-601", severity: "high", arg_positions: [0] },
|
|
11465
11492
|
{ method: "temporary", class: "Redirect", type: "open_redirect", cwe: "CWE-601", severity: "high", arg_positions: [0] },
|
|
@@ -11624,7 +11651,9 @@ var DEFAULT_SINKS = [
|
|
|
11624
11651
|
{ method: "CreateChatCompletionStream", class: "Client", type: "prompt_injection", cwe: "CWE-1427", severity: "high", arg_positions: [0, 1, 2, 3], languages: ["go"] },
|
|
11625
11652
|
{ method: "Call", class: "LLM", type: "prompt_injection", cwe: "CWE-1427", severity: "high", arg_positions: [0, 1, 2, 3], languages: ["go"] },
|
|
11626
11653
|
{ method: "Generate", class: "LLM", type: "prompt_injection", cwe: "CWE-1427", severity: "high", arg_positions: [0, 1, 2, 3], languages: ["go"] },
|
|
11627
|
-
{ method: "GenerateContent", class: "Model", type: "prompt_injection", cwe: "CWE-1427", severity: "high", arg_positions: [0, 1, 2, 3], languages: ["go"] }
|
|
11654
|
+
{ method: "GenerateContent", class: "Model", type: "prompt_injection", cwe: "CWE-1427", severity: "high", arg_positions: [0, 1, 2, 3], languages: ["go"] },
|
|
11655
|
+
...OPEN_REDIRECT_FRAMEWORK_SINKS,
|
|
11656
|
+
...TRUST_BOUNDARY_FRAMEWORK_SINKS
|
|
11628
11657
|
];
|
|
11629
11658
|
var DEFAULT_SANITIZERS = [
|
|
11630
11659
|
{ method: "setString", class: "PreparedStatement", removes: ["sql_injection"] },
|
|
@@ -11919,6 +11948,84 @@ var DEFAULT_HEADER_RULES = [
|
|
|
11919
11948
|
note: "Fires when the value is not a string literal (likely reflected from request)"
|
|
11920
11949
|
}
|
|
11921
11950
|
];
|
|
11951
|
+
// ../circle-ir/dist/analysis/arg-type-resolver.js
|
|
11952
|
+
function findEnclosingType(callInMethod, types) {
|
|
11953
|
+
if (!callInMethod)
|
|
11954
|
+
return null;
|
|
11955
|
+
for (const t of types) {
|
|
11956
|
+
for (const m of t.methods) {
|
|
11957
|
+
if (m.name === callInMethod)
|
|
11958
|
+
return t;
|
|
11959
|
+
}
|
|
11960
|
+
}
|
|
11961
|
+
return null;
|
|
11962
|
+
}
|
|
11963
|
+
function resolveIdentifierType(name2, callInMethod, types) {
|
|
11964
|
+
if (!name2)
|
|
11965
|
+
return null;
|
|
11966
|
+
const enclosing = findEnclosingType(callInMethod, types);
|
|
11967
|
+
if (enclosing) {
|
|
11968
|
+
for (const m of enclosing.methods) {
|
|
11969
|
+
if (m.name !== callInMethod)
|
|
11970
|
+
continue;
|
|
11971
|
+
for (const p of m.parameters) {
|
|
11972
|
+
if (p.name === name2 && p.type)
|
|
11973
|
+
return p.type;
|
|
11974
|
+
}
|
|
11975
|
+
}
|
|
11976
|
+
for (const f of enclosing.fields) {
|
|
11977
|
+
if (f.name === name2 && f.type)
|
|
11978
|
+
return f.type;
|
|
11979
|
+
}
|
|
11980
|
+
return null;
|
|
11981
|
+
}
|
|
11982
|
+
for (const t of types) {
|
|
11983
|
+
for (const m of t.methods) {
|
|
11984
|
+
for (const p of m.parameters) {
|
|
11985
|
+
if (p.name === name2 && p.type)
|
|
11986
|
+
return p.type;
|
|
11987
|
+
}
|
|
11988
|
+
}
|
|
11989
|
+
for (const f of t.fields) {
|
|
11990
|
+
if (f.name === name2 && f.type)
|
|
11991
|
+
return f.type;
|
|
11992
|
+
}
|
|
11993
|
+
}
|
|
11994
|
+
return null;
|
|
11995
|
+
}
|
|
11996
|
+
function resolveCallReturnType(calleeName, callInMethod, types) {
|
|
11997
|
+
if (!calleeName)
|
|
11998
|
+
return null;
|
|
11999
|
+
const enclosing = findEnclosingType(callInMethod, types);
|
|
12000
|
+
if (enclosing) {
|
|
12001
|
+
for (const m of enclosing.methods) {
|
|
12002
|
+
if (m.name === calleeName && m.return_type)
|
|
12003
|
+
return m.return_type;
|
|
12004
|
+
}
|
|
12005
|
+
}
|
|
12006
|
+
for (const t of types) {
|
|
12007
|
+
for (const m of t.methods) {
|
|
12008
|
+
if (m.name === calleeName && m.return_type)
|
|
12009
|
+
return m.return_type;
|
|
12010
|
+
}
|
|
12011
|
+
}
|
|
12012
|
+
return null;
|
|
12013
|
+
}
|
|
12014
|
+
function isBoundedClassType(rawType) {
|
|
12015
|
+
if (!rawType)
|
|
12016
|
+
return false;
|
|
12017
|
+
const stripped = rawType.trim().replace(/^(?:java\.lang\.)+/, "");
|
|
12018
|
+
return /^Class(?:\s*<[\s\S]*>)?$/.test(stripped);
|
|
12019
|
+
}
|
|
12020
|
+
function isArgvContainerType(rawType) {
|
|
12021
|
+
if (!rawType)
|
|
12022
|
+
return false;
|
|
12023
|
+
const s = rawType.trim().replace(/^(?:java\.util\.|java\.lang\.)+/, "");
|
|
12024
|
+
if (/^String\s*(?:\[\s*\]|\.\.\.)$/.test(s))
|
|
12025
|
+
return true;
|
|
12026
|
+
return /^(?:List|ArrayList|LinkedList|Collection|Iterable|Deque|Queue)\s*<\s*(?:String|CharSequence|java\.lang\.String)\b/.test(s);
|
|
12027
|
+
}
|
|
12028
|
+
|
|
11922
12029
|
// ../circle-ir/dist/analysis/taint-matcher.js
|
|
11923
12030
|
var PYTHON_TAINTED_PATTERNS = [
|
|
11924
12031
|
{ pattern: /\brequest\.args\b/, sourceType: "http_param" },
|
|
@@ -11942,7 +12049,7 @@ function analyzeTaint(calls, types, config = getDefaultConfig(), typeHierarchy,
|
|
|
11942
12049
|
const sources = findSources(calls, types, config.sources, sourceLines, language);
|
|
11943
12050
|
let sinkPatterns = expandPromisifyAliases(config.sinks, sourceLines, language);
|
|
11944
12051
|
sinkPatterns = expandIndirectEvalAliases(sinkPatterns, sourceLines, language);
|
|
11945
|
-
const sinks = findSinks(calls, sinkPatterns, typeHierarchy, language, sourceLines);
|
|
12052
|
+
const sinks = findSinks(calls, sinkPatterns, typeHierarchy, language, sourceLines, types);
|
|
11946
12053
|
const sanitizers = findSanitizers(calls, types, config.sanitizers, sourceLines);
|
|
11947
12054
|
return { sources, sinks, sanitizers };
|
|
11948
12055
|
}
|
|
@@ -12558,7 +12665,7 @@ function isSafeRustCommandCall(call, pattern, language) {
|
|
|
12558
12665
|
return false;
|
|
12559
12666
|
}
|
|
12560
12667
|
var CLASS_LITERAL_RE = /^(?:[A-Za-z_][\w]*\.)*[A-Z][\w]*(?:\[\])*\.class$/;
|
|
12561
|
-
function argIsClassLiteral(call, position) {
|
|
12668
|
+
function argIsClassLiteral(call, position, types) {
|
|
12562
12669
|
const arg = call.arguments.find((a) => a.position === position);
|
|
12563
12670
|
if (!arg)
|
|
12564
12671
|
return false;
|
|
@@ -12567,7 +12674,28 @@ function argIsClassLiteral(call, position) {
|
|
|
12567
12674
|
return false;
|
|
12568
12675
|
if (CLASS_LITERAL_RE.test(expr))
|
|
12569
12676
|
return true;
|
|
12570
|
-
|
|
12677
|
+
if (TYPE_TOKEN_RE.test(expr))
|
|
12678
|
+
return true;
|
|
12679
|
+
if (!types || types.length === 0)
|
|
12680
|
+
return false;
|
|
12681
|
+
const argExpr = (arg.expression ?? "").trim();
|
|
12682
|
+
const varName = arg.variable ?? "";
|
|
12683
|
+
const isBareIdentifier = varName !== "" && argExpr === varName && !/[(.]/.test(argExpr);
|
|
12684
|
+
if (isBareIdentifier) {
|
|
12685
|
+
const t = resolveIdentifierType(varName, call.in_method, types);
|
|
12686
|
+
if (isBoundedClassType(t))
|
|
12687
|
+
return true;
|
|
12688
|
+
}
|
|
12689
|
+
const isCallExpr = varName !== "" && new RegExp(`^${escapeRe(varName)}\\s*\\(`).test(argExpr);
|
|
12690
|
+
if (isCallExpr) {
|
|
12691
|
+
const t = resolveCallReturnType(varName, call.in_method, types);
|
|
12692
|
+
if (isBoundedClassType(t))
|
|
12693
|
+
return true;
|
|
12694
|
+
}
|
|
12695
|
+
return false;
|
|
12696
|
+
}
|
|
12697
|
+
function escapeRe(s) {
|
|
12698
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
12571
12699
|
}
|
|
12572
12700
|
var TYPE_TOKEN_RE = /^new\s+(?:TypeReference|TypeToken)\s*<[\s\S]*>\s*\(\s*\)\s*\{\s*\}$/;
|
|
12573
12701
|
function argIsStringLiteral(call, position) {
|
|
@@ -12750,7 +12878,7 @@ function isSafeJinjaRenderCall(call, pattern, language, sourceLines) {
|
|
|
12750
12878
|
}
|
|
12751
12879
|
return false;
|
|
12752
12880
|
}
|
|
12753
|
-
function findSinks(calls, patterns, typeHierarchy, language, sourceLines) {
|
|
12881
|
+
function findSinks(calls, patterns, typeHierarchy, language, sourceLines, types) {
|
|
12754
12882
|
const sinkMap = new Map;
|
|
12755
12883
|
for (const call of calls) {
|
|
12756
12884
|
for (const pattern of patterns) {
|
|
@@ -12770,7 +12898,7 @@ function findSinks(calls, patterns, typeHierarchy, language, sourceLines) {
|
|
|
12770
12898
|
if (isSafeJSChildProcessCall(call, pattern, language)) {
|
|
12771
12899
|
continue;
|
|
12772
12900
|
}
|
|
12773
|
-
if (pattern.safe_if_class_literal_at !== undefined && argIsClassLiteral(call, pattern.safe_if_class_literal_at)) {
|
|
12901
|
+
if (pattern.safe_if_class_literal_at !== undefined && argIsClassLiteral(call, pattern.safe_if_class_literal_at, types)) {
|
|
12774
12902
|
continue;
|
|
12775
12903
|
}
|
|
12776
12904
|
if (pattern.safe_if_string_literal_at !== undefined && argIsStringLiteral(call, pattern.safe_if_string_literal_at)) {
|
|
@@ -30767,6 +30895,9 @@ class MyBatisAnnotationSqlSinkPass {
|
|
|
30767
30895
|
}
|
|
30768
30896
|
|
|
30769
30897
|
// ../circle-ir/dist/analysis/passes/sink-filter-pass.js
|
|
30898
|
+
function escapeReSf(s) {
|
|
30899
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
30900
|
+
}
|
|
30770
30901
|
var JS_XSS_SANITIZERS = [
|
|
30771
30902
|
/\bDOMPurify\.sanitize\s*\(/,
|
|
30772
30903
|
/\bsanitizeHtml\s*\(/,
|
|
@@ -31396,6 +31527,8 @@ class SinkFilterPass {
|
|
|
31396
31527
|
if (language === "java") {
|
|
31397
31528
|
const sourceLines = ctx.code.split(`
|
|
31398
31529
|
`);
|
|
31530
|
+
const irCalls = ctx.graph.ir.calls;
|
|
31531
|
+
const irTypes = ctx.graph.ir.types;
|
|
31399
31532
|
filtered = filtered.filter((sink) => {
|
|
31400
31533
|
if (sink.type !== "command_injection")
|
|
31401
31534
|
return true;
|
|
@@ -31406,6 +31539,24 @@ class SinkFilterPass {
|
|
|
31406
31539
|
return true;
|
|
31407
31540
|
if (PROCESS_BUILDER_ARGV_FORM_RE.test(sinkLineText))
|
|
31408
31541
|
return false;
|
|
31542
|
+
const ctorCall = irCalls.find((c) => c.method_name === "ProcessBuilder" && c.location.line === sink.line && (c.receiver === null || c.receiver === undefined));
|
|
31543
|
+
if (!ctorCall || ctorCall.arguments.length === 0)
|
|
31544
|
+
return true;
|
|
31545
|
+
const arg0 = ctorCall.arguments[0];
|
|
31546
|
+
if (!arg0)
|
|
31547
|
+
return true;
|
|
31548
|
+
const argExpr = (arg0.expression ?? "").trim();
|
|
31549
|
+
const varName = arg0.variable ?? "";
|
|
31550
|
+
if (varName !== "" && argExpr === varName && !/[(.]/.test(argExpr)) {
|
|
31551
|
+
const t = resolveIdentifierType(varName, ctorCall.in_method, irTypes);
|
|
31552
|
+
if (isArgvContainerType(t))
|
|
31553
|
+
return false;
|
|
31554
|
+
}
|
|
31555
|
+
if (varName !== "" && new RegExp(`^${escapeReSf(varName)}\\s*\\(`).test(argExpr)) {
|
|
31556
|
+
const t = resolveCallReturnType(varName, ctorCall.in_method, irTypes);
|
|
31557
|
+
if (isArgvContainerType(t))
|
|
31558
|
+
return false;
|
|
31559
|
+
}
|
|
31409
31560
|
return true;
|
|
31410
31561
|
});
|
|
31411
31562
|
}
|
|
@@ -44767,7 +44918,7 @@ var colors = {
|
|
|
44767
44918
|
};
|
|
44768
44919
|
|
|
44769
44920
|
// src/version.ts
|
|
44770
|
-
var version = "3.
|
|
44921
|
+
var version = "3.176.0";
|
|
44771
44922
|
|
|
44772
44923
|
// src/formatters.ts
|
|
44773
44924
|
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.176.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.176.0"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
72
|
"@types/node": "^25.5.0",
|