circle-ir 4.7.1 → 4.7.2
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/analysis/config-loader.d.ts.map +1 -1
- package/dist/analysis/config-loader.js +56 -2
- package/dist/analysis/config-loader.js.map +1 -1
- package/dist/analysis/findings.js +1 -1
- package/dist/analysis/findings.js.map +1 -1
- package/dist/analysis/passes/language-sources-pass.d.ts.map +1 -1
- package/dist/analysis/passes/language-sources-pass.js +11 -1
- package/dist/analysis/passes/language-sources-pass.js.map +1 -1
- package/dist/analysis/passes/scan-secrets-pass.d.ts.map +1 -1
- package/dist/analysis/passes/scan-secrets-pass.js +10 -0
- package/dist/analysis/passes/scan-secrets-pass.js.map +1 -1
- package/dist/analysis/taint-matcher.d.ts.map +1 -1
- package/dist/analysis/taint-matcher.js +46 -0
- package/dist/analysis/taint-matcher.js.map +1 -1
- package/dist/browser/circle-ir.js +93 -5
- package/dist/core/circle-ir-core.cjs +87 -2
- package/dist/core/circle-ir-core.js +87 -2
- package/package.json +1 -1
|
@@ -12258,7 +12258,11 @@ var DEFAULT_SINKS = [
|
|
|
12258
12258
|
// File: covers both File(String pathname) and File(parent, child). The 2-arg
|
|
12259
12259
|
// overload's child argument carries CVE-2018-8041 (Camel mail Content-Disposition
|
|
12260
12260
|
// filename written to disk).
|
|
12261
|
-
|
|
12261
|
+
// Java `new File(path)` idiom. Excluded for C#: there is no `new File()` in
|
|
12262
|
+
// .NET (it's `System.IO.File` statics + `FileStream`, covered separately), and
|
|
12263
|
+
// this over-matched ASP.NET `ControllerBase.File(stream|bytes, contentType)` —
|
|
12264
|
+
// a result helper that returns a file, not a path sink (cognium-ai#326 B).
|
|
12265
|
+
{ method: "File", class: "constructor", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0, 1], exclude_languages: ["csharp"] },
|
|
12262
12266
|
{ method: "FileInputStream", class: "constructor", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
|
|
12263
12267
|
{ method: "FileOutputStream", class: "constructor", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
|
|
12264
12268
|
{ method: "FileReader", class: "constructor", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
|
|
@@ -13813,6 +13817,22 @@ var DEFAULT_SINKS = [
|
|
|
13813
13817
|
{ method: "FileStream", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13814
13818
|
{ method: "StreamReader", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13815
13819
|
{ method: "StreamWriter", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13820
|
+
// Remaining System.IO.File path APIs — class-scoped so they don't collide
|
|
13821
|
+
// with unrelated methods. Copy/Move take a source AND destination path (both
|
|
13822
|
+
// attacker-controllable → read-anywhere / write-anywhere), hence [0, 1].
|
|
13823
|
+
{ method: "Copy", class: "File", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0, 1], languages: ["csharp"] },
|
|
13824
|
+
{ method: "Move", class: "File", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0, 1], languages: ["csharp"] },
|
|
13825
|
+
{ method: "Delete", class: "File", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13826
|
+
{ method: "Open", class: "File", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13827
|
+
{ method: "OpenText", class: "File", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13828
|
+
{ method: "Create", class: "File", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13829
|
+
{ method: "WriteAllLines", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13830
|
+
{ method: "AppendAllLines", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13831
|
+
// System.IO.Directory path APIs.
|
|
13832
|
+
{ method: "CreateDirectory", class: "Directory", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13833
|
+
{ method: "Delete", class: "Directory", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13834
|
+
{ method: "GetFiles", class: "Directory", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13835
|
+
{ method: "EnumerateFiles", class: "Directory", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13816
13836
|
// C# SSRF — HttpClient / WebClient / WebRequest (CWE-918).
|
|
13817
13837
|
{ method: "GetAsync", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13818
13838
|
{ method: "PostAsync", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
@@ -13829,9 +13849,24 @@ var DEFAULT_SINKS = [
|
|
|
13829
13849
|
// C# code injection — dynamic script/assembly loading (CWE-94).
|
|
13830
13850
|
{ method: "EvaluateAsync", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
13831
13851
|
{ method: "RunAsync", class: "CSharpScript", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
13832
|
-
//
|
|
13852
|
+
// Loading an assembly from an attacker-controlled name/path is arbitrary code
|
|
13853
|
+
// execution. Class-scoped to `Assembly` (low FP — a tainted arg here is rare
|
|
13854
|
+
// in benign code). `Type.GetType`/`Activator.CreateInstance` are intentionally
|
|
13855
|
+
// NOT added — reflection with config-driven type names is common in DI, an FP
|
|
13856
|
+
// trap without the reflection-suppress machinery.
|
|
13857
|
+
{ method: "Load", class: "Assembly", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
13858
|
+
{ method: "LoadFrom", class: "Assembly", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
13859
|
+
{ method: "LoadFile", class: "Assembly", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
13860
|
+
// C# insecure deserialization — the polymorphic BCL formatters that can
|
|
13861
|
+
// instantiate arbitrary types named in the payload (CWE-502, cognium-ai#318).
|
|
13862
|
+
// Each of these classes exists only to deserialize and is unsafe on untrusted
|
|
13863
|
+
// input; class-scoped, so no collision with safe JSON APIs (System.Text.Json /
|
|
13864
|
+
// Newtonsoft-default, which are intentionally NOT sinks).
|
|
13833
13865
|
{ method: "Deserialize", class: "BinaryFormatter", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
13834
13866
|
{ method: "Deserialize", class: "NetDataContractSerializer", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
13867
|
+
{ method: "Deserialize", class: "SoapFormatter", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
13868
|
+
{ method: "Deserialize", class: "LosFormatter", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
13869
|
+
{ method: "Deserialize", class: "ObjectStateFormatter", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
13835
13870
|
// C# XSS — raw HTML output (CWE-79).
|
|
13836
13871
|
{ method: "Raw", class: "Html", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13837
13872
|
{ method: "Write", class: "Response", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
@@ -13856,6 +13891,20 @@ var DEFAULT_SINKS = [
|
|
|
13856
13891
|
// cognium-dev#273/#275). `BsonDocument.Parse(userJson)` deserializes an
|
|
13857
13892
|
// attacker-controlled query document. Class-scoped (static receiver resolves).
|
|
13858
13893
|
{ method: "Parse", class: "BsonDocument", type: "nosql_injection", cwe: "CWE-943", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13894
|
+
// C# log injection — Microsoft.Extensions.Logging `ILogger` (CWE-117,
|
|
13895
|
+
// cognium-ai#318). Only the message TEMPLATE (arg[0]) is the injectable
|
|
13896
|
+
// position; the structured form `LogInformation("… {Id}", id)` keeps taint in
|
|
13897
|
+
// later args (the logger renders them as data), so arg_positions:[0] does not
|
|
13898
|
+
// flag it. Mirrors the Java `Logger` sinks; severity low.
|
|
13899
|
+
{ method: "LogInformation", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0], languages: ["csharp"] },
|
|
13900
|
+
{ method: "LogWarning", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0], languages: ["csharp"] },
|
|
13901
|
+
{ method: "LogError", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0], languages: ["csharp"] },
|
|
13902
|
+
{ method: "LogDebug", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0], languages: ["csharp"] },
|
|
13903
|
+
{ method: "LogCritical", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0], languages: ["csharp"] },
|
|
13904
|
+
{ method: "LogTrace", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0], languages: ["csharp"] },
|
|
13905
|
+
// Generic `ILogger.Log(logLevel, message, …)` — class-scoped (`Log` alone is
|
|
13906
|
+
// too generic); the message is arg[1].
|
|
13907
|
+
{ method: "Log", class: "ILogger", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [1], languages: ["csharp"] },
|
|
13859
13908
|
// C# XPath injection — System.Xml.XPath (CWE-643). Distinctive selector methods.
|
|
13860
13909
|
{ method: "SelectSingleNode", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13861
13910
|
{ method: "SelectNodes", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
@@ -13864,6 +13913,11 @@ var DEFAULT_SINKS = [
|
|
|
13864
13913
|
{ method: "LoadXml", type: "xxe", cwe: "CWE-611", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13865
13914
|
{ method: "Load", class: "XmlDocument", type: "xxe", cwe: "CWE-611", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13866
13915
|
{ method: "Load", class: "XDocument", type: "xxe", cwe: "CWE-611", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13916
|
+
// `new XmlTextReader(input)` — its DtdProcessing defaults to Parse (resolves
|
|
13917
|
+
// external entities), unlike `XmlReader.Create` (Prohibit). CWE-611,
|
|
13918
|
+
// cognium-ai#318. The 4.7.0 XmlResolver=null / DtdProcessing=Prohibit
|
|
13919
|
+
// hardening still suppresses the safe shape.
|
|
13920
|
+
{ method: "XmlTextReader", type: "xxe", cwe: "CWE-611", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13867
13921
|
// Python SQLi — asyncpg Connection.*
|
|
13868
13922
|
{ method: "execute", class: "Connection", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
|
|
13869
13923
|
{ method: "fetch", class: "Connection", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
|
|
@@ -15276,6 +15330,34 @@ function isSafeJSChildProcessCall(call, pattern, language) {
|
|
|
15276
15330
|
if (SHELL_PROGRAMS.has(program)) return false;
|
|
15277
15331
|
return true;
|
|
15278
15332
|
}
|
|
15333
|
+
function isSafeCSharpProcessStartCall(call, pattern, language) {
|
|
15334
|
+
if (language !== "csharp") return false;
|
|
15335
|
+
if (pattern.type !== "command_injection") return false;
|
|
15336
|
+
if (call.method_name !== "Start") return false;
|
|
15337
|
+
if (call.arguments.length < 2) return false;
|
|
15338
|
+
const fileArg = call.arguments.find((a) => a.position === 0);
|
|
15339
|
+
if (!fileArg) return false;
|
|
15340
|
+
let raw;
|
|
15341
|
+
if (fileArg.literal !== null && fileArg.literal !== void 0) {
|
|
15342
|
+
raw = String(fileArg.literal).trim();
|
|
15343
|
+
} else {
|
|
15344
|
+
raw = (fileArg.expression ?? "").trim();
|
|
15345
|
+
}
|
|
15346
|
+
if (!/^@?"[^"]*"$/.test(raw)) return false;
|
|
15347
|
+
const program = (raw.replace(/^@?"|"$/g, "").split(/[\\/]/).pop() ?? "").toLowerCase().replace(/\.exe$/, "");
|
|
15348
|
+
const SHELL_PROGRAMS = /* @__PURE__ */ new Set([
|
|
15349
|
+
"sh",
|
|
15350
|
+
"bash",
|
|
15351
|
+
"zsh",
|
|
15352
|
+
"dash",
|
|
15353
|
+
"ash",
|
|
15354
|
+
"ksh",
|
|
15355
|
+
"cmd",
|
|
15356
|
+
"powershell",
|
|
15357
|
+
"pwsh"
|
|
15358
|
+
]);
|
|
15359
|
+
return !SHELL_PROGRAMS.has(program);
|
|
15360
|
+
}
|
|
15279
15361
|
function isSafeRustCommandCall(call, pattern, language) {
|
|
15280
15362
|
if (language !== "rust") return false;
|
|
15281
15363
|
if (pattern.type !== "command_injection") return false;
|
|
@@ -15531,6 +15613,9 @@ function findSinks(calls, patterns, typeHierarchy, language, sourceLines, types)
|
|
|
15531
15613
|
if (isSafeJSChildProcessCall(call, pattern, language)) {
|
|
15532
15614
|
continue;
|
|
15533
15615
|
}
|
|
15616
|
+
if (isSafeCSharpProcessStartCall(call, pattern, language)) {
|
|
15617
|
+
continue;
|
|
15618
|
+
}
|
|
15534
15619
|
if (pattern.safe_if_class_literal_at !== void 0 && argIsClassLiteral(call, pattern.safe_if_class_literal_at, types)) {
|
|
15535
15620
|
continue;
|
|
15536
15621
|
}
|
|
@@ -16761,8 +16846,8 @@ function canSourceReachSink(sourceType, sinkType) {
|
|
|
16761
16846
|
network_input: ["sql_injection", "command_injection", "xss", "ssrf", "log_injection", "format_string", "nosql_injection", "prompt_injection"],
|
|
16762
16847
|
config_param: ["sql_injection", "command_injection", "path_traversal", "xss", "ssrf", "log_injection", "format_string"],
|
|
16763
16848
|
// Servlet init params
|
|
16764
|
-
interprocedural_param: ["sql_injection", "command_injection", "path_traversal", "xss", "xpath_injection", "ldap_injection", "ssrf", "code_injection", "mybatis_mapper_call", "crlf", "mass_assignment", "open_redirect", "trust_boundary", "log_injection", "format_string", "nosql_injection", "prompt_injection"],
|
|
16765
|
-
// Cross-method taint; Sprint 82 (#189) — open_redirect added; Sprint 91 (#117) — trust_boundary added; cognium-ai#129 — log_injection/format_string/nosql_injection added; cognium-ai#281 — prompt_injection added
|
|
16849
|
+
interprocedural_param: ["sql_injection", "command_injection", "path_traversal", "xss", "xpath_injection", "ldap_injection", "ssrf", "code_injection", "mybatis_mapper_call", "crlf", "mass_assignment", "open_redirect", "trust_boundary", "log_injection", "format_string", "nosql_injection", "prompt_injection", "xxe", "deserialization"],
|
|
16850
|
+
// Cross-method taint; Sprint 82 (#189) — open_redirect added; Sprint 91 (#117) — trust_boundary added; cognium-ai#129 — log_injection/format_string/nosql_injection added; cognium-ai#281 — prompt_injection added; cognium-ai#317 — xxe/deserialization added (C# xxe/deser sinks are reached via param-seeded sources and were silently dropped, 0% finding conversion)
|
|
16766
16851
|
plugin_param: ["sql_injection", "command_injection", "path_traversal", "xss", "code_injection", "log_injection", "format_string"]
|
|
16767
16852
|
// Plugin/config parameters
|
|
16768
16853
|
};
|
|
@@ -27764,8 +27849,9 @@ function buildJavaTaintedVars(sourceCode, seedVars) {
|
|
|
27764
27849
|
if (JAVA_KEYWORDS.has(lhs)) continue;
|
|
27765
27850
|
if (knownTainted.has(lhs)) continue;
|
|
27766
27851
|
const escaped = (v) => v.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
27852
|
+
const rhsCode = rhs.replace(/\$@?"(?:[^"\\]|\\.)*"/g, (lit) => " " + [...lit.matchAll(/\{([^}]*)\}/g)].map((x) => x[1]).join(" ") + " ").replace(/@?"(?:[^"\\]|\\.)*"/g, " ").replace(/'(?:[^'\\]|\\.)'/g, " ");
|
|
27767
27853
|
const ref = [...knownTainted].some(
|
|
27768
|
-
(v) => new RegExp(`(?<![\\p{L}\\p{N}_])${escaped(v)}(?![\\p{L}\\p{N}_])`, "u").test(
|
|
27854
|
+
(v) => new RegExp(`(?<![\\p{L}\\p{N}_])${escaped(v)}(?![\\p{L}\\p{N}_])`, "u").test(rhsCode)
|
|
27769
27855
|
);
|
|
27770
27856
|
if (ref) {
|
|
27771
27857
|
derived.set(lhs, i2 + 1);
|
|
@@ -40790,6 +40876,8 @@ function isLikelyCredentialAssignment(line) {
|
|
|
40790
40876
|
if (CRED_DYNAMIC_VALUE_RE.test(value)) return null;
|
|
40791
40877
|
if (value.length < 3) return null;
|
|
40792
40878
|
if (isAllSameChar(value)) return null;
|
|
40879
|
+
if (value.toLowerCase() === name2.toLowerCase()) return null;
|
|
40880
|
+
if (/^(?:https?:\/\/|urn:|xmlns)/i.test(value)) return null;
|
|
40793
40881
|
if (value.length < 12) return null;
|
|
40794
40882
|
if (shannonEntropy(value) < 3.5) return null;
|
|
40795
40883
|
if (charClassDiversity(value) < 2) return null;
|
|
@@ -11653,7 +11653,11 @@ var DEFAULT_SINKS = [
|
|
|
11653
11653
|
// File: covers both File(String pathname) and File(parent, child). The 2-arg
|
|
11654
11654
|
// overload's child argument carries CVE-2018-8041 (Camel mail Content-Disposition
|
|
11655
11655
|
// filename written to disk).
|
|
11656
|
-
|
|
11656
|
+
// Java `new File(path)` idiom. Excluded for C#: there is no `new File()` in
|
|
11657
|
+
// .NET (it's `System.IO.File` statics + `FileStream`, covered separately), and
|
|
11658
|
+
// this over-matched ASP.NET `ControllerBase.File(stream|bytes, contentType)` —
|
|
11659
|
+
// a result helper that returns a file, not a path sink (cognium-ai#326 B).
|
|
11660
|
+
{ method: "File", class: "constructor", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0, 1], exclude_languages: ["csharp"] },
|
|
11657
11661
|
{ method: "FileInputStream", class: "constructor", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
|
|
11658
11662
|
{ method: "FileOutputStream", class: "constructor", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
|
|
11659
11663
|
{ method: "FileReader", class: "constructor", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
|
|
@@ -13208,6 +13212,22 @@ var DEFAULT_SINKS = [
|
|
|
13208
13212
|
{ method: "FileStream", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13209
13213
|
{ method: "StreamReader", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13210
13214
|
{ method: "StreamWriter", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13215
|
+
// Remaining System.IO.File path APIs — class-scoped so they don't collide
|
|
13216
|
+
// with unrelated methods. Copy/Move take a source AND destination path (both
|
|
13217
|
+
// attacker-controllable → read-anywhere / write-anywhere), hence [0, 1].
|
|
13218
|
+
{ method: "Copy", class: "File", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0, 1], languages: ["csharp"] },
|
|
13219
|
+
{ method: "Move", class: "File", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0, 1], languages: ["csharp"] },
|
|
13220
|
+
{ method: "Delete", class: "File", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13221
|
+
{ method: "Open", class: "File", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13222
|
+
{ method: "OpenText", class: "File", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13223
|
+
{ method: "Create", class: "File", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13224
|
+
{ method: "WriteAllLines", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13225
|
+
{ method: "AppendAllLines", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13226
|
+
// System.IO.Directory path APIs.
|
|
13227
|
+
{ method: "CreateDirectory", class: "Directory", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13228
|
+
{ method: "Delete", class: "Directory", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13229
|
+
{ method: "GetFiles", class: "Directory", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13230
|
+
{ method: "EnumerateFiles", class: "Directory", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13211
13231
|
// C# SSRF — HttpClient / WebClient / WebRequest (CWE-918).
|
|
13212
13232
|
{ method: "GetAsync", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13213
13233
|
{ method: "PostAsync", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
@@ -13224,9 +13244,24 @@ var DEFAULT_SINKS = [
|
|
|
13224
13244
|
// C# code injection — dynamic script/assembly loading (CWE-94).
|
|
13225
13245
|
{ method: "EvaluateAsync", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
13226
13246
|
{ method: "RunAsync", class: "CSharpScript", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
13227
|
-
//
|
|
13247
|
+
// Loading an assembly from an attacker-controlled name/path is arbitrary code
|
|
13248
|
+
// execution. Class-scoped to `Assembly` (low FP — a tainted arg here is rare
|
|
13249
|
+
// in benign code). `Type.GetType`/`Activator.CreateInstance` are intentionally
|
|
13250
|
+
// NOT added — reflection with config-driven type names is common in DI, an FP
|
|
13251
|
+
// trap without the reflection-suppress machinery.
|
|
13252
|
+
{ method: "Load", class: "Assembly", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
13253
|
+
{ method: "LoadFrom", class: "Assembly", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
13254
|
+
{ method: "LoadFile", class: "Assembly", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
13255
|
+
// C# insecure deserialization — the polymorphic BCL formatters that can
|
|
13256
|
+
// instantiate arbitrary types named in the payload (CWE-502, cognium-ai#318).
|
|
13257
|
+
// Each of these classes exists only to deserialize and is unsafe on untrusted
|
|
13258
|
+
// input; class-scoped, so no collision with safe JSON APIs (System.Text.Json /
|
|
13259
|
+
// Newtonsoft-default, which are intentionally NOT sinks).
|
|
13228
13260
|
{ method: "Deserialize", class: "BinaryFormatter", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
13229
13261
|
{ method: "Deserialize", class: "NetDataContractSerializer", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
13262
|
+
{ method: "Deserialize", class: "SoapFormatter", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
13263
|
+
{ method: "Deserialize", class: "LosFormatter", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
13264
|
+
{ method: "Deserialize", class: "ObjectStateFormatter", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
13230
13265
|
// C# XSS — raw HTML output (CWE-79).
|
|
13231
13266
|
{ method: "Raw", class: "Html", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13232
13267
|
{ method: "Write", class: "Response", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
@@ -13251,6 +13286,20 @@ var DEFAULT_SINKS = [
|
|
|
13251
13286
|
// cognium-dev#273/#275). `BsonDocument.Parse(userJson)` deserializes an
|
|
13252
13287
|
// attacker-controlled query document. Class-scoped (static receiver resolves).
|
|
13253
13288
|
{ method: "Parse", class: "BsonDocument", type: "nosql_injection", cwe: "CWE-943", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13289
|
+
// C# log injection — Microsoft.Extensions.Logging `ILogger` (CWE-117,
|
|
13290
|
+
// cognium-ai#318). Only the message TEMPLATE (arg[0]) is the injectable
|
|
13291
|
+
// position; the structured form `LogInformation("… {Id}", id)` keeps taint in
|
|
13292
|
+
// later args (the logger renders them as data), so arg_positions:[0] does not
|
|
13293
|
+
// flag it. Mirrors the Java `Logger` sinks; severity low.
|
|
13294
|
+
{ method: "LogInformation", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0], languages: ["csharp"] },
|
|
13295
|
+
{ method: "LogWarning", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0], languages: ["csharp"] },
|
|
13296
|
+
{ method: "LogError", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0], languages: ["csharp"] },
|
|
13297
|
+
{ method: "LogDebug", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0], languages: ["csharp"] },
|
|
13298
|
+
{ method: "LogCritical", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0], languages: ["csharp"] },
|
|
13299
|
+
{ method: "LogTrace", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0], languages: ["csharp"] },
|
|
13300
|
+
// Generic `ILogger.Log(logLevel, message, …)` — class-scoped (`Log` alone is
|
|
13301
|
+
// too generic); the message is arg[1].
|
|
13302
|
+
{ method: "Log", class: "ILogger", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [1], languages: ["csharp"] },
|
|
13254
13303
|
// C# XPath injection — System.Xml.XPath (CWE-643). Distinctive selector methods.
|
|
13255
13304
|
{ method: "SelectSingleNode", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13256
13305
|
{ method: "SelectNodes", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
@@ -13259,6 +13308,11 @@ var DEFAULT_SINKS = [
|
|
|
13259
13308
|
{ method: "LoadXml", type: "xxe", cwe: "CWE-611", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13260
13309
|
{ method: "Load", class: "XmlDocument", type: "xxe", cwe: "CWE-611", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13261
13310
|
{ method: "Load", class: "XDocument", type: "xxe", cwe: "CWE-611", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13311
|
+
// `new XmlTextReader(input)` — its DtdProcessing defaults to Parse (resolves
|
|
13312
|
+
// external entities), unlike `XmlReader.Create` (Prohibit). CWE-611,
|
|
13313
|
+
// cognium-ai#318. The 4.7.0 XmlResolver=null / DtdProcessing=Prohibit
|
|
13314
|
+
// hardening still suppresses the safe shape.
|
|
13315
|
+
{ method: "XmlTextReader", type: "xxe", cwe: "CWE-611", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13262
13316
|
// Python SQLi — asyncpg Connection.*
|
|
13263
13317
|
{ method: "execute", class: "Connection", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
|
|
13264
13318
|
{ method: "fetch", class: "Connection", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
|
|
@@ -14576,6 +14630,34 @@ function isSafeJSChildProcessCall(call, pattern, language) {
|
|
|
14576
14630
|
if (SHELL_PROGRAMS.has(program)) return false;
|
|
14577
14631
|
return true;
|
|
14578
14632
|
}
|
|
14633
|
+
function isSafeCSharpProcessStartCall(call, pattern, language) {
|
|
14634
|
+
if (language !== "csharp") return false;
|
|
14635
|
+
if (pattern.type !== "command_injection") return false;
|
|
14636
|
+
if (call.method_name !== "Start") return false;
|
|
14637
|
+
if (call.arguments.length < 2) return false;
|
|
14638
|
+
const fileArg = call.arguments.find((a) => a.position === 0);
|
|
14639
|
+
if (!fileArg) return false;
|
|
14640
|
+
let raw;
|
|
14641
|
+
if (fileArg.literal !== null && fileArg.literal !== void 0) {
|
|
14642
|
+
raw = String(fileArg.literal).trim();
|
|
14643
|
+
} else {
|
|
14644
|
+
raw = (fileArg.expression ?? "").trim();
|
|
14645
|
+
}
|
|
14646
|
+
if (!/^@?"[^"]*"$/.test(raw)) return false;
|
|
14647
|
+
const program = (raw.replace(/^@?"|"$/g, "").split(/[\\/]/).pop() ?? "").toLowerCase().replace(/\.exe$/, "");
|
|
14648
|
+
const SHELL_PROGRAMS = /* @__PURE__ */ new Set([
|
|
14649
|
+
"sh",
|
|
14650
|
+
"bash",
|
|
14651
|
+
"zsh",
|
|
14652
|
+
"dash",
|
|
14653
|
+
"ash",
|
|
14654
|
+
"ksh",
|
|
14655
|
+
"cmd",
|
|
14656
|
+
"powershell",
|
|
14657
|
+
"pwsh"
|
|
14658
|
+
]);
|
|
14659
|
+
return !SHELL_PROGRAMS.has(program);
|
|
14660
|
+
}
|
|
14579
14661
|
function isSafeRustCommandCall(call, pattern, language) {
|
|
14580
14662
|
if (language !== "rust") return false;
|
|
14581
14663
|
if (pattern.type !== "command_injection") return false;
|
|
@@ -14831,6 +14913,9 @@ function findSinks(calls, patterns, typeHierarchy, language, sourceLines, types)
|
|
|
14831
14913
|
if (isSafeJSChildProcessCall(call, pattern, language)) {
|
|
14832
14914
|
continue;
|
|
14833
14915
|
}
|
|
14916
|
+
if (isSafeCSharpProcessStartCall(call, pattern, language)) {
|
|
14917
|
+
continue;
|
|
14918
|
+
}
|
|
14834
14919
|
if (pattern.safe_if_class_literal_at !== void 0 && argIsClassLiteral(call, pattern.safe_if_class_literal_at, types)) {
|
|
14835
14920
|
continue;
|
|
14836
14921
|
}
|
|
@@ -11587,7 +11587,11 @@ var DEFAULT_SINKS = [
|
|
|
11587
11587
|
// File: covers both File(String pathname) and File(parent, child). The 2-arg
|
|
11588
11588
|
// overload's child argument carries CVE-2018-8041 (Camel mail Content-Disposition
|
|
11589
11589
|
// filename written to disk).
|
|
11590
|
-
|
|
11590
|
+
// Java `new File(path)` idiom. Excluded for C#: there is no `new File()` in
|
|
11591
|
+
// .NET (it's `System.IO.File` statics + `FileStream`, covered separately), and
|
|
11592
|
+
// this over-matched ASP.NET `ControllerBase.File(stream|bytes, contentType)` —
|
|
11593
|
+
// a result helper that returns a file, not a path sink (cognium-ai#326 B).
|
|
11594
|
+
{ method: "File", class: "constructor", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0, 1], exclude_languages: ["csharp"] },
|
|
11591
11595
|
{ method: "FileInputStream", class: "constructor", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
|
|
11592
11596
|
{ method: "FileOutputStream", class: "constructor", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
|
|
11593
11597
|
{ method: "FileReader", class: "constructor", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0] },
|
|
@@ -13142,6 +13146,22 @@ var DEFAULT_SINKS = [
|
|
|
13142
13146
|
{ method: "FileStream", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13143
13147
|
{ method: "StreamReader", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13144
13148
|
{ method: "StreamWriter", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13149
|
+
// Remaining System.IO.File path APIs — class-scoped so they don't collide
|
|
13150
|
+
// with unrelated methods. Copy/Move take a source AND destination path (both
|
|
13151
|
+
// attacker-controllable → read-anywhere / write-anywhere), hence [0, 1].
|
|
13152
|
+
{ method: "Copy", class: "File", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0, 1], languages: ["csharp"] },
|
|
13153
|
+
{ method: "Move", class: "File", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0, 1], languages: ["csharp"] },
|
|
13154
|
+
{ method: "Delete", class: "File", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13155
|
+
{ method: "Open", class: "File", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13156
|
+
{ method: "OpenText", class: "File", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13157
|
+
{ method: "Create", class: "File", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13158
|
+
{ method: "WriteAllLines", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13159
|
+
{ method: "AppendAllLines", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13160
|
+
// System.IO.Directory path APIs.
|
|
13161
|
+
{ method: "CreateDirectory", class: "Directory", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13162
|
+
{ method: "Delete", class: "Directory", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13163
|
+
{ method: "GetFiles", class: "Directory", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13164
|
+
{ method: "EnumerateFiles", class: "Directory", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13145
13165
|
// C# SSRF — HttpClient / WebClient / WebRequest (CWE-918).
|
|
13146
13166
|
{ method: "GetAsync", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13147
13167
|
{ method: "PostAsync", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
@@ -13158,9 +13178,24 @@ var DEFAULT_SINKS = [
|
|
|
13158
13178
|
// C# code injection — dynamic script/assembly loading (CWE-94).
|
|
13159
13179
|
{ method: "EvaluateAsync", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
13160
13180
|
{ method: "RunAsync", class: "CSharpScript", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
13161
|
-
//
|
|
13181
|
+
// Loading an assembly from an attacker-controlled name/path is arbitrary code
|
|
13182
|
+
// execution. Class-scoped to `Assembly` (low FP — a tainted arg here is rare
|
|
13183
|
+
// in benign code). `Type.GetType`/`Activator.CreateInstance` are intentionally
|
|
13184
|
+
// NOT added — reflection with config-driven type names is common in DI, an FP
|
|
13185
|
+
// trap without the reflection-suppress machinery.
|
|
13186
|
+
{ method: "Load", class: "Assembly", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
13187
|
+
{ method: "LoadFrom", class: "Assembly", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
13188
|
+
{ method: "LoadFile", class: "Assembly", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
13189
|
+
// C# insecure deserialization — the polymorphic BCL formatters that can
|
|
13190
|
+
// instantiate arbitrary types named in the payload (CWE-502, cognium-ai#318).
|
|
13191
|
+
// Each of these classes exists only to deserialize and is unsafe on untrusted
|
|
13192
|
+
// input; class-scoped, so no collision with safe JSON APIs (System.Text.Json /
|
|
13193
|
+
// Newtonsoft-default, which are intentionally NOT sinks).
|
|
13162
13194
|
{ method: "Deserialize", class: "BinaryFormatter", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
13163
13195
|
{ method: "Deserialize", class: "NetDataContractSerializer", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
13196
|
+
{ method: "Deserialize", class: "SoapFormatter", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
13197
|
+
{ method: "Deserialize", class: "LosFormatter", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
13198
|
+
{ method: "Deserialize", class: "ObjectStateFormatter", type: "deserialization", cwe: "CWE-502", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
13164
13199
|
// C# XSS — raw HTML output (CWE-79).
|
|
13165
13200
|
{ method: "Raw", class: "Html", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13166
13201
|
{ method: "Write", class: "Response", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
@@ -13185,6 +13220,20 @@ var DEFAULT_SINKS = [
|
|
|
13185
13220
|
// cognium-dev#273/#275). `BsonDocument.Parse(userJson)` deserializes an
|
|
13186
13221
|
// attacker-controlled query document. Class-scoped (static receiver resolves).
|
|
13187
13222
|
{ method: "Parse", class: "BsonDocument", type: "nosql_injection", cwe: "CWE-943", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13223
|
+
// C# log injection — Microsoft.Extensions.Logging `ILogger` (CWE-117,
|
|
13224
|
+
// cognium-ai#318). Only the message TEMPLATE (arg[0]) is the injectable
|
|
13225
|
+
// position; the structured form `LogInformation("… {Id}", id)` keeps taint in
|
|
13226
|
+
// later args (the logger renders them as data), so arg_positions:[0] does not
|
|
13227
|
+
// flag it. Mirrors the Java `Logger` sinks; severity low.
|
|
13228
|
+
{ method: "LogInformation", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0], languages: ["csharp"] },
|
|
13229
|
+
{ method: "LogWarning", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0], languages: ["csharp"] },
|
|
13230
|
+
{ method: "LogError", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0], languages: ["csharp"] },
|
|
13231
|
+
{ method: "LogDebug", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0], languages: ["csharp"] },
|
|
13232
|
+
{ method: "LogCritical", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0], languages: ["csharp"] },
|
|
13233
|
+
{ method: "LogTrace", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [0], languages: ["csharp"] },
|
|
13234
|
+
// Generic `ILogger.Log(logLevel, message, …)` — class-scoped (`Log` alone is
|
|
13235
|
+
// too generic); the message is arg[1].
|
|
13236
|
+
{ method: "Log", class: "ILogger", type: "log_injection", cwe: "CWE-117", severity: "low", arg_positions: [1], languages: ["csharp"] },
|
|
13188
13237
|
// C# XPath injection — System.Xml.XPath (CWE-643). Distinctive selector methods.
|
|
13189
13238
|
{ method: "SelectSingleNode", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13190
13239
|
{ method: "SelectNodes", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
@@ -13193,6 +13242,11 @@ var DEFAULT_SINKS = [
|
|
|
13193
13242
|
{ method: "LoadXml", type: "xxe", cwe: "CWE-611", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13194
13243
|
{ method: "Load", class: "XmlDocument", type: "xxe", cwe: "CWE-611", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13195
13244
|
{ method: "Load", class: "XDocument", type: "xxe", cwe: "CWE-611", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13245
|
+
// `new XmlTextReader(input)` — its DtdProcessing defaults to Parse (resolves
|
|
13246
|
+
// external entities), unlike `XmlReader.Create` (Prohibit). CWE-611,
|
|
13247
|
+
// cognium-ai#318. The 4.7.0 XmlResolver=null / DtdProcessing=Prohibit
|
|
13248
|
+
// hardening still suppresses the safe shape.
|
|
13249
|
+
{ method: "XmlTextReader", type: "xxe", cwe: "CWE-611", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
13196
13250
|
// Python SQLi — asyncpg Connection.*
|
|
13197
13251
|
{ method: "execute", class: "Connection", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
|
|
13198
13252
|
{ method: "fetch", class: "Connection", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0] },
|
|
@@ -14510,6 +14564,34 @@ function isSafeJSChildProcessCall(call, pattern, language) {
|
|
|
14510
14564
|
if (SHELL_PROGRAMS.has(program)) return false;
|
|
14511
14565
|
return true;
|
|
14512
14566
|
}
|
|
14567
|
+
function isSafeCSharpProcessStartCall(call, pattern, language) {
|
|
14568
|
+
if (language !== "csharp") return false;
|
|
14569
|
+
if (pattern.type !== "command_injection") return false;
|
|
14570
|
+
if (call.method_name !== "Start") return false;
|
|
14571
|
+
if (call.arguments.length < 2) return false;
|
|
14572
|
+
const fileArg = call.arguments.find((a) => a.position === 0);
|
|
14573
|
+
if (!fileArg) return false;
|
|
14574
|
+
let raw;
|
|
14575
|
+
if (fileArg.literal !== null && fileArg.literal !== void 0) {
|
|
14576
|
+
raw = String(fileArg.literal).trim();
|
|
14577
|
+
} else {
|
|
14578
|
+
raw = (fileArg.expression ?? "").trim();
|
|
14579
|
+
}
|
|
14580
|
+
if (!/^@?"[^"]*"$/.test(raw)) return false;
|
|
14581
|
+
const program = (raw.replace(/^@?"|"$/g, "").split(/[\\/]/).pop() ?? "").toLowerCase().replace(/\.exe$/, "");
|
|
14582
|
+
const SHELL_PROGRAMS = /* @__PURE__ */ new Set([
|
|
14583
|
+
"sh",
|
|
14584
|
+
"bash",
|
|
14585
|
+
"zsh",
|
|
14586
|
+
"dash",
|
|
14587
|
+
"ash",
|
|
14588
|
+
"ksh",
|
|
14589
|
+
"cmd",
|
|
14590
|
+
"powershell",
|
|
14591
|
+
"pwsh"
|
|
14592
|
+
]);
|
|
14593
|
+
return !SHELL_PROGRAMS.has(program);
|
|
14594
|
+
}
|
|
14513
14595
|
function isSafeRustCommandCall(call, pattern, language) {
|
|
14514
14596
|
if (language !== "rust") return false;
|
|
14515
14597
|
if (pattern.type !== "command_injection") return false;
|
|
@@ -14765,6 +14847,9 @@ function findSinks(calls, patterns, typeHierarchy, language, sourceLines, types)
|
|
|
14765
14847
|
if (isSafeJSChildProcessCall(call, pattern, language)) {
|
|
14766
14848
|
continue;
|
|
14767
14849
|
}
|
|
14850
|
+
if (isSafeCSharpProcessStartCall(call, pattern, language)) {
|
|
14851
|
+
continue;
|
|
14852
|
+
}
|
|
14768
14853
|
if (pattern.safe_if_class_literal_at !== void 0 && argIsClassLiteral(call, pattern.safe_if_class_literal_at, types)) {
|
|
14769
14854
|
continue;
|
|
14770
14855
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "circle-ir",
|
|
3
|
-
"version": "4.7.
|
|
3
|
+
"version": "4.7.2",
|
|
4
4
|
"description": "High-performance Static Application Security Testing (SAST) library for detecting security vulnerabilities through taint analysis",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.js",
|