circle-ir 4.9.27 → 4.9.29
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 +58 -5
- package/dist/analysis/config-loader.js.map +1 -1
- package/dist/analysis/findings.d.ts.map +1 -1
- package/dist/analysis/findings.js +130 -0
- package/dist/analysis/findings.js.map +1 -1
- package/dist/analysis/interprocedural.d.ts.map +1 -1
- package/dist/analysis/interprocedural.js +63 -0
- package/dist/analysis/interprocedural.js.map +1 -1
- package/dist/analysis/passes/language-sources-pass.d.ts.map +1 -1
- package/dist/analysis/passes/language-sources-pass.js +162 -8
- package/dist/analysis/passes/language-sources-pass.js.map +1 -1
- package/dist/analysis/passes/taint-propagation-pass.d.ts.map +1 -1
- package/dist/analysis/passes/taint-propagation-pass.js +214 -16
- package/dist/analysis/passes/taint-propagation-pass.js.map +1 -1
- package/dist/analysis/passes/variable-shadowing-pass.d.ts.map +1 -1
- package/dist/analysis/passes/variable-shadowing-pass.js +15 -0
- package/dist/analysis/passes/variable-shadowing-pass.js.map +1 -1
- package/dist/analysis/taint-matcher.d.ts.map +1 -1
- package/dist/analysis/taint-matcher.js +62 -1
- package/dist/analysis/taint-matcher.js.map +1 -1
- package/dist/browser/circle-ir.js +486 -33
- package/dist/core/circle-ir-core.cjs +173 -13
- package/dist/core/circle-ir-core.js +173 -13
- package/dist/core/extractors/calls.js +155 -1
- package/dist/core/extractors/calls.js.map +1 -1
- package/dist/core/extractors/types.js +50 -7
- package/dist/core/extractors/types.js.map +1 -1
- package/dist/types/config.d.ts +14 -0
- package/dist/types/config.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../../src/analysis/config-loader.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,UAAU,EACV,mBAAmB,EACnB,kBAAkB,EAClB,WAAW,EACX,aAAa,EACb,WAAW,EACX,gBAAgB,EAChB,UAAU,EACX,MAAM,oBAAoB,CAAC;AAE5B;;;GAGG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,GAAG,CAAC,CAEjD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,aAAa,EAAE,CAiB1E;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG;IACtD,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,UAAU,EAAE,gBAAgB,EAAE,CAAC;CAChC,CAcA;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,mBAAmB,EAAE,GAC7B,kBAAkB,EAAE,CAQtB;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,cAAc,EAAE,MAAM,EAAE,EACxB,YAAY,EAAE,MAAM,EAAE,EACtB,qBAAqB,GAAE,MAAM,EAAO,GACnC,WAAW,CAYb;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../../src/analysis/config-loader.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,UAAU,EACV,mBAAmB,EACnB,kBAAkB,EAClB,WAAW,EACX,aAAa,EACb,WAAW,EACX,gBAAgB,EAChB,UAAU,EACX,MAAM,oBAAoB,CAAC;AAE5B;;;GAGG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,GAAG,CAAC,CAEjD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,aAAa,EAAE,CAiB1E;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG;IACtD,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,UAAU,EAAE,gBAAgB,EAAE,CAAC;CAChC,CAcA;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,mBAAmB,EAAE,GAC7B,kBAAkB,EAAE,CAQtB;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,cAAc,EAAE,MAAM,EAAE,EACxB,YAAY,EAAE,MAAM,EAAE,EACtB,qBAAqB,GAAE,MAAM,EAAO,GACnC,WAAW,CAYb;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,aAAa,EAy0B1C,CAAC;AA+KF,eAAO,MAAM,aAAa,EAAE,WAAW,EAmpEtC,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,gBAAgB,EAgjBhD,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,sBAAsB,EAAE,kBAAkB,EAiDtD,CAAC;AAEF;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,WAAW,CAO9C;AAMD;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,EAAE,UAAU,EA8F5C,CAAC"}
|
|
@@ -137,6 +137,23 @@ export const DEFAULT_SOURCES = [
|
|
|
137
137
|
{ method: 'next', class: 'Scanner', type: 'io_input', severity: 'high', return_tainted: true },
|
|
138
138
|
{ method: 'nextInt', class: 'Scanner', type: 'io_input', severity: 'high', return_tainted: true },
|
|
139
139
|
// Database result sources
|
|
140
|
+
// C# I/O, network and database reads (cognium-dev#502). Mirrors the Java
|
|
141
|
+
// rows above one-for-one, including the severity split: console/file I/O is
|
|
142
|
+
// `io_input` at high, a database row read is `db_input` at medium. There is
|
|
143
|
+
// no separate confidence tier — `type` + `severity` IS the tier, exactly as
|
|
144
|
+
// for `BufferedReader.readLine` vs `ResultSet.getString`.
|
|
145
|
+
{ method: 'ReadLine', class: 'StreamReader', type: 'io_input', severity: 'high', return_tainted: true, languages: ['csharp'] },
|
|
146
|
+
{ method: 'ReadLineAsync', class: 'StreamReader', type: 'io_input', severity: 'high', return_tainted: true, languages: ['csharp'] },
|
|
147
|
+
{ method: 'ReadToEnd', class: 'StreamReader', type: 'io_input', severity: 'high', return_tainted: true, languages: ['csharp'] },
|
|
148
|
+
{ method: 'ReadToEndAsync', class: 'StreamReader', type: 'io_input', severity: 'high', return_tainted: true, languages: ['csharp'] },
|
|
149
|
+
// Socket and HTTP-client reads. `GetStream` / `AcceptTcpClient` /
|
|
150
|
+
// `OpenRead` return the channel; the read off it is covered by the
|
|
151
|
+
// StreamReader rows above, and seeding the channel too lets a flow form when
|
|
152
|
+
// the read is inlined.
|
|
153
|
+
{ method: 'GetStream', class: 'TcpClient', type: 'network_input', severity: 'high', return_tainted: true, languages: ['csharp'] },
|
|
154
|
+
{ method: 'AcceptTcpClient', class: 'TcpListener', type: 'network_input', severity: 'high', return_tainted: true, languages: ['csharp'] },
|
|
155
|
+
{ method: 'OpenRead', class: 'WebClient', type: 'network_input', severity: 'high', return_tainted: true, languages: ['csharp'] },
|
|
156
|
+
{ method: 'DownloadString', class: 'WebClient', type: 'network_input', severity: 'high', return_tainted: true, languages: ['csharp'] },
|
|
140
157
|
{ method: 'getString', class: 'ResultSet', type: 'db_input', severity: 'medium', return_tainted: true },
|
|
141
158
|
{ method: 'getObject', class: 'ResultSet', type: 'db_input', severity: 'medium', return_tainted: true },
|
|
142
159
|
{ method: 'getInt', class: 'ResultSet', type: 'db_input', severity: 'medium', return_tainted: true },
|
|
@@ -2422,9 +2439,14 @@ export const DEFAULT_SINKS = [
|
|
|
2422
2439
|
{ method: 'deserialize', class: 'bincode', type: 'deserialization', cwe: 'CWE-502', severity: 'critical', arg_positions: [0] },
|
|
2423
2440
|
{ method: 'from_str', class: 'toml', type: 'deserialization', cwe: 'CWE-502', severity: 'high', arg_positions: [0] },
|
|
2424
2441
|
{ method: 'from_str', class: 'ron', type: 'deserialization', cwe: 'CWE-502', severity: 'high', arg_positions: [0] },
|
|
2425
|
-
//
|
|
2426
|
-
|
|
2427
|
-
|
|
2442
|
+
// #294/#484: no classless `from_str` / `from_slice` deserialization sink.
|
|
2443
|
+
// Those rows matched EVERY `T::from_str` / `from_slice` — `u32::from_str`,
|
|
2444
|
+
// `Url::from_str`, `PublicKey::from_slice` — i.e. ordinary `FromStr` / byte
|
|
2445
|
+
// parsing, which cannot instantiate an attacker-chosen type. Removing them
|
|
2446
|
+
// was previously blocked because the class-scoped rows below could not match
|
|
2447
|
+
// the IMPORTED call form (`use serde_json::from_str; from_str(&body)`); the
|
|
2448
|
+
// `::` path-separator fix in taint-matcher.ts makes them match, so the
|
|
2449
|
+
// classless rows are no longer load-bearing.
|
|
2428
2450
|
// Rust XSS (actix-web, rocket, axum response body)
|
|
2429
2451
|
{ method: 'body', class: 'HttpResponseBuilder', type: 'xss', cwe: 'CWE-79', severity: 'high', arg_positions: [0] },
|
|
2430
2452
|
{ method: 'body', class: 'HttpResponse', type: 'xss', cwe: 'CWE-79', severity: 'high', arg_positions: [0] },
|
|
@@ -2740,8 +2762,12 @@ export const DEFAULT_SINKS = [
|
|
|
2740
2762
|
{ method: 'OpenRead', class: 'File', type: 'path_traversal', cwe: 'CWE-22', severity: 'high', arg_positions: [0], languages: ['csharp'] },
|
|
2741
2763
|
{ method: 'OpenWrite', class: 'File', type: 'path_traversal', cwe: 'CWE-22', severity: 'high', arg_positions: [0], languages: ['csharp'] },
|
|
2742
2764
|
{ method: 'FileStream', type: 'path_traversal', cwe: 'CWE-22', severity: 'high', arg_positions: [0], languages: ['csharp'] },
|
|
2743
|
-
|
|
2744
|
-
|
|
2765
|
+
// #502: the `(Stream)` overload takes no path — `new StreamReader(tcp.GetStream())`
|
|
2766
|
+
// is not CWE-22. The `(string path)` overload still matches.
|
|
2767
|
+
{ method: 'StreamReader', type: 'path_traversal', cwe: 'CWE-22', severity: 'high', arg_positions: [0], safe_if_stream_arg_at: 0, languages: ['csharp'] },
|
|
2768
|
+
// #502: the `(Stream)` overload takes no path — `new StreamWriter(tcp.GetStream())`
|
|
2769
|
+
// is not CWE-22. The `(string path)` overload still matches.
|
|
2770
|
+
{ method: 'StreamWriter', type: 'path_traversal', cwe: 'CWE-22', severity: 'high', arg_positions: [0], safe_if_stream_arg_at: 0, languages: ['csharp'] },
|
|
2745
2771
|
// Remaining System.IO.File path APIs — class-scoped so they don't collide
|
|
2746
2772
|
// with unrelated methods. Copy/Move take a source AND destination path (both
|
|
2747
2773
|
// attacker-controllable → read-anywhere / write-anywhere), hence [0, 1].
|
|
@@ -2785,6 +2811,23 @@ export const DEFAULT_SINKS = [
|
|
|
2785
2811
|
// `new RestClient(userUrl)` points every later request at attacker-controlled
|
|
2786
2812
|
// infrastructure. Ctor arg 0, taint-gated.
|
|
2787
2813
|
{ method: 'RestClient', class: 'constructor', type: 'ssrf', cwe: 'CWE-918', severity: 'high', arg_positions: [0], languages: ['csharp'] },
|
|
2814
|
+
// C# code injection — CodeDOM runtime compilation (CWE-94), cognium-dev#503
|
|
2815
|
+
// part 2. `provider.CompileAssemblyFromSource(parameters, source)` compiles
|
|
2816
|
+
// and can then execute attacker-supplied C#, so the source argument is the
|
|
2817
|
+
// injection point. The signature is
|
|
2818
|
+
// `CompileAssemblyFromSource(CompilerParameters, params string[] sources)`,
|
|
2819
|
+
// so the sources begin at position 1 — position 0 is the options object.
|
|
2820
|
+
//
|
|
2821
|
+
// These rows are only useful together with the #530 StringBuilder
|
|
2822
|
+
// propagation fix: the Juliet CWE-94 corpus accumulates the compiled source
|
|
2823
|
+
// through `sb.Append(...)` and reads it back with `ToString()`, so before
|
|
2824
|
+
// that fix the sink registered but no taint ever reached it.
|
|
2825
|
+
{ method: 'CompileAssemblyFromSource', type: 'code_injection', cwe: 'CWE-94', severity: 'critical', arg_positions: [1, 2], languages: ['csharp'] },
|
|
2826
|
+
{ method: 'CompileAssemblyFromSourceBatch', type: 'code_injection', cwe: 'CWE-94', severity: 'critical', arg_positions: [1, 2], languages: ['csharp'] },
|
|
2827
|
+
// Roslyn's equivalent pair. `ParseText` turns text into a syntax tree and
|
|
2828
|
+
// `Create` compiles it; either is the point where attacker text becomes code.
|
|
2829
|
+
{ method: 'ParseText', class: 'CSharpSyntaxTree', type: 'code_injection', cwe: 'CWE-94', severity: 'critical', arg_positions: [0], languages: ['csharp'] },
|
|
2830
|
+
{ method: 'ParseText', class: 'SyntaxFactory', type: 'code_injection', cwe: 'CWE-94', severity: 'critical', arg_positions: [0], languages: ['csharp'] },
|
|
2788
2831
|
// C# code injection — dynamic script/assembly loading (CWE-94).
|
|
2789
2832
|
{ method: 'EvaluateAsync', type: 'code_injection', cwe: 'CWE-94', severity: 'critical', arg_positions: [0], languages: ['csharp'] },
|
|
2790
2833
|
{ method: 'RunAsync', class: 'CSharpScript', type: 'code_injection', cwe: 'CWE-94', severity: 'critical', arg_positions: [0], languages: ['csharp'] },
|
|
@@ -2829,6 +2872,10 @@ export const DEFAULT_SINKS = [
|
|
|
2829
2872
|
// Blazor `new MarkupString(x)` renders its argument as raw HTML (the framework's
|
|
2830
2873
|
// documented "trusted markup" escape hatch) — attacker-controlled input is XSS. (ca#275)
|
|
2831
2874
|
{ method: 'MarkupString', class: 'constructor', type: 'xss', cwe: 'CWE-79', severity: 'high', arg_positions: [0], languages: ['csharp'] },
|
|
2875
|
+
// #503 (part 1): `Response.StatusDescription = "Bad " + data` writes
|
|
2876
|
+
// attacker text into the HTTP status line (CWE-81). Surfaced by the
|
|
2877
|
+
// property-assignment synthesiser in the C# extractor, receiver-gated there.
|
|
2878
|
+
{ method: 'StatusDescription', class: 'Response', type: 'xss', cwe: 'CWE-81', severity: 'medium', arg_positions: [0], languages: ['csharp'] },
|
|
2832
2879
|
// `return Content(html, "text/html")` on a controller writes arg 0 to the
|
|
2833
2880
|
// response body unescaped (cognium-dev#275). Taint-gated on arg 0; the common
|
|
2834
2881
|
// `Content(constantString)` and the JSON/plain-text content types are
|
|
@@ -2843,6 +2890,12 @@ export const DEFAULT_SINKS = [
|
|
|
2843
2890
|
// filter is the constructor argument.
|
|
2844
2891
|
{ method: 'DirectorySearcher', type: 'ldap_injection', cwe: 'CWE-90', severity: 'high', arg_positions: [0], languages: ['csharp'] },
|
|
2845
2892
|
{ method: 'DirectoryEntry', type: 'ldap_injection', cwe: 'CWE-90', severity: 'high', arg_positions: [0], languages: ['csharp'] },
|
|
2893
|
+
// #336: a tainted `HttpClient.BaseAddress` gives the attacker the scheme,
|
|
2894
|
+
// host and port of every RELATIVE request made on that client, so the
|
|
2895
|
+
// request arguments can all be constant and the destination still be
|
|
2896
|
+
// attacker-chosen. Surfaced by the property-assignment synthesiser, which
|
|
2897
|
+
// class-gates it to a resolved `HttpClient`.
|
|
2898
|
+
{ method: 'BaseAddress', class: 'HttpClient', type: 'ssrf', cwe: 'CWE-918', severity: 'high', arg_positions: [0], languages: ['csharp'] },
|
|
2846
2899
|
// C# open redirect — ASP.NET MVC / Minimal API redirect helpers (CWE-601,
|
|
2847
2900
|
// cognium-dev#273/#275). Classless: `return Redirect(url)` on a controller is
|
|
2848
2901
|
// an implicit-`this` call (no receiver), and `Results.Redirect(url)` /
|