circle-ir 4.9.16 → 4.9.19
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/findings.d.ts +2 -2
- package/dist/analysis/findings.d.ts.map +1 -1
- package/dist/analysis/findings.js +166 -6
- package/dist/analysis/findings.js.map +1 -1
- package/dist/analysis/passes/language-sources-pass.d.ts +3 -0
- package/dist/analysis/passes/language-sources-pass.d.ts.map +1 -1
- package/dist/analysis/passes/language-sources-pass.js +247 -1
- package/dist/analysis/passes/language-sources-pass.js.map +1 -1
- package/dist/analysis/passes/library-profile-sink-gate-pass.d.ts.map +1 -1
- package/dist/analysis/passes/library-profile-sink-gate-pass.js +48 -13
- package/dist/analysis/passes/library-profile-sink-gate-pass.js.map +1 -1
- package/dist/analysis/passes/library-profile-source-gate-pass.d.ts.map +1 -1
- package/dist/analysis/passes/library-profile-source-gate-pass.js +35 -10
- package/dist/analysis/passes/library-profile-source-gate-pass.js.map +1 -1
- package/dist/analysis/passes/sink-filter-pass.d.ts.map +1 -1
- package/dist/analysis/passes/sink-filter-pass.js +54 -0
- package/dist/analysis/passes/sink-filter-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 +59 -1
- package/dist/analysis/passes/taint-propagation-pass.js.map +1 -1
- package/dist/analyzer.d.ts.map +1 -1
- package/dist/analyzer.js +16 -2
- package/dist/analyzer.js.map +1 -1
- package/dist/browser/circle-ir.js +245 -18
- package/dist/languages/plugins/go.d.ts.map +1 -1
- package/dist/languages/plugins/go.js +71 -0
- package/dist/languages/plugins/go.js.map +1 -1
- package/package.json +1 -1
|
@@ -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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqEG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;
|
|
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;AAG9E,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;CAwFzD"}
|
|
@@ -68,6 +68,7 @@
|
|
|
68
68
|
* to a follow-up if the harness rerun shows material Rust
|
|
69
69
|
* residuals; the Tier 2 8-repo cohort is Java-heavy.
|
|
70
70
|
*/
|
|
71
|
+
import { LIBRARY_API_SURFACE_TAG } from '../library-api-surface-downgrade.js';
|
|
71
72
|
/**
|
|
72
73
|
* Sink types eligible for the library-profile drop. Seeded with
|
|
73
74
|
* `log_injection` (CWE-117) in 3.152.0. Extending this set is a
|
|
@@ -167,9 +168,22 @@ export class LibraryProfileCwe22PathGatePass {
|
|
|
167
168
|
droppedBySourceType: {},
|
|
168
169
|
};
|
|
169
170
|
}
|
|
170
|
-
//
|
|
171
|
-
// `
|
|
172
|
-
|
|
171
|
+
// cognium-dev#288 — the authoritative flow list is
|
|
172
|
+
// `InterproceduralPassResult.additionalFlows`, which is what the
|
|
173
|
+
// post-pipeline rebuild assigns to `taint.flows`. The comment here used to
|
|
174
|
+
// claim `TaintPropagationPass` / `InterproceduralPass` populate
|
|
175
|
+
// `graph.ir.taint.flows`; they do not — nothing ever assigns it, so this
|
|
176
|
+
// pass read `undefined` and returned early on every run.
|
|
177
|
+
//
|
|
178
|
+
// With the source gate now effective BEFORE flow generation (#288), no
|
|
179
|
+
// flow from a gated source should reach this point at all. That makes this
|
|
180
|
+
// a genuine belt-and-suspenders net rather than the primary mechanism —
|
|
181
|
+
// but it is wired correctly now, so if a new flow-producing path ever
|
|
182
|
+
// bypasses the source list it will still be caught instead of silently
|
|
183
|
+
// doing nothing.
|
|
184
|
+
const flows = ctx.hasResult('interprocedural')
|
|
185
|
+
? ctx.getResult('interprocedural').additionalFlows
|
|
186
|
+
: graph.ir.taint.flows;
|
|
173
187
|
if (!flows || flows.length === 0) {
|
|
174
188
|
return {
|
|
175
189
|
profile,
|
|
@@ -178,24 +192,45 @@ export class LibraryProfileCwe22PathGatePass {
|
|
|
178
192
|
droppedBySourceType: {},
|
|
179
193
|
};
|
|
180
194
|
}
|
|
195
|
+
// cognium-dev#288 (option A) — TAG, do not delete.
|
|
196
|
+
//
|
|
197
|
+
// Previously this spliced matching flows out of the list. A flow removed
|
|
198
|
+
// here is unrecoverable downstream: the finding simply never exists, with
|
|
199
|
+
// nothing in the output to say a library-shape judgement was applied. That
|
|
200
|
+
// is the wrong default for the deterministic layer, whose job is to expose
|
|
201
|
+
// signals for adjudication (CLAUDE.md), and it is inconsistent with
|
|
202
|
+
// ADR-008, which keeps such findings and downgrades them.
|
|
203
|
+
//
|
|
204
|
+
// `TaintFlowInfo.tags` exists for exactly this (3.105.0): the
|
|
205
|
+
// `library-api-surface:caller-responsibility` tag is already understood by
|
|
206
|
+
// CLI/SARIF consumers as "downgrade and badge". So the flow survives,
|
|
207
|
+
// carrying the reason it was judged speculative.
|
|
208
|
+
//
|
|
209
|
+
// Note for whoever revisits the policy: ADR-008's
|
|
210
|
+
// `DOWNGRADE_ELIGIBLE_RULE_IDS` deliberately EXCLUDES `path_traversal`
|
|
211
|
+
// (only code_injection / template_injection / xpath_injection /
|
|
212
|
+
// sql_injection are eligible), on the reasoning that a library with a path
|
|
213
|
+
// traversal is a bug whatever its shape. So tagging a CWE-22 flow does not
|
|
214
|
+
// downgrade it under `applyProjectProfileTransform` today — the tag is
|
|
215
|
+
// carried, and the severity policy stays where ADR-008 put it. Deleting
|
|
216
|
+
// these flows, as this pass used to, contradicted that decision outright.
|
|
181
217
|
const droppedBySourceType = {};
|
|
182
|
-
|
|
218
|
+
let tagged = 0;
|
|
183
219
|
for (const flow of flows) {
|
|
184
220
|
if (flow.sink_type === 'path_traversal' &&
|
|
185
221
|
CWE22_SPECULATIVE_SOURCE_TYPES.has(flow.source_type)) {
|
|
186
222
|
droppedBySourceType[flow.source_type] =
|
|
187
223
|
(droppedBySourceType[flow.source_type] ?? 0) + 1;
|
|
188
|
-
|
|
224
|
+
const tags = flow.tags ?? [];
|
|
225
|
+
if (!tags.includes(LIBRARY_API_SURFACE_TAG)) {
|
|
226
|
+
flow.tags = [...tags, LIBRARY_API_SURFACE_TAG];
|
|
227
|
+
}
|
|
228
|
+
tagged++;
|
|
189
229
|
}
|
|
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
230
|
}
|
|
231
|
+
// `dropped` keeps its name for result-shape compatibility but now reports
|
|
232
|
+
// how many flows were TAGGED; none are removed.
|
|
233
|
+
const dropped = tagged;
|
|
199
234
|
return {
|
|
200
235
|
profile,
|
|
201
236
|
applied: true,
|
|
@@ -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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqEG;
|
|
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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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"library-profile-source-gate-pass.d.ts","sourceRoot":"","sources":["../../../src/analysis/passes/library-profile-source-gate-pass.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAC9E,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"library-profile-source-gate-pass.d.ts","sourceRoot":"","sources":["../../../src/analysis/passes/library-profile-source-gate-pass.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAC9E,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAe,MAAM,sBAAsB,CAAC;AAcpF,MAAM,WAAW,8BAA8B;IAC7C;;;;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,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;CACpD;AAaD,qBAAa,4BACX,YAAW,YAAY,CAAC,8BAA8B,CAAC;IAEvD,QAAQ,CAAC,IAAI,iCAAiC;IAC9C,QAAQ,CAAC,QAAQ,EAAG,UAAU,CAAU;IAExC,GAAG,CAAC,GAAG,EAAE,WAAW,GAAG,8BAA8B;CAuEtD"}
|
|
@@ -88,7 +88,19 @@ export class LibraryProfileSourceGatePass {
|
|
|
88
88
|
droppedByType: {},
|
|
89
89
|
};
|
|
90
90
|
}
|
|
91
|
-
|
|
91
|
+
// cognium-dev#288 — read the AUTHORITATIVE source list, mirroring the
|
|
92
|
+
// fetch pattern `LibraryProfileSinkGatePass` already uses and proves.
|
|
93
|
+
//
|
|
94
|
+
// `graph.ir.taint.sources` is NOT that list: `analyzer.ts` constructs the
|
|
95
|
+
// graph with `taint: { sources: [], sinks: [], sanitizers: [] }` and
|
|
96
|
+
// nothing ever populates it, so this pass used to filter a permanently
|
|
97
|
+
// empty array and report `dropped: 0` on every run. The list that both
|
|
98
|
+
// `InterproceduralPass` and the final `taint` rebuild consume is
|
|
99
|
+
// `SinkFilterResult.sources`. The fallback keeps the stand-alone unit
|
|
100
|
+
// tests working, which build an IR by hand and never run SinkFilterPass.
|
|
101
|
+
const sources = ctx.hasResult('sink-filter')
|
|
102
|
+
? ctx.getResult('sink-filter').sources
|
|
103
|
+
: graph.ir.taint.sources;
|
|
92
104
|
if (sources.length === 0) {
|
|
93
105
|
return {
|
|
94
106
|
profile,
|
|
@@ -97,21 +109,34 @@ export class LibraryProfileSourceGatePass {
|
|
|
97
109
|
droppedByType: {},
|
|
98
110
|
};
|
|
99
111
|
}
|
|
112
|
+
// cognium-dev#288 (option A) — COUNT, do not delete.
|
|
113
|
+
//
|
|
114
|
+
// This pass used to splice the speculative sources out of the authoritative
|
|
115
|
+
// list. Deleting them destroys information the downstream adjudication
|
|
116
|
+
// layer needs and is invisible in the output: a consumer cannot tell a
|
|
117
|
+
// clean file from a gated one, and `@cognium/project-profile-detect` can
|
|
118
|
+
// misclassify a repo as a library. It is also inconsistent with how this
|
|
119
|
+
// codebase already answers the same "caller's responsibility" question —
|
|
120
|
+
// `applyLibraryApiSurfaceDowngrade` and `applyProjectProfileTransform`
|
|
121
|
+
// (ADR-008) TAG a finding and downgrade its severity while keeping it,
|
|
122
|
+
// recording `original_severity` so the decision is auditable and
|
|
123
|
+
// reversible.
|
|
124
|
+
//
|
|
125
|
+
// So the sources survive and the signal is carried on the FLOWS instead,
|
|
126
|
+
// via the `library-api-surface:caller-responsibility` tag that
|
|
127
|
+
// `TaintFlowInfo.tags` has existed for since 3.105.0. The count is still
|
|
128
|
+
// reported for diagnostics.
|
|
100
129
|
const droppedByType = {};
|
|
101
|
-
const kept = [];
|
|
102
130
|
for (const src of sources) {
|
|
103
131
|
if (SPECULATIVE_SOURCE_TYPES.has(src.type)) {
|
|
104
132
|
droppedByType[src.type] = (droppedByType[src.type] ?? 0) + 1;
|
|
105
|
-
continue;
|
|
106
133
|
}
|
|
107
|
-
kept.push(src);
|
|
108
134
|
}
|
|
109
|
-
const dropped =
|
|
110
|
-
//
|
|
111
|
-
//
|
|
112
|
-
//
|
|
113
|
-
|
|
114
|
-
sources.push(...kept);
|
|
135
|
+
const dropped = 0;
|
|
136
|
+
// No mutation: `sources` is handed to `TaintPropagationPass` and
|
|
137
|
+
// `InterproceduralPass` and assigned to `taint.sources` by the rebuild.
|
|
138
|
+
// Leaving it intact is the point of option A — the sources/flows stay and
|
|
139
|
+
// the library-shape judgement is expressed as a tag, not a deletion.
|
|
115
140
|
return {
|
|
116
141
|
profile,
|
|
117
142
|
applied: true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"library-profile-source-gate-pass.js","sourceRoot":"","sources":["../../../src/analysis/passes/library-profile-source-gate-pass.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;
|
|
1
|
+
{"version":3,"file":"library-profile-source-gate-pass.js","sourceRoot":"","sources":["../../../src/analysis/passes/library-profile-source-gate-pass.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AAMH;;;;;GAKG;AACH,MAAM,wBAAwB,GAA4B,IAAI,GAAG,CAAa;IAC5E,uBAAuB;IACvB,mBAAmB;CACpB,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,4BAA4B;IAG9B,IAAI,GAAG,6BAA6B,CAAC;IACrC,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,sEAAsE;QACtE,sEAAsE;QACtE,EAAE;QACF,0EAA0E;QAC1E,qEAAqE;QACrE,uEAAuE;QACvE,uEAAuE;QACvE,iEAAiE;QACjE,sEAAsE;QACtE,yEAAyE;QACzE,MAAM,OAAO,GAAkB,GAAG,CAAC,SAAS,CAAC,aAAa,CAAC;YACzD,CAAC,CAAC,GAAG,CAAC,SAAS,CAAmB,aAAa,CAAC,CAAC,OAAO;YACxD,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC;QAC3B,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO;gBACL,OAAO;gBACP,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,CAAC;gBACV,aAAa,EAAE,EAAE;aAClB,CAAC;QACJ,CAAC;QAED,qDAAqD;QACrD,EAAE;QACF,4EAA4E;QAC5E,uEAAuE;QACvE,uEAAuE;QACvE,yEAAyE;QACzE,yEAAyE;QACzE,yEAAyE;QACzE,uEAAuE;QACvE,uEAAuE;QACvE,iEAAiE;QACjE,cAAc;QACd,EAAE;QACF,yEAAyE;QACzE,+DAA+D;QAC/D,yEAAyE;QACzE,4BAA4B;QAC5B,MAAM,aAAa,GAAwC,EAAE,CAAC;QAC9D,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YAC1B,IAAI,wBAAwB,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC3C,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;YAC/D,CAAC;QACH,CAAC;QACD,MAAM,OAAO,GAAG,CAAC,CAAC;QAElB,iEAAiE;QACjE,wEAAwE;QACxE,0EAA0E;QAC1E,qEAAqE;QACrE,OAAO;YACL,OAAO;YACP,OAAO,EAAE,IAAI;YACb,OAAO;YACP,aAAa;SACd,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sink-filter-pass.d.ts","sourceRoot":"","sources":["../../../src/analysis/passes/sink-filter-pass.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,cAAc,EAAwB,MAAM,sBAAsB,CAAC;AACzG,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"sink-filter-pass.d.ts","sourceRoot":"","sources":["../../../src/analysis/passes/sink-filter-pass.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,cAAc,EAAwB,MAAM,sBAAsB,CAAC;AACzG,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAogC9E,MAAM,WAAW,gBAAgB;IAC/B,wDAAwD;IACxD,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,sBAAsB;IACtB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,UAAU,EAAE,cAAc,EAAE,CAAC;CAC9B;AA6BD,qBAAa,cAAe,YAAW,YAAY,CAAC,gBAAgB,CAAC;IACnE,QAAQ,CAAC,IAAI,iBAAiB;IAC9B,QAAQ,CAAC,QAAQ,EAAG,UAAU,CAAU;IAExC,GAAG,CAAC,GAAG,EAAE,WAAW,GAAG,gBAAgB;CA0xCxC;AAkRD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAErD,KAAK,OAAO,GAAG,GAAG,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AA4I1G,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,EACjC,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,EACxB,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,EACxB,OAAO,EAAE,OAAO,EAChB,GAAG,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC,EACrB,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EAC3B,iBAAiB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EAC/B,QAAQ,CAAC,EAAE,MAAM,GAChB,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CA6E5B;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,EACjC,UAAU,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,EAC3C,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,GACvB,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CA2C5B"}
|
|
@@ -201,6 +201,36 @@ const PROTOCOL_CLIENT_PACKAGES = [
|
|
|
201
201
|
// Defense-in-depth: even inside a protocol-client file, do not
|
|
202
202
|
// suppress a sink whose receiver is explicitly an OS-exec class.
|
|
203
203
|
const OS_EXEC_RECEIVER_RE = /\b(?:Runtime|ProcessBuilder|DefaultExecutor|Executor|Exec|Launcher|ProcStarter|ProcessExecutor|RuntimeUtil)\s*[.(]/;
|
|
204
|
+
// Stage 15e — Java xss: `System.out` / `System.err` are not HTTP responses.
|
|
205
|
+
// (cognium-dev#374 — Java over-prediction)
|
|
206
|
+
//
|
|
207
|
+
// The canonical Java xss sink set is class-scoped — `PrintWriter.println`,
|
|
208
|
+
// `ServletOutputStream.println`, `WikiPrinter.println` — plus a CLASSLESS
|
|
209
|
+
// `println` entry so an unresolved writer receiver is still caught.
|
|
210
|
+
// `System.out.println(x)` / `System.err.println(x)` match that classless entry,
|
|
211
|
+
// so every console print of a tainted value was reported as CWE-79.
|
|
212
|
+
//
|
|
213
|
+
// Stdout and stderr are not a browser context: no HTML document, no script
|
|
214
|
+
// execution, no HTTP response. There is no reading under which this is XSS.
|
|
215
|
+
//
|
|
216
|
+
// WHY THIS IS A DROP AND NOT A RETYPE. CWE-117 (improper output neutralisation
|
|
217
|
+
// for logs) would be a defensible label — container stdout is routinely shipped
|
|
218
|
+
// to a log aggregator, where an unneutralised newline forges entries. But Java
|
|
219
|
+
// `log_injection` is deliberately `Logger`-scoped (`info`/`warn`/`error`/…), and
|
|
220
|
+
// extending it to `System.out` is a separate, ADDITIVE decision: console prints
|
|
221
|
+
// are ubiquitous, so it would trade an xss flood for a log_injection flood of
|
|
222
|
+
// the same cardinality and buy no localization improvement. Retyping was also
|
|
223
|
+
// tried at the registry level and matched unpredictably — `System.err` missed
|
|
224
|
+
// the new entry entirely while `PrintWriter.println` gained a spurious
|
|
225
|
+
// `log_injection` alongside its correct xss. So these lines are now unflagged,
|
|
226
|
+
// and the CWE-117 question is left to its own issue with its own measurement.
|
|
227
|
+
//
|
|
228
|
+
// This matters out of proportion to its subtlety because *every* Java class
|
|
229
|
+
// prints. On the 500-repo vuln-localization benchmark Java emits ~306
|
|
230
|
+
// security-typed findings per repo against ~8 genuinely vulnerable files, so the
|
|
231
|
+
// real finding drowns and hit@3 collapses to 16% while recall stays at 79% —
|
|
232
|
+
// a ranking failure caused by FP volume, not a detection gap.
|
|
233
|
+
const JAVA_STDOUT_PRINT_RE = /\bSystem\s*\.\s*(?:out|err)\s*\.\s*(?:println|print|printf|write|append)\s*\(/;
|
|
204
234
|
// ---------------------------------------------------------------------------
|
|
205
235
|
// Stage 11 — Java command_injection (CWE-78) FP reduction.
|
|
206
236
|
// (cognium-dev #179 Sink 1 — Sprint 44)
|
|
@@ -1937,6 +1967,30 @@ export class SinkFilterPass {
|
|
|
1937
1967
|
if (language === 'java' && !HTML_CONTENT_TYPE_RE.test(ctx.code)) {
|
|
1938
1968
|
filtered = filtered.filter(sink => !(sink.type === 'xss' && sink.method === 'body'));
|
|
1939
1969
|
}
|
|
1970
|
+
// Stage 15e — Java xss on a `System.out` / `System.err` print. See
|
|
1971
|
+
// JAVA_STDOUT_PRINT_RE above for why this is not CWE-79, and why it is a
|
|
1972
|
+
// drop rather than a retype to CWE-117.
|
|
1973
|
+
//
|
|
1974
|
+
// Scoped three ways so the real XSS writers are untouched:
|
|
1975
|
+
// 1. `xss` sinks only;
|
|
1976
|
+
// 2. only sinks with NO resolved class — `sink.class` records which
|
|
1977
|
+
// pattern matched, so `undefined` means the classless `println` entry
|
|
1978
|
+
// caught it. `PrintWriter.println` / `ServletOutputStream.println`
|
|
1979
|
+
// resolve to their class and never reach this branch;
|
|
1980
|
+
// 3. only when the sink's own line actually prints via System.out/err.
|
|
1981
|
+
//
|
|
1982
|
+
// Known limitation of (3): a single line carrying BOTH a System.out print
|
|
1983
|
+
// and an unresolved real writer print would lose the latter. The sink
|
|
1984
|
+
// carries no column, and every other stage here judges on line text, so
|
|
1985
|
+
// this follows the existing convention rather than inventing a new one.
|
|
1986
|
+
if (language === 'java') {
|
|
1987
|
+
const sourceLines = ctx.code.split('\n');
|
|
1988
|
+
filtered = filtered.filter(sink => {
|
|
1989
|
+
if (sink.type !== 'xss' || sink.class !== undefined)
|
|
1990
|
+
return true;
|
|
1991
|
+
return !JAVA_STDOUT_PRINT_RE.test(sourceLines[sink.line - 1] ?? '');
|
|
1992
|
+
});
|
|
1993
|
+
}
|
|
1940
1994
|
// Stage 15d — Java path_traversal: `if (x.contains("..")) throw/return`
|
|
1941
1995
|
// reject-guard. (cognium-dev#269 CWE-22 review) A user path checked for a
|
|
1942
1996
|
// `..` traversal token and rejected before any filesystem use cannot carry
|