cognium-dev 4.4.0 → 4.5.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 +51 -4
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -5268,6 +5268,14 @@ function findFirstDescendant(node, type) {
|
|
|
5268
5268
|
}
|
|
5269
5269
|
return null;
|
|
5270
5270
|
}
|
|
5271
|
+
var CSHARP_COMMAND_EXECUTE_METHODS = new Set([
|
|
5272
|
+
"ExecuteScalar",
|
|
5273
|
+
"ExecuteReader",
|
|
5274
|
+
"ExecuteNonQuery",
|
|
5275
|
+
"ExecuteScalarAsync",
|
|
5276
|
+
"ExecuteReaderAsync",
|
|
5277
|
+
"ExecuteNonQueryAsync"
|
|
5278
|
+
]);
|
|
5271
5279
|
function extractCSharpCalls(tree, cache) {
|
|
5272
5280
|
const calls = [];
|
|
5273
5281
|
const typeMap = buildCSharpReceiverTypeMap(tree, cache);
|
|
@@ -5285,12 +5293,16 @@ function extractCSharpCalls(tree, cache) {
|
|
|
5285
5293
|
methodName = getNodeText(fn);
|
|
5286
5294
|
}
|
|
5287
5295
|
const argsNode = inv.childForFieldName("arguments");
|
|
5296
|
+
let args2 = argsNode ? extractCSharpArguments(argsNode) : [];
|
|
5297
|
+
if (receiver && CSHARP_COMMAND_EXECUTE_METHODS.has(methodName)) {
|
|
5298
|
+
args2 = [{ position: 0, expression: receiver, variable: receiver, literal: null, value: null }, ...args2];
|
|
5299
|
+
}
|
|
5288
5300
|
calls.push({
|
|
5289
5301
|
method_name: methodName,
|
|
5290
5302
|
receiver,
|
|
5291
5303
|
receiver_type: receiver ? typeMap.get(receiver) ?? null : null,
|
|
5292
5304
|
receiver_type_fqn: null,
|
|
5293
|
-
arguments:
|
|
5305
|
+
arguments: args2,
|
|
5294
5306
|
location: { line: inv.startPosition.row + 1, column: inv.startPosition.column },
|
|
5295
5307
|
in_method: findEnclosingMethod(inv)
|
|
5296
5308
|
});
|
|
@@ -12314,6 +12326,12 @@ var DEFAULT_SINKS = [
|
|
|
12314
12326
|
{ method: "FromSqlRaw", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
12315
12327
|
{ method: "FromSqlRawAsync", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
12316
12328
|
{ method: "CommandText", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
12329
|
+
{ method: "ExecuteScalar", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
12330
|
+
{ method: "ExecuteReader", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
12331
|
+
{ method: "ExecuteNonQuery", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
12332
|
+
{ method: "ExecuteScalarAsync", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
12333
|
+
{ method: "ExecuteReaderAsync", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
12334
|
+
{ method: "ExecuteNonQueryAsync", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
12317
12335
|
{ method: "Start", class: "Process", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
12318
12336
|
{ method: "ProcessStartInfo", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0, 1], languages: ["csharp"] },
|
|
12319
12337
|
{ method: "ReadAllText", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
@@ -25619,18 +25637,20 @@ function findCSharpRequestSources(sourceCode, language) {
|
|
|
25619
25637
|
`);
|
|
25620
25638
|
const assignRe = /^\s*(?:var\s+|[A-Za-z_][\w.<>\[\]]*\s+)?([A-Za-z_]\w*)\s*=\s*(.+?);?\s*$/;
|
|
25621
25639
|
const requestReadRe = /\bRequest\s*\.\s*(?:Query|Form|Headers|Cookies|QueryString|RouteValues|Body|Files|Params)\b/;
|
|
25640
|
+
const consoleReadRe = /\bConsole\s*\.\s*ReadLine\s*\(/;
|
|
25622
25641
|
for (let i2 = 0;i2 < lines.length; i2++) {
|
|
25623
25642
|
const m = assignRe.exec(lines[i2]);
|
|
25624
25643
|
if (!m)
|
|
25625
25644
|
continue;
|
|
25626
25645
|
const [, varName, rhs] = m;
|
|
25627
|
-
|
|
25646
|
+
const type = requestReadRe.test(rhs) ? "http_param" : consoleReadRe.test(rhs) ? "io_input" : null;
|
|
25647
|
+
if (!type)
|
|
25628
25648
|
continue;
|
|
25629
25649
|
const lineNumber = i2 + 1;
|
|
25630
25650
|
if (sources.some((s) => s.line === lineNumber && s.variable === varName))
|
|
25631
25651
|
continue;
|
|
25632
25652
|
sources.push({
|
|
25633
|
-
type
|
|
25653
|
+
type,
|
|
25634
25654
|
location: `${varName} = ${rhs.trim().substring(0, 50)}${rhs.length > 50 ? "..." : ""}`,
|
|
25635
25655
|
severity: "high",
|
|
25636
25656
|
line: lineNumber,
|
|
@@ -36020,6 +36040,33 @@ function detectExpressionScanFlows(calls, sources, sinks, sanitizers, unreachabl
|
|
|
36020
36040
|
}
|
|
36021
36041
|
}
|
|
36022
36042
|
}
|
|
36043
|
+
if (language === "csharp" && typeof code === "string" && sourcesWithVar.length > 0) {
|
|
36044
|
+
const lines = code.split(`
|
|
36045
|
+
`);
|
|
36046
|
+
const ctRe = /(\w+)\s*\.\s*CommandText\s*\+?=\s*(.+)/;
|
|
36047
|
+
const anchor = sourcesWithVar.reduce((a, s) => s.line < a.line ? s : a, sourcesWithVar[0]);
|
|
36048
|
+
let added = true;
|
|
36049
|
+
let guard = 0;
|
|
36050
|
+
while (added && guard < lines.length + 2) {
|
|
36051
|
+
added = false;
|
|
36052
|
+
guard++;
|
|
36053
|
+
const known = new Set(sourcesWithVar.map((s) => s.variable));
|
|
36054
|
+
for (let i2 = 0;i2 < lines.length; i2++) {
|
|
36055
|
+
const m = ctRe.exec(lines[i2]);
|
|
36056
|
+
if (!m)
|
|
36057
|
+
continue;
|
|
36058
|
+
const [, obj, rhs] = m;
|
|
36059
|
+
if (known.has(obj))
|
|
36060
|
+
continue;
|
|
36061
|
+
const codePart = rhs.replace(/\$@?"(?:[^"\\]|\\.)*"/g, (lit) => " " + [...lit.matchAll(/\{([^}]*)\}/g)].map((x) => x[1]).join(" ") + " ").replace(/@?"(?:[^"\\]|\\.)*"/g, " ");
|
|
36062
|
+
const rhsTainted = sourcesWithVar.some((s) => new RegExp(`(?<![\\p{L}\\p{N}_])${s.variable.replace(/[.*+?^${}()|[\\]\\\\]/g, "\\$&")}(?![\\p{L}\\p{N}_])`, "u").test(codePart));
|
|
36063
|
+
if (!rhsTainted)
|
|
36064
|
+
continue;
|
|
36065
|
+
sourcesWithVar.push({ ...anchor, variable: obj, line: i2 + 1 });
|
|
36066
|
+
added = true;
|
|
36067
|
+
}
|
|
36068
|
+
}
|
|
36069
|
+
}
|
|
36023
36070
|
const reCache = new Map;
|
|
36024
36071
|
for (const s of sourcesWithVar) {
|
|
36025
36072
|
if (reCache.has(s.variable))
|
|
@@ -47808,7 +47855,7 @@ var colors = {
|
|
|
47808
47855
|
};
|
|
47809
47856
|
|
|
47810
47857
|
// src/version.ts
|
|
47811
|
-
var version = "4.
|
|
47858
|
+
var version = "4.5.0";
|
|
47812
47859
|
|
|
47813
47860
|
// src/formatters.ts
|
|
47814
47861
|
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": "4.
|
|
3
|
+
"version": "4.5.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": "^4.
|
|
69
|
+
"circle-ir": "^4.5.0"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
72
|
"@types/node": "^25.5.0",
|