circle-ir 3.175.0 → 3.177.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.
@@ -0,0 +1,90 @@
1
+ /**
2
+ * cognium-dev #256 — same-file argument-type resolver.
3
+ *
4
+ * Two sink-shape gates ship in circle-ir today match only the DIRECT/LITERAL
5
+ * argument form and miss argument indirection:
6
+ *
7
+ * 1. `safe_if_class_literal_at` (taint-matcher.ts, #22) — matches
8
+ * `readValue(json, Foo.class)` but not `readValue(json, templateClass)`
9
+ * where `templateClass` is a `Class<T>` parameter.
10
+ * 2. Stage-11 `PROCESS_BUILDER_ARGV_FORM_RE` (sink-filter-pass.ts, #179)
11
+ * matches `new ProcessBuilder(Arrays.asList(...))` but not
12
+ * `new ProcessBuilder(buildCommand(...))` where `buildCommand` returns
13
+ * `List<String>`.
14
+ *
15
+ * This module provides two pure, same-file, `TypeInfo[]`-based helpers to
16
+ * resolve the effective type of an argument that is either:
17
+ * - a bare identifier (parameter or field name), or
18
+ * - a method-call expression (callee name).
19
+ *
20
+ * Same-file only — locals declared inside method bodies and cross-file
21
+ * resolutions are deferred. Both #256 repros (jib, flyingsaucer) are
22
+ * same-method-parameter / same-class-static-callee, so this scope suffices.
23
+ *
24
+ * Design guarantee: both resolvers return null liberally. A null return
25
+ * flows to the existing gate's default-dangerous behavior (sink fires) —
26
+ * so any resolver bug regresses gracefully to current (over-firing)
27
+ * behavior, never to false-negative.
28
+ */
29
+ import type { TypeInfo } from '../types/index.js';
30
+ /**
31
+ * Resolve the declared type of a bare-identifier argument (parameter or
32
+ * field) visible at `callInMethod` scope.
33
+ *
34
+ * Lookup order:
35
+ * 1. Parameters of the enclosing method (matching `callInMethod`).
36
+ * 2. Fields of the enclosing type (any visibility).
37
+ * 3. If enclosing type not found, scan ALL types' method params + fields
38
+ * (best-effort for top-level functions or method-name collisions).
39
+ *
40
+ * Returns the raw type string as extracted (`"Class<T>"`, `"List<String>"`,
41
+ * `"java.util.List<String>"`, `"Class<? extends JsonTemplate>"`, …) or null.
42
+ */
43
+ export declare function resolveIdentifierType(name: string, callInMethod: string | null | undefined, types: TypeInfo[]): string | null;
44
+ /**
45
+ * Resolve the declared return type of a same-file method invoked by
46
+ * `calleeName`. Accepts a bare callee name (as extracted into
47
+ * `ArgumentInfo.variable` for call expressions like `buildCommand(x, y)`).
48
+ *
49
+ * Preference order:
50
+ * 1. Method on the enclosing type matching `callInMethod`.
51
+ * 2. Method on any type in the file (static call `MyClass.foo()` case).
52
+ *
53
+ * Overload handling: if the enclosing type has multiple methods with the
54
+ * same name, returns the first one whose `return_type` is non-null. Full
55
+ * overload resolution would need argument-expression typing that we don't
56
+ * have; ambiguity is rare in practice and biases toward null (which
57
+ * flows to the current default-dangerous behavior).
58
+ */
59
+ export declare function resolveCallReturnType(calleeName: string, callInMethod: string | null | undefined, types: TypeInfo[]): string | null;
60
+ /**
61
+ * true when the raw type string represents a Java `Class` type (any bound):
62
+ * `Class`, `Class<T>`, `Class<? extends X>`, `Class<Foo>`, `java.lang.Class<...>`.
63
+ *
64
+ * NEVER matches:
65
+ * - `Class.forName(x)` — that's a call expression, not a declared type;
66
+ * lookups against `ir.types` won't find it (JDK reflection isn't
67
+ * user code).
68
+ * - `getClass()` return type — for the same reason.
69
+ * - Raw types missing generic bounds are Jackson-safe in the same way
70
+ * as the generic form: a bare `Class` param still has a compile-time
71
+ * type identity, so we accept it.
72
+ */
73
+ export declare function isBoundedClassType(rawType: string | null): boolean;
74
+ /**
75
+ * true when the raw type resolves to a container shape that
76
+ * `ProcessBuilder(argv)` accepts as non-exploitable — the JVM passes the
77
+ * elements to `fork(2)` directly, no shell interpolation:
78
+ *
79
+ * - `List<String>` (any parameterization narrower than `Object`)
80
+ * - `ArrayList<String>`, `LinkedList<String>`
81
+ * - `Collection<String>`, `Iterable<String>`, `Deque<String>`, `Queue<String>`
82
+ * - `String[]`, `String ...` (varargs)
83
+ * - Fully qualified variants: `java.util.List<String>`, etc.
84
+ *
85
+ * Excludes bare `List` / `List<Object>` / `Collection<?>` — those permit
86
+ * arbitrary element types that could carry non-String content the JVM
87
+ * would `.toString()` unsafely.
88
+ */
89
+ export declare function isArgvContainerType(rawType: string | null): boolean;
90
+ //# sourceMappingURL=arg-type-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"arg-type-resolver.d.ts","sourceRoot":"","sources":["../../src/analysis/arg-type-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAoBlD;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACvC,KAAK,EAAE,QAAQ,EAAE,GAChB,MAAM,GAAG,IAAI,CA8Bf;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACvC,KAAK,EAAE,QAAQ,EAAE,GAChB,MAAM,GAAG,IAAI,CAef;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAIlE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAUnE"}
@@ -0,0 +1,174 @@
1
+ /**
2
+ * cognium-dev #256 — same-file argument-type resolver.
3
+ *
4
+ * Two sink-shape gates ship in circle-ir today match only the DIRECT/LITERAL
5
+ * argument form and miss argument indirection:
6
+ *
7
+ * 1. `safe_if_class_literal_at` (taint-matcher.ts, #22) — matches
8
+ * `readValue(json, Foo.class)` but not `readValue(json, templateClass)`
9
+ * where `templateClass` is a `Class<T>` parameter.
10
+ * 2. Stage-11 `PROCESS_BUILDER_ARGV_FORM_RE` (sink-filter-pass.ts, #179)
11
+ * matches `new ProcessBuilder(Arrays.asList(...))` but not
12
+ * `new ProcessBuilder(buildCommand(...))` where `buildCommand` returns
13
+ * `List<String>`.
14
+ *
15
+ * This module provides two pure, same-file, `TypeInfo[]`-based helpers to
16
+ * resolve the effective type of an argument that is either:
17
+ * - a bare identifier (parameter or field name), or
18
+ * - a method-call expression (callee name).
19
+ *
20
+ * Same-file only — locals declared inside method bodies and cross-file
21
+ * resolutions are deferred. Both #256 repros (jib, flyingsaucer) are
22
+ * same-method-parameter / same-class-static-callee, so this scope suffices.
23
+ *
24
+ * Design guarantee: both resolvers return null liberally. A null return
25
+ * flows to the existing gate's default-dangerous behavior (sink fires) —
26
+ * so any resolver bug regresses gracefully to current (over-firing)
27
+ * behavior, never to false-negative.
28
+ */
29
+ /**
30
+ * Locate the TypeInfo whose `methods` list contains a method named
31
+ * `callInMethod`. Falls back to `null` if not found (e.g. top-level
32
+ * function, or method name collision that our best-effort match misses).
33
+ */
34
+ function findEnclosingType(callInMethod, types) {
35
+ if (!callInMethod)
36
+ return null;
37
+ for (const t of types) {
38
+ for (const m of t.methods) {
39
+ if (m.name === callInMethod)
40
+ return t;
41
+ }
42
+ }
43
+ return null;
44
+ }
45
+ /**
46
+ * Resolve the declared type of a bare-identifier argument (parameter or
47
+ * field) visible at `callInMethod` scope.
48
+ *
49
+ * Lookup order:
50
+ * 1. Parameters of the enclosing method (matching `callInMethod`).
51
+ * 2. Fields of the enclosing type (any visibility).
52
+ * 3. If enclosing type not found, scan ALL types' method params + fields
53
+ * (best-effort for top-level functions or method-name collisions).
54
+ *
55
+ * Returns the raw type string as extracted (`"Class<T>"`, `"List<String>"`,
56
+ * `"java.util.List<String>"`, `"Class<? extends JsonTemplate>"`, …) or null.
57
+ */
58
+ export function resolveIdentifierType(name, callInMethod, types) {
59
+ if (!name)
60
+ return null;
61
+ const enclosing = findEnclosingType(callInMethod, types);
62
+ if (enclosing) {
63
+ // Parameter check (preferred — narrower scope, shadows fields).
64
+ for (const m of enclosing.methods) {
65
+ if (m.name !== callInMethod)
66
+ continue;
67
+ for (const p of m.parameters) {
68
+ if (p.name === name && p.type)
69
+ return p.type;
70
+ }
71
+ }
72
+ // Field check on the enclosing type.
73
+ for (const f of enclosing.fields) {
74
+ if (f.name === name && f.type)
75
+ return f.type;
76
+ }
77
+ return null;
78
+ }
79
+ // Fallback: scan all types (top-level function case, or extractor didn't
80
+ // populate `in_method` reliably for this language).
81
+ for (const t of types) {
82
+ for (const m of t.methods) {
83
+ for (const p of m.parameters) {
84
+ if (p.name === name && p.type)
85
+ return p.type;
86
+ }
87
+ }
88
+ for (const f of t.fields) {
89
+ if (f.name === name && f.type)
90
+ return f.type;
91
+ }
92
+ }
93
+ return null;
94
+ }
95
+ /**
96
+ * Resolve the declared return type of a same-file method invoked by
97
+ * `calleeName`. Accepts a bare callee name (as extracted into
98
+ * `ArgumentInfo.variable` for call expressions like `buildCommand(x, y)`).
99
+ *
100
+ * Preference order:
101
+ * 1. Method on the enclosing type matching `callInMethod`.
102
+ * 2. Method on any type in the file (static call `MyClass.foo()` case).
103
+ *
104
+ * Overload handling: if the enclosing type has multiple methods with the
105
+ * same name, returns the first one whose `return_type` is non-null. Full
106
+ * overload resolution would need argument-expression typing that we don't
107
+ * have; ambiguity is rare in practice and biases toward null (which
108
+ * flows to the current default-dangerous behavior).
109
+ */
110
+ export function resolveCallReturnType(calleeName, callInMethod, types) {
111
+ if (!calleeName)
112
+ return null;
113
+ const enclosing = findEnclosingType(callInMethod, types);
114
+ if (enclosing) {
115
+ for (const m of enclosing.methods) {
116
+ if (m.name === calleeName && m.return_type)
117
+ return m.return_type;
118
+ }
119
+ }
120
+ // Fallback: any type in file. Static calls / helper classes.
121
+ for (const t of types) {
122
+ for (const m of t.methods) {
123
+ if (m.name === calleeName && m.return_type)
124
+ return m.return_type;
125
+ }
126
+ }
127
+ return null;
128
+ }
129
+ /**
130
+ * true when the raw type string represents a Java `Class` type (any bound):
131
+ * `Class`, `Class<T>`, `Class<? extends X>`, `Class<Foo>`, `java.lang.Class<...>`.
132
+ *
133
+ * NEVER matches:
134
+ * - `Class.forName(x)` — that's a call expression, not a declared type;
135
+ * lookups against `ir.types` won't find it (JDK reflection isn't
136
+ * user code).
137
+ * - `getClass()` return type — for the same reason.
138
+ * - Raw types missing generic bounds are Jackson-safe in the same way
139
+ * as the generic form: a bare `Class` param still has a compile-time
140
+ * type identity, so we accept it.
141
+ */
142
+ export function isBoundedClassType(rawType) {
143
+ if (!rawType)
144
+ return false;
145
+ const stripped = rawType.trim().replace(/^(?:java\.lang\.)+/, '');
146
+ return /^Class(?:\s*<[\s\S]*>)?$/.test(stripped);
147
+ }
148
+ /**
149
+ * true when the raw type resolves to a container shape that
150
+ * `ProcessBuilder(argv)` accepts as non-exploitable — the JVM passes the
151
+ * elements to `fork(2)` directly, no shell interpolation:
152
+ *
153
+ * - `List<String>` (any parameterization narrower than `Object`)
154
+ * - `ArrayList<String>`, `LinkedList<String>`
155
+ * - `Collection<String>`, `Iterable<String>`, `Deque<String>`, `Queue<String>`
156
+ * - `String[]`, `String ...` (varargs)
157
+ * - Fully qualified variants: `java.util.List<String>`, etc.
158
+ *
159
+ * Excludes bare `List` / `List<Object>` / `Collection<?>` — those permit
160
+ * arbitrary element types that could carry non-String content the JVM
161
+ * would `.toString()` unsafely.
162
+ */
163
+ export function isArgvContainerType(rawType) {
164
+ if (!rawType)
165
+ return false;
166
+ const s = rawType.trim().replace(/^(?:java\.util\.|java\.lang\.)+/, '');
167
+ // String[] or String...
168
+ if (/^String\s*(?:\[\s*\]|\.\.\.)$/.test(s))
169
+ return true;
170
+ // Container<String>-like — permit CharSequence too (String subtype narrower
171
+ // than Object). Reject `<?>`, `<? extends Object>`, bare `<Object>`.
172
+ return /^(?:List|ArrayList|LinkedList|Collection|Iterable|Deque|Queue)\s*<\s*(?:String|CharSequence|java\.lang\.String)\b/.test(s);
173
+ }
174
+ //# sourceMappingURL=arg-type-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"arg-type-resolver.js","sourceRoot":"","sources":["../../src/analysis/arg-type-resolver.ts"],"names":[],"mappings":"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"}
@@ -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,EA6hB1C,CAAC;AAmGF,eAAO,MAAM,aAAa,EAAE,WAAW,EAwuDtC,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,gBAAgB,EAwThD,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"}
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,EA6hB1C,CAAC;AA+KF,eAAO,MAAM,aAAa,EAAE,WAAW,EA6uDtC,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,gBAAgB,EAwThD,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"}
@@ -602,6 +602,76 @@ const OPEN_REDIRECT_FRAMEWORK_SINKS = [
602
602
  { method: 'Redirect', class: 'Ctx', type: 'open_redirect', cwe: 'CWE-601', severity: 'medium', arg_positions: [0], languages: ['go'] },
603
603
  ];
604
604
  // =========================================================================
605
+ // cognium-dev #240 ship 2 — extend deserialization (CWE-502) framework
606
+ // coverage across Python (pickle / marshal / dill / jsonpickle) and Go
607
+ // (encoding/gob, gopkg.in/yaml). Java coverage (readObject / XStream /
608
+ // ObjectMapper / Yaml SnakeYAML / Kryo / XMLDecoder) is already extensive
609
+ // via DEFAULT_SINKS below; JS/TS `node-serialize.unserialize` added here.
610
+ //
611
+ // Spread into DEFAULT_SINKS below (per the ship-1 pattern).
612
+ // =========================================================================
613
+ const DESERIALIZATION_FRAMEWORK_SINKS = [
614
+ // --- Python: stdlib + popular third-party --------------------------------
615
+ // pickle: known-dangerous, any unpickle on untrusted bytes is RCE.
616
+ { method: 'loads', class: 'pickle', type: 'deserialization', cwe: 'CWE-502', severity: 'critical', arg_positions: [0], languages: ['python'] },
617
+ { method: 'load', class: 'pickle', type: 'deserialization', cwe: 'CWE-502', severity: 'critical', arg_positions: [0], languages: ['python'] },
618
+ // cPickle alias (Python 2 name, still around in older codebases).
619
+ { method: 'loads', class: 'cPickle', type: 'deserialization', cwe: 'CWE-502', severity: 'critical', arg_positions: [0], languages: ['python'] },
620
+ { method: 'load', class: 'cPickle', type: 'deserialization', cwe: 'CWE-502', severity: 'critical', arg_positions: [0], languages: ['python'] },
621
+ // marshal: stdlib code-object deserializer. Loading a tainted bytestring
622
+ // as a code object followed by `exec` is arbitrary-code execution.
623
+ { method: 'loads', class: 'marshal', type: 'deserialization', cwe: 'CWE-502', severity: 'critical', arg_positions: [0], languages: ['python'] },
624
+ { method: 'load', class: 'marshal', type: 'deserialization', cwe: 'CWE-502', severity: 'critical', arg_positions: [0], languages: ['python'] },
625
+ // dill: pickle superset — same RCE profile.
626
+ { method: 'loads', class: 'dill', type: 'deserialization', cwe: 'CWE-502', severity: 'critical', arg_positions: [0], languages: ['python'] },
627
+ { method: 'load', class: 'dill', type: 'deserialization', cwe: 'CWE-502', severity: 'critical', arg_positions: [0], languages: ['python'] },
628
+ // jsonpickle: JSON wrapper around pickle — trusts `py/object` marker.
629
+ { method: 'decode', class: 'jsonpickle', type: 'deserialization', cwe: 'CWE-502', severity: 'critical', arg_positions: [0], languages: ['python'] },
630
+ // --- Go: encoding/gob + yaml.Unmarshal -----------------------------------
631
+ // gob.NewDecoder(r).Decode(&v): tainted io.Reader → arbitrary Go values.
632
+ { method: 'Decode', class: 'Decoder', type: 'deserialization', cwe: 'CWE-502', severity: 'high', arg_positions: [0], languages: ['go'] },
633
+ // gopkg.in/yaml.v2 + v3 top-level function; interface{} target is unsafe.
634
+ { method: 'Unmarshal', class: 'yaml', type: 'deserialization', cwe: 'CWE-502', severity: 'high', arg_positions: [0], languages: ['go'] },
635
+ // --- JS/TS: node-serialize ------------------------------------------------
636
+ // Known-dangerous — accepts embedded IIFE that runs during deserialize.
637
+ { method: 'unserialize', class: 'nodeSerialize', type: 'deserialization', cwe: 'CWE-502', severity: 'critical', arg_positions: [0], languages: ['javascript', 'typescript'] },
638
+ ];
639
+ // =========================================================================
640
+ // cognium-dev #240 ship 2 — extend nosql_injection (CWE-943) framework
641
+ // coverage. JS/TS MongoDB Collection + Mongoose Model are already covered
642
+ // at line 1776+. This ship adds Python (pymongo), Java (Spring Data
643
+ // MongoTemplate + native MongoCollection), and Go (mongo-driver Collection).
644
+ //
645
+ // Spread into DEFAULT_SINKS below.
646
+ // =========================================================================
647
+ const NOSQL_FRAMEWORK_SINKS = [
648
+ // --- Python: pymongo Collection ------------------------------------------
649
+ // Every filter-taking Collection method; filter arg[0] is the query dict.
650
+ { method: 'find', class: 'Collection', type: 'nosql_injection', cwe: 'CWE-943', severity: 'high', arg_positions: [0], languages: ['python'] },
651
+ { method: 'find_one', class: 'Collection', type: 'nosql_injection', cwe: 'CWE-943', severity: 'high', arg_positions: [0], languages: ['python'] },
652
+ { method: 'aggregate', class: 'Collection', type: 'nosql_injection', cwe: 'CWE-943', severity: 'high', arg_positions: [0], languages: ['python'] },
653
+ { method: 'update_one', class: 'Collection', type: 'nosql_injection', cwe: 'CWE-943', severity: 'high', arg_positions: [0, 1], languages: ['python'] },
654
+ { method: 'update_many', class: 'Collection', type: 'nosql_injection', cwe: 'CWE-943', severity: 'high', arg_positions: [0, 1], languages: ['python'] },
655
+ { method: 'delete_one', class: 'Collection', type: 'nosql_injection', cwe: 'CWE-943', severity: 'high', arg_positions: [0], languages: ['python'] },
656
+ { method: 'delete_many', class: 'Collection', type: 'nosql_injection', cwe: 'CWE-943', severity: 'high', arg_positions: [0], languages: ['python'] },
657
+ { method: 'count_documents', class: 'Collection', type: 'nosql_injection', cwe: 'CWE-943', severity: 'high', arg_positions: [0], languages: ['python'] },
658
+ // --- Java: Spring Data MongoTemplate + native MongoCollection ------------
659
+ { method: 'find', class: 'MongoTemplate', type: 'nosql_injection', cwe: 'CWE-943', severity: 'high', arg_positions: [0], languages: ['java'] },
660
+ { method: 'findOne', class: 'MongoTemplate', type: 'nosql_injection', cwe: 'CWE-943', severity: 'high', arg_positions: [0], languages: ['java'] },
661
+ { method: 'findAll', class: 'MongoTemplate', type: 'nosql_injection', cwe: 'CWE-943', severity: 'high', arg_positions: [0], languages: ['java'] },
662
+ { method: 'find', class: 'MongoCollection', type: 'nosql_injection', cwe: 'CWE-943', severity: 'high', arg_positions: [0], languages: ['java'] },
663
+ { method: 'aggregate', class: 'MongoCollection', type: 'nosql_injection', cwe: 'CWE-943', severity: 'high', arg_positions: [0], languages: ['java'] },
664
+ // --- Go: go.mongodb.org/mongo-driver Collection --------------------------
665
+ // These fire once Go local-receiver type resolution lands (see
666
+ // taint-matcher.ts + #240 ship 2 Go receiver work). Same gate as the
667
+ // gin/fiber Ctx sinks in ship 1.
668
+ { method: 'Find', class: 'Collection', type: 'nosql_injection', cwe: 'CWE-943', severity: 'high', arg_positions: [1], languages: ['go'] },
669
+ { method: 'FindOne', class: 'Collection', type: 'nosql_injection', cwe: 'CWE-943', severity: 'high', arg_positions: [1], languages: ['go'] },
670
+ { method: 'UpdateOne', class: 'Collection', type: 'nosql_injection', cwe: 'CWE-943', severity: 'high', arg_positions: [1, 2], languages: ['go'] },
671
+ { method: 'UpdateMany', class: 'Collection', type: 'nosql_injection', cwe: 'CWE-943', severity: 'high', arg_positions: [1, 2], languages: ['go'] },
672
+ { method: 'DeleteOne', class: 'Collection', type: 'nosql_injection', cwe: 'CWE-943', severity: 'high', arg_positions: [1], languages: ['go'] },
673
+ ];
674
+ // =========================================================================
605
675
  // cognium-dev #240 ship 1 — extend trust_boundary (CWE-501) framework coverage
606
676
  //
607
677
  // Extracted from DEFAULT_SINKS (see note above). Spread into DEFAULT_SINKS
@@ -2297,6 +2367,11 @@ export const DEFAULT_SINKS = [
2297
2367
  // inference complexity limit (TS2590). See ~lines 661-752.
2298
2368
  ...OPEN_REDIRECT_FRAMEWORK_SINKS,
2299
2369
  ...TRUST_BOUNDARY_FRAMEWORK_SINKS,
2370
+ // cognium-dev #240 ship 2 — extended framework sinks for
2371
+ // deserialization (CWE-502) and nosql_injection (CWE-943). Same
2372
+ // pattern: constants defined near the ship-1 blocks and spread here.
2373
+ ...DESERIALIZATION_FRAMEWORK_SINKS,
2374
+ ...NOSQL_FRAMEWORK_SINKS,
2300
2375
  ];
2301
2376
  export const DEFAULT_SANITIZERS = [
2302
2377
  // SQL Injection - proper parameter binding sanitizes input