circle-ir 3.153.0 → 3.154.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.
@@ -1,11 +1,24 @@
1
1
  /**
2
2
  * LibraryProfileSinkGatePass — cognium-dev #232
3
+ * LibraryProfileCwe22PathGatePass — cognium-dev #245 RC1 (belt-and-suspenders)
3
4
  *
4
5
  * Sink-side companion to `LibraryProfileSourceGatePass` (#236,
5
6
  * shipped 3.151.0). Under the `library/*` project profile, drops
6
7
  * sinks whose entire vulnerability class is off-topic for library
7
8
  * code — currently just `log_injection` (CWE-117).
8
9
  *
10
+ * The second (companion) class `LibraryProfileCwe22PathGatePass`
11
+ * runs post-`InterproceduralPass` and filters `graph.ir.taint.flows`
12
+ * for CWE-22 (`path_traversal`) flows whose source shape is
13
+ * speculative (`interprocedural_param` / `constructor_field`).
14
+ * `LibraryProfileSourceGatePass` already drops those `SourceType`s
15
+ * from `graph.ir.taint.sources` under `library/*`, but this
16
+ * companion catches any residual flows synthesised downstream that
17
+ * bypassed the source-list mutation (belt-and-suspenders).
18
+ * Empirically 170/246 CWE-22 H+C findings on the Tier 2 10-repo
19
+ * cohort carried an `interprocedural_param` source with empty
20
+ * `source.code` (cognium-ai#189 §4).
21
+ *
9
22
  * Motivation:
10
23
  *
11
24
  * `log_injection` requires a downstream log-viewer that interprets
@@ -56,7 +69,7 @@
56
69
  * residuals; the Tier 2 8-repo cohort is Java-heavy.
57
70
  */
58
71
  import type { AnalysisPass, PassContext } from '../../graph/analysis-pass.js';
59
- import type { ProjectProfile, SinkType } from '../../types/index.js';
72
+ import type { ProjectProfile, SinkType, SourceType } from '../../types/index.js';
60
73
  export interface LibraryProfileSinkGateResult {
61
74
  /**
62
75
  * Resolved `ProjectProfile` observed on `graph.ir.meta.projectProfile`
@@ -86,4 +99,33 @@ export declare class LibraryProfileSinkGatePass implements AnalysisPass<LibraryP
86
99
  readonly category: "security";
87
100
  run(ctx: PassContext): LibraryProfileSinkGateResult;
88
101
  }
102
+ export interface LibraryProfileCwe22PathGateResult {
103
+ /**
104
+ * Resolved `ProjectProfile` observed on `graph.ir.meta.projectProfile`
105
+ * at the time this pass ran. `undefined` when no profile was
106
+ * supplied by the caller.
107
+ */
108
+ profile: ProjectProfile | undefined;
109
+ /**
110
+ * Whether the profile matched the library-shape trigger and the
111
+ * gate was applied. `false` for every non-library shape and for
112
+ * `'unknown'` / absent profiles.
113
+ */
114
+ applied: boolean;
115
+ /**
116
+ * Number of CWE-22 flows removed from `graph.ir.taint.flows`.
117
+ * Zero when `applied === false` or when no matching flow existed.
118
+ */
119
+ dropped: number;
120
+ /**
121
+ * Breakdown of drops by speculative source shape. Empty object
122
+ * when `applied === false` or when no drops fired.
123
+ */
124
+ droppedBySourceType: Partial<Record<SourceType, number>>;
125
+ }
126
+ export declare class LibraryProfileCwe22PathGatePass implements AnalysisPass<LibraryProfileCwe22PathGateResult> {
127
+ readonly name = "library-profile-cwe22-path-gate";
128
+ readonly category: "security";
129
+ run(ctx: PassContext): LibraryProfileCwe22PathGateResult;
130
+ }
89
131
  //# sourceMappingURL=library-profile-sink-gate-pass.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"library-profile-sink-gate-pass.d.ts","sourceRoot":"","sources":["../../../src/analysis/passes/library-profile-sink-gate-pass.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAC9E,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAa,MAAM,sBAAsB,CAAC;AAYhF,MAAM,WAAW,4BAA4B;IAC3C;;;;OAIG;IACH,OAAO,EAAE,cAAc,GAAG,SAAS,CAAC;IACpC;;;;OAIG;IACH,OAAO,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,aAAa,EAAE,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;CAClD;AAaD,qBAAa,0BACX,YAAW,YAAY,CAAC,4BAA4B,CAAC;IAErD,QAAQ,CAAC,IAAI,+BAA+B;IAC5C,QAAQ,CAAC,QAAQ,EAAG,UAAU,CAAU;IAExC,GAAG,CAAC,GAAG,EAAE,WAAW,GAAG,4BAA4B;CA0DpD"}
1
+ {"version":3,"file":"library-profile-sink-gate-pass.d.ts","sourceRoot":"","sources":["../../../src/analysis/passes/library-profile-sink-gate-pass.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqEG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAC9E,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,UAAU,EAA4B,MAAM,sBAAsB,CAAC;AAY3G,MAAM,WAAW,4BAA4B;IAC3C;;;;OAIG;IACH,OAAO,EAAE,cAAc,GAAG,SAAS,CAAC;IACpC;;;;OAIG;IACH,OAAO,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,aAAa,EAAE,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;CAClD;AAaD,qBAAa,0BACX,YAAW,YAAY,CAAC,4BAA4B,CAAC;IAErD,QAAQ,CAAC,IAAI,+BAA+B;IAC5C,QAAQ,CAAC,QAAQ,EAAG,UAAU,CAAU;IAExC,GAAG,CAAC,GAAG,EAAE,WAAW,GAAG,4BAA4B;CA0DpD;AAcD,MAAM,WAAW,iCAAiC;IAChD;;;;OAIG;IACH,OAAO,EAAE,cAAc,GAAG,SAAS,CAAC;IACpC;;;;OAIG;IACH,OAAO,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,mBAAmB,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;CAC1D;AAED,qBAAa,+BACX,YAAW,YAAY,CAAC,iCAAiC,CAAC;IAE1D,QAAQ,CAAC,IAAI,qCAAqC;IAClD,QAAQ,CAAC,QAAQ,EAAG,UAAU,CAAU;IAExC,GAAG,CAAC,GAAG,EAAE,WAAW,GAAG,iCAAiC;CAuDzD"}
@@ -1,11 +1,24 @@
1
1
  /**
2
2
  * LibraryProfileSinkGatePass — cognium-dev #232
3
+ * LibraryProfileCwe22PathGatePass — cognium-dev #245 RC1 (belt-and-suspenders)
3
4
  *
4
5
  * Sink-side companion to `LibraryProfileSourceGatePass` (#236,
5
6
  * shipped 3.151.0). Under the `library/*` project profile, drops
6
7
  * sinks whose entire vulnerability class is off-topic for library
7
8
  * code — currently just `log_injection` (CWE-117).
8
9
  *
10
+ * The second (companion) class `LibraryProfileCwe22PathGatePass`
11
+ * runs post-`InterproceduralPass` and filters `graph.ir.taint.flows`
12
+ * for CWE-22 (`path_traversal`) flows whose source shape is
13
+ * speculative (`interprocedural_param` / `constructor_field`).
14
+ * `LibraryProfileSourceGatePass` already drops those `SourceType`s
15
+ * from `graph.ir.taint.sources` under `library/*`, but this
16
+ * companion catches any residual flows synthesised downstream that
17
+ * bypassed the source-list mutation (belt-and-suspenders).
18
+ * Empirically 170/246 CWE-22 H+C findings on the Tier 2 10-repo
19
+ * cohort carried an `interprocedural_param` source with empty
20
+ * `source.code` (cognium-ai#189 §4).
21
+ *
9
22
  * Motivation:
10
23
  *
11
24
  * `log_injection` requires a downstream log-viewer that interprets
@@ -129,4 +142,66 @@ export class LibraryProfileSinkGatePass {
129
142
  };
130
143
  }
131
144
  }
145
+ /**
146
+ * `SourceType`s eligible for the CWE-22 belt-and-suspenders drop.
147
+ * These are the same speculative shapes that `LibraryProfileSourceGatePass`
148
+ * drops from `graph.ir.taint.sources` under `library/*`. Listed
149
+ * here so the post-flow companion catches any flow that made it
150
+ * past the source-list mutation.
151
+ */
152
+ const CWE22_SPECULATIVE_SOURCE_TYPES = new Set([
153
+ 'interprocedural_param',
154
+ 'constructor_field',
155
+ ]);
156
+ export class LibraryProfileCwe22PathGatePass {
157
+ name = 'library-profile-cwe22-path-gate';
158
+ category = 'security';
159
+ run(ctx) {
160
+ const { graph } = ctx;
161
+ const profile = graph.ir.meta.projectProfile;
162
+ if (!isLibraryShape(profile)) {
163
+ return {
164
+ profile,
165
+ applied: false,
166
+ dropped: 0,
167
+ droppedBySourceType: {},
168
+ };
169
+ }
170
+ // `TaintPropagationPass` / `InterproceduralPass` populate
171
+ // `graph.ir.taint.flows`. Nothing to filter if no flow ever ran.
172
+ const flows = graph.ir.taint.flows;
173
+ if (!flows || flows.length === 0) {
174
+ return {
175
+ profile,
176
+ applied: true,
177
+ dropped: 0,
178
+ droppedBySourceType: {},
179
+ };
180
+ }
181
+ const droppedBySourceType = {};
182
+ const kept = [];
183
+ for (const flow of flows) {
184
+ if (flow.sink_type === 'path_traversal' &&
185
+ CWE22_SPECULATIVE_SOURCE_TYPES.has(flow.source_type)) {
186
+ droppedBySourceType[flow.source_type] =
187
+ (droppedBySourceType[flow.source_type] ?? 0) + 1;
188
+ continue;
189
+ }
190
+ kept.push(flow);
191
+ }
192
+ const dropped = flows.length - kept.length;
193
+ // Mutate the flow array in place so downstream consumers
194
+ // (`CrossFilePass`, SARIF writer) see the filtered list.
195
+ if (dropped > 0) {
196
+ flows.length = 0;
197
+ flows.push(...kept);
198
+ }
199
+ return {
200
+ profile,
201
+ applied: true,
202
+ dropped,
203
+ droppedBySourceType,
204
+ };
205
+ }
206
+ }
132
207
  //# sourceMappingURL=library-profile-sink-gate-pass.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"library-profile-sink-gate-pass.js","sourceRoot":"","sources":["../../../src/analysis/passes/library-profile-sink-gate-pass.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AAMH;;;;GAIG;AACH,MAAM,kBAAkB,GAA0B,IAAI,GAAG,CAAW;IAClE,eAAe;CAChB,CAAC,CAAC;AA2BH;;;;;GAKG;AACH,SAAS,cAAc,CAAC,OAAmC;IACzD,IAAI,CAAC,OAAO,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACpD,OAAO,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;AACxC,CAAC;AAED,MAAM,OAAO,0BAA0B;IAG5B,IAAI,GAAG,2BAA2B,CAAC;IACnC,QAAQ,GAAG,UAAmB,CAAC;IAExC,GAAG,CAAC,GAAgB;QAClB,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC;QACtB,MAAM,OAAO,GAAG,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC;QAE7C,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC;YAC7B,OAAO;gBACL,OAAO;gBACP,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,CAAC;gBACV,aAAa,EAAE,EAAE;aAClB,CAAC;QACJ,CAAC;QAED,uDAAuD;QACvD,6DAA6D;QAC7D,8DAA8D;QAC9D,4DAA4D;QAC5D,mCAAmC;QACnC,MAAM,KAAK,GAAgB,GAAG,CAAC,SAAS,CAAC,aAAa,CAAC;YACrD,CAAC,CAAC,GAAG,CAAC,SAAS,CAAmB,aAAa,CAAC,CAAC,KAAK;YACtD,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC;QAEzB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO;gBACL,OAAO;gBACP,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,CAAC;gBACV,aAAa,EAAE,EAAE;aAClB,CAAC;QACJ,CAAC;QAED,MAAM,aAAa,GAAsC,EAAE,CAAC;QAC5D,MAAM,IAAI,GAAgB,EAAE,CAAC;QAC7B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBACtC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;gBAC/D,SAAS;YACX,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAE3C,yDAAyD;QACzD,gEAAgE;QAChE,6CAA6C;QAC7C,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;YAChB,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;YACjB,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;QACtB,CAAC;QAED,OAAO;YACL,OAAO;YACP,OAAO,EAAE,IAAI;YACb,OAAO;YACP,aAAa;SACd,CAAC;IACJ,CAAC;CACF"}
1
+ {"version":3,"file":"library-profile-sink-gate-pass.js","sourceRoot":"","sources":["../../../src/analysis/passes/library-profile-sink-gate-pass.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,104 @@
1
+ /**
2
+ * LibraryProfileXssGatePass — cognium-dev #244
3
+ *
4
+ * Sink-side companion to `LibraryProfileSinkGatePass` (#232, canonical
5
+ * #112, shipped 3.152.0). Where #112 drops entire `SinkType`s under
6
+ * `library/*` (currently `log_injection`), this pass narrows the
7
+ * `xss` `SinkType` on a per-receiver-class basis: `TaintSink`s whose
8
+ * simple-name receiver class is in `XSS_NON_HTML_OUTPUT_CLASSES` are
9
+ * dropped before flow generation.
10
+ *
11
+ * Motivation:
12
+ *
13
+ * The current `xss` sink class treats any `String`-valued method
14
+ * receiver as a potential CWE-79 sink. Under `library/*` this
15
+ * over-collects by ~100x. A 10-repo Tier 2 library-profile audit
16
+ * (cognium-ai#189 §3, 2026-07) surfaced 507 H+C findings across
17
+ * hutool, xdocreport, languagetool, AndroidAsync, Sentinel,
18
+ * mybatis-plus, flyingsaucer, jedis — **zero** of which are actual
19
+ * HTML-output sinks. The 507 decompose as:
20
+ *
21
+ * - 149 (29.4%) `StringBuilder.append` / `StringBuffer.append` —
22
+ * in-memory buffers, not HTML output.
23
+ * - 66 (13.0%) `PrintStream.println` on `System.out` / `System.err` —
24
+ * CLI stdio, not HTML output.
25
+ * - 43 ( 8.5%) `response.body()` on `HttpRequest` / `HttpResponse` —
26
+ * outbound HTTP client body READ — a taint SOURCE, not sink.
27
+ * - 27 ( 5.3%) `response.end()` header terminator (AndroidAsync).
28
+ * - 26 ( 5.1%) `HttpSession.setAttribute` — session store IO.
29
+ * - 33 ( 6.5%) `write` on jedis wire-protocol writers.
30
+ * - 91 (17.9%) other (Loggers, JSON parsers, Netflix Zuul
31
+ * `RequestContext`, Sentinel `Context`).
32
+ *
33
+ * All eight buckets are `library/*` internal buffer / IO / logger /
34
+ * HTTP-client / router / JSON-parser plumbing. No web-app response
35
+ * writes reach `HttpServletResponse.getWriter().println(taint)` or
36
+ * a template renderer.
37
+ *
38
+ * Where #112 targets the whole vulnerability class (`log_injection`
39
+ * is off-topic for every library), CWE-79 is legitimate for library
40
+ * code that writes HTML (Thymeleaf, FreeMarker, Velocity, JSP
41
+ * fragments); it is only the RECEIVER SHAPE that is off-topic.
42
+ * Hence a class-level allowlist would over-drop and a class-level
43
+ * denylist is the calibrated response.
44
+ *
45
+ * Pipeline slot: runs immediately after `LibraryProfileSinkGatePass`
46
+ * (#112) and before `TaintPropagationPass` (so no dropped sink ever
47
+ * reaches the flow generators). Ordering ensures both library-profile
48
+ * gates fire under the same predicate before flow synthesis.
49
+ *
50
+ * Guardrails:
51
+ * - Pass is a no-op when `graph.ir.meta.projectProfile` is absent,
52
+ * `'unknown'`, or does not start with `library/`. Callers that do
53
+ * not opt in to profile detection get the unmodified sink list.
54
+ * - Only `xss`-type sinks are eligible; every other `SinkType`
55
+ * (`sql_injection`, `command_injection`, `path_traversal`,
56
+ * `deserialization`, …) is preserved unconditionally.
57
+ * - The class denylist is intentionally conservative: it only
58
+ * targets classes measured with zero HTML-output flows across the
59
+ * 10-repo cohort. `HttpServletResponse`, `JspWriter`,
60
+ * `ServletOutputStream`, `PrintWriter` (in servlet context),
61
+ * template engines (Thymeleaf `SpringWebContext`, FreeMarker
62
+ * `Environment`, Velocity `VelocityContext`) are **not** on the
63
+ * denylist and continue to fire.
64
+ * - Guarded on `disabledPasses.has('library-profile-xss-gate')` at
65
+ * the pipeline registration site.
66
+ *
67
+ * Reference:
68
+ * - cognium-dev#244 — this ticket.
69
+ * - cognium-dev#232 (#112, 3.152.0) — sink-side profile gate template.
70
+ * - cognium-ai#189 §3 — Tier 2 library-profile CWE-79 audit.
71
+ * - `docs/ARCHITECTURE.md` ADR-011.
72
+ */
73
+ import type { AnalysisPass, PassContext } from '../../graph/analysis-pass.js';
74
+ import type { ProjectProfile } from '../../types/index.js';
75
+ export interface LibraryProfileXssGateResult {
76
+ /**
77
+ * Resolved `ProjectProfile` observed on `graph.ir.meta.projectProfile`
78
+ * at the time this pass ran. `undefined` when no profile was
79
+ * supplied by the caller.
80
+ */
81
+ profile: ProjectProfile | undefined;
82
+ /**
83
+ * Whether the profile matched the library-shape trigger and the
84
+ * gate was applied. `false` for every non-library shape and for
85
+ * `'unknown'` / absent profiles.
86
+ */
87
+ applied: boolean;
88
+ /**
89
+ * Number of `xss` sinks removed from the authoritative sink list.
90
+ * Zero when `applied === false`.
91
+ */
92
+ dropped: number;
93
+ /**
94
+ * Breakdown of drops by receiver class (simple name). Empty object
95
+ * when `applied === false` or when no drops fired.
96
+ */
97
+ droppedByClass: Record<string, number>;
98
+ }
99
+ export declare class LibraryProfileXssGatePass implements AnalysisPass<LibraryProfileXssGateResult> {
100
+ readonly name = "library-profile-xss-gate";
101
+ readonly category: "security";
102
+ run(ctx: PassContext): LibraryProfileXssGateResult;
103
+ }
104
+ //# sourceMappingURL=library-profile-xss-gate-pass.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"library-profile-xss-gate-pass.d.ts","sourceRoot":"","sources":["../../../src/analysis/passes/library-profile-xss-gate-pass.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuEG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAC9E,OAAO,KAAK,EAAE,cAAc,EAAa,MAAM,sBAAsB,CAAC;AA6DtE,MAAM,WAAW,2BAA2B;IAC1C;;;;OAIG;IACH,OAAO,EAAE,cAAc,GAAG,SAAS,CAAC;IACpC;;;;OAIG;IACH,OAAO,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACxC;AAaD,qBAAa,yBACX,YAAW,YAAY,CAAC,2BAA2B,CAAC;IAEpD,QAAQ,CAAC,IAAI,8BAA8B;IAC3C,QAAQ,CAAC,QAAQ,EAAG,UAAU,CAAU;IAExC,GAAG,CAAC,GAAG,EAAE,WAAW,GAAG,2BAA2B;CA0DnD"}
@@ -0,0 +1,196 @@
1
+ /**
2
+ * LibraryProfileXssGatePass — cognium-dev #244
3
+ *
4
+ * Sink-side companion to `LibraryProfileSinkGatePass` (#232, canonical
5
+ * #112, shipped 3.152.0). Where #112 drops entire `SinkType`s under
6
+ * `library/*` (currently `log_injection`), this pass narrows the
7
+ * `xss` `SinkType` on a per-receiver-class basis: `TaintSink`s whose
8
+ * simple-name receiver class is in `XSS_NON_HTML_OUTPUT_CLASSES` are
9
+ * dropped before flow generation.
10
+ *
11
+ * Motivation:
12
+ *
13
+ * The current `xss` sink class treats any `String`-valued method
14
+ * receiver as a potential CWE-79 sink. Under `library/*` this
15
+ * over-collects by ~100x. A 10-repo Tier 2 library-profile audit
16
+ * (cognium-ai#189 §3, 2026-07) surfaced 507 H+C findings across
17
+ * hutool, xdocreport, languagetool, AndroidAsync, Sentinel,
18
+ * mybatis-plus, flyingsaucer, jedis — **zero** of which are actual
19
+ * HTML-output sinks. The 507 decompose as:
20
+ *
21
+ * - 149 (29.4%) `StringBuilder.append` / `StringBuffer.append` —
22
+ * in-memory buffers, not HTML output.
23
+ * - 66 (13.0%) `PrintStream.println` on `System.out` / `System.err` —
24
+ * CLI stdio, not HTML output.
25
+ * - 43 ( 8.5%) `response.body()` on `HttpRequest` / `HttpResponse` —
26
+ * outbound HTTP client body READ — a taint SOURCE, not sink.
27
+ * - 27 ( 5.3%) `response.end()` header terminator (AndroidAsync).
28
+ * - 26 ( 5.1%) `HttpSession.setAttribute` — session store IO.
29
+ * - 33 ( 6.5%) `write` on jedis wire-protocol writers.
30
+ * - 91 (17.9%) other (Loggers, JSON parsers, Netflix Zuul
31
+ * `RequestContext`, Sentinel `Context`).
32
+ *
33
+ * All eight buckets are `library/*` internal buffer / IO / logger /
34
+ * HTTP-client / router / JSON-parser plumbing. No web-app response
35
+ * writes reach `HttpServletResponse.getWriter().println(taint)` or
36
+ * a template renderer.
37
+ *
38
+ * Where #112 targets the whole vulnerability class (`log_injection`
39
+ * is off-topic for every library), CWE-79 is legitimate for library
40
+ * code that writes HTML (Thymeleaf, FreeMarker, Velocity, JSP
41
+ * fragments); it is only the RECEIVER SHAPE that is off-topic.
42
+ * Hence a class-level allowlist would over-drop and a class-level
43
+ * denylist is the calibrated response.
44
+ *
45
+ * Pipeline slot: runs immediately after `LibraryProfileSinkGatePass`
46
+ * (#112) and before `TaintPropagationPass` (so no dropped sink ever
47
+ * reaches the flow generators). Ordering ensures both library-profile
48
+ * gates fire under the same predicate before flow synthesis.
49
+ *
50
+ * Guardrails:
51
+ * - Pass is a no-op when `graph.ir.meta.projectProfile` is absent,
52
+ * `'unknown'`, or does not start with `library/`. Callers that do
53
+ * not opt in to profile detection get the unmodified sink list.
54
+ * - Only `xss`-type sinks are eligible; every other `SinkType`
55
+ * (`sql_injection`, `command_injection`, `path_traversal`,
56
+ * `deserialization`, …) is preserved unconditionally.
57
+ * - The class denylist is intentionally conservative: it only
58
+ * targets classes measured with zero HTML-output flows across the
59
+ * 10-repo cohort. `HttpServletResponse`, `JspWriter`,
60
+ * `ServletOutputStream`, `PrintWriter` (in servlet context),
61
+ * template engines (Thymeleaf `SpringWebContext`, FreeMarker
62
+ * `Environment`, Velocity `VelocityContext`) are **not** on the
63
+ * denylist and continue to fire.
64
+ * - Guarded on `disabledPasses.has('library-profile-xss-gate')` at
65
+ * the pipeline registration site.
66
+ *
67
+ * Reference:
68
+ * - cognium-dev#244 — this ticket.
69
+ * - cognium-dev#232 (#112, 3.152.0) — sink-side profile gate template.
70
+ * - cognium-ai#189 §3 — Tier 2 library-profile CWE-79 audit.
71
+ * - `docs/ARCHITECTURE.md` ADR-011.
72
+ */
73
+ /**
74
+ * Simple-name receiver classes for which `xss` sinks are dropped
75
+ * under `library/*` profile. Each entry was measured with zero
76
+ * true-positive HTML-output flows across the 10-repo Tier 2 cohort
77
+ * (cognium-ai#189 §3, 2026-07).
78
+ *
79
+ * Extending this set is a deliberate, reviewable change. Adding an
80
+ * entry risks false-negative regressions on the OWASP Benchmark
81
+ * Java, SecuriBench Micro, and Juliet CWE-79 recall guards.
82
+ */
83
+ const XSS_NON_HTML_OUTPUT_CLASSES = new Set([
84
+ // In-memory buffers — no HTML output surface.
85
+ 'StringBuilder',
86
+ 'StringBuffer',
87
+ 'CharArrayWriter',
88
+ 'ByteArrayOutputStream',
89
+ // CLI stdio — CLI apps, not web response bodies.
90
+ 'PrintStream',
91
+ 'System',
92
+ // HTTP client builders — these are taint SOURCES (outbound reads),
93
+ // not XSS sinks. `response.body()`, `.post()`, `.get()` on
94
+ // hutool `HttpRequest` / `HttpResponse` reach us as sink
95
+ // matches only because xss.yaml catches String-valued receivers.
96
+ 'HttpRequest',
97
+ 'HttpRequestBuilder',
98
+ 'HttpResponse',
99
+ // Servlet non-body IO. `HttpSession.setAttribute`, `HttpSession.putValue`,
100
+ // `HttpServletRequest.setAttribute` are session/request attribute
101
+ // IO, not HTML output. Under `library/*` there is no JSP renderer
102
+ // reflecting them back. `HttpServletResponse` itself is NOT on
103
+ // this list — its writers are genuine XSS sinks.
104
+ 'HttpSession',
105
+ 'ServletRequest',
106
+ 'HttpServletRequest',
107
+ // Wire-protocol writers (jedis internal).
108
+ 'RedisOutputStream',
109
+ 'SafeEncoder',
110
+ 'RESP2',
111
+ 'Protocol',
112
+ // JSON parsers — these read JSON into POJOs. Source, not sink.
113
+ 'JSONUtil',
114
+ 'JSON',
115
+ 'ObjectMapper',
116
+ 'JsonReader',
117
+ // Loggers — log injection is CWE-117 (already covered by #112);
118
+ // these appear here because xss.yaml has a String-valued catch-all
119
+ // that hits Logger receivers.
120
+ 'Logger',
121
+ 'LoggerFactory',
122
+ 'Log',
123
+ 'Slf4jLogger',
124
+ // Router / interceptor context stores. Zuul `RequestContext`,
125
+ // Sentinel `Context` are internal request-processing state, not
126
+ // HTML output.
127
+ 'RequestContext',
128
+ 'Context',
129
+ ]);
130
+ /**
131
+ * Returns true when the resolved profile begins with `library/`
132
+ * (i.e. any `library/production`, `library/dev`, `library/sample`,
133
+ * `library/benchmark`, `library/test` environment binding).
134
+ * `'unknown'` and non-library shapes return false.
135
+ */
136
+ function isLibraryShape(profile) {
137
+ if (!profile || profile === 'unknown')
138
+ return false;
139
+ return profile.startsWith('library/');
140
+ }
141
+ export class LibraryProfileXssGatePass {
142
+ name = 'library-profile-xss-gate';
143
+ category = 'security';
144
+ run(ctx) {
145
+ const { graph } = ctx;
146
+ const profile = graph.ir.meta.projectProfile;
147
+ if (!isLibraryShape(profile)) {
148
+ return {
149
+ profile,
150
+ applied: false,
151
+ dropped: 0,
152
+ droppedByClass: {},
153
+ };
154
+ }
155
+ // Authoritative sink list mirrors the fetch pattern in
156
+ // `LibraryProfileSinkGatePass` and `SinkSemanticsPass`: prefer
157
+ // `SinkFilterResult.sinks` (what `analyzer.ts` assembles the
158
+ // final `taint.sinks` from), fall back to `graph.ir.taint.sinks`
159
+ // for stand-alone unit tests that don't run `SinkFilterPass`.
160
+ const sinks = ctx.hasResult('sink-filter')
161
+ ? ctx.getResult('sink-filter').sinks
162
+ : graph.ir.taint.sinks;
163
+ if (sinks.length === 0) {
164
+ return {
165
+ profile,
166
+ applied: true,
167
+ dropped: 0,
168
+ droppedByClass: {},
169
+ };
170
+ }
171
+ const droppedByClass = {};
172
+ const kept = [];
173
+ for (const sink of sinks) {
174
+ if (sink.type === 'xss' && sink.class && XSS_NON_HTML_OUTPUT_CLASSES.has(sink.class)) {
175
+ droppedByClass[sink.class] = (droppedByClass[sink.class] ?? 0) + 1;
176
+ continue;
177
+ }
178
+ kept.push(sink);
179
+ }
180
+ const dropped = sinks.length - kept.length;
181
+ // Mutate the array in place so downstream passes see the
182
+ // filtered list. Preserves array identity for any consumer that
183
+ // captured a reference before this pass ran.
184
+ if (dropped > 0) {
185
+ sinks.length = 0;
186
+ sinks.push(...kept);
187
+ }
188
+ return {
189
+ profile,
190
+ applied: true,
191
+ dropped,
192
+ droppedByClass,
193
+ };
194
+ }
195
+ }
196
+ //# sourceMappingURL=library-profile-xss-gate-pass.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"library-profile-xss-gate-pass.js","sourceRoot":"","sources":["../../../src/analysis/passes/library-profile-xss-gate-pass.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuEG;AAMH;;;;;;;;;GASG;AACH,MAAM,2BAA2B,GAAwB,IAAI,GAAG,CAAS;IACvE,8CAA8C;IAC9C,eAAe;IACf,cAAc;IACd,iBAAiB;IACjB,uBAAuB;IACvB,iDAAiD;IACjD,aAAa;IACb,QAAQ;IACR,mEAAmE;IACnE,2DAA2D;IAC3D,yDAAyD;IACzD,iEAAiE;IACjE,aAAa;IACb,oBAAoB;IACpB,cAAc;IACd,2EAA2E;IAC3E,kEAAkE;IAClE,kEAAkE;IAClE,+DAA+D;IAC/D,iDAAiD;IACjD,aAAa;IACb,gBAAgB;IAChB,oBAAoB;IACpB,0CAA0C;IAC1C,mBAAmB;IACnB,aAAa;IACb,OAAO;IACP,UAAU;IACV,+DAA+D;IAC/D,UAAU;IACV,MAAM;IACN,cAAc;IACd,YAAY;IACZ,gEAAgE;IAChE,mEAAmE;IACnE,8BAA8B;IAC9B,QAAQ;IACR,eAAe;IACf,KAAK;IACL,aAAa;IACb,8DAA8D;IAC9D,gEAAgE;IAChE,eAAe;IACf,gBAAgB;IAChB,SAAS;CACV,CAAC,CAAC;AA2BH;;;;;GAKG;AACH,SAAS,cAAc,CAAC,OAAmC;IACzD,IAAI,CAAC,OAAO,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACpD,OAAO,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;AACxC,CAAC;AAED,MAAM,OAAO,yBAAyB;IAG3B,IAAI,GAAG,0BAA0B,CAAC;IAClC,QAAQ,GAAG,UAAmB,CAAC;IAExC,GAAG,CAAC,GAAgB;QAClB,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC;QACtB,MAAM,OAAO,GAAG,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC;QAE7C,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC;YAC7B,OAAO;gBACL,OAAO;gBACP,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,CAAC;gBACV,cAAc,EAAE,EAAE;aACnB,CAAC;QACJ,CAAC;QAED,uDAAuD;QACvD,+DAA+D;QAC/D,6DAA6D;QAC7D,iEAAiE;QACjE,8DAA8D;QAC9D,MAAM,KAAK,GAAgB,GAAG,CAAC,SAAS,CAAC,aAAa,CAAC;YACrD,CAAC,CAAC,GAAG,CAAC,SAAS,CAAmB,aAAa,CAAC,CAAC,KAAK;YACtD,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC;QAEzB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO;gBACL,OAAO;gBACP,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,CAAC;gBACV,cAAc,EAAE,EAAE;aACnB,CAAC;QACJ,CAAC;QAED,MAAM,cAAc,GAA2B,EAAE,CAAC;QAClD,MAAM,IAAI,GAAgB,EAAE,CAAC;QAC7B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI,2BAA2B,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;gBACrF,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;gBACnE,SAAS;YACX,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAE3C,yDAAyD;QACzD,gEAAgE;QAChE,6CAA6C;QAC7C,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;YAChB,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;YACjB,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;QACtB,CAAC;QAED,OAAO;YACL,OAAO;YACP,OAAO,EAAE,IAAI;YACb,OAAO;YACP,cAAc;SACf,CAAC;IACJ,CAAC;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"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"}
package/dist/analyzer.js CHANGED
@@ -79,7 +79,8 @@ import { LibraryProfileSourceGatePass } from './analysis/passes/library-profile-
79
79
  import { SinkFilterPass, filterCleanVariableSinks, filterSanitizedSinks } from './analysis/passes/sink-filter-pass.js';
80
80
  import { SinkSemanticsPass } from './analysis/passes/sink-semantics-pass.js';
81
81
  import { CliMainReflectionSuppressPass } from './analysis/passes/cli-main-reflection-suppress-pass.js';
82
- import { LibraryProfileSinkGatePass } from './analysis/passes/library-profile-sink-gate-pass.js';
82
+ import { LibraryProfileSinkGatePass, LibraryProfileCwe22PathGatePass } from './analysis/passes/library-profile-sink-gate-pass.js';
83
+ import { LibraryProfileXssGatePass } from './analysis/passes/library-profile-xss-gate-pass.js';
83
84
  import { TaintPropagationPass } from './analysis/passes/taint-propagation-pass.js';
84
85
  import { InterproceduralPass } from './analysis/passes/interprocedural-pass.js';
85
86
  import { DeadCodePass } from './analysis/passes/dead-code-pass.js';
@@ -459,10 +460,33 @@ export async function analyze(code, filePath, language, options = {}) {
459
460
  // No-op when profile is absent, `'unknown'`, or non-library shape.
460
461
  if (!disabledPasses.has('library-profile-sink-gate'))
461
462
  pipeline.add(new LibraryProfileSinkGatePass());
463
+ // cognium-dev #244: under `library/*` project profile, drop `xss`
464
+ // (CWE-79) sinks whose simple-name receiver class is on a curated
465
+ // non-HTML-output denylist (`StringBuilder`, `PrintStream`,
466
+ // `HttpSession`, `HttpRequest`, jedis wire-writers, JSON parsers,
467
+ // Loggers, Zuul `RequestContext`, Sentinel `Context`). Runs after
468
+ // #112 so the sink list is already free of `log_injection` sinks;
469
+ // runs before `TaintPropagationPass` so flow generators never see
470
+ // the dropped sinks. Empirically drops 507 H+C FPs across the 10-repo
471
+ // Tier 2 cohort (cognium-ai#189 §3, 2026-07).
472
+ if (!disabledPasses.has('library-profile-xss-gate'))
473
+ pipeline.add(new LibraryProfileXssGatePass());
462
474
  pipeline.add(new TaintPropagationPass());
463
475
  pipeline.add(new InterproceduralPass({
464
476
  enableEntryPointGate: options.enableEntryPointGate ?? true,
465
477
  }));
478
+ // cognium-dev #245 RC1 (belt-and-suspenders): under `library/*`
479
+ // profile, drop CWE-22 (`path_traversal`) flows whose source shape
480
+ // is `interprocedural_param` / `constructor_field` — the same
481
+ // speculative shapes `LibraryProfileSourceGatePass` (#236) already
482
+ // drops from `graph.ir.taint.sources`. Belt-and-suspenders because
483
+ // 170/246 CWE-22 H+C findings on the Tier 2 10-repo cohort
484
+ // (cognium-ai#189 §4) carried an `interprocedural_param` source
485
+ // with empty `source.code`. Runs post-`InterproceduralPass` so it
486
+ // filters the authoritative `taint.flows` list. No-op when profile
487
+ // is absent, `'unknown'`, or non-library shape.
488
+ if (!disabledPasses.has('library-profile-cwe22-path-gate'))
489
+ pipeline.add(new LibraryProfileCwe22PathGatePass());
466
490
  // Secret scanner runs after LanguageSourcesPass so the legacy Bash
467
491
  // `hardcoded-credential` findings are already in the dedup buffer.
468
492
  if (!disabledPasses.has('scan-secrets'))