circle-ir 3.147.0 → 3.149.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.
- package/dist/analysis/passes/cli-main-reflection-suppress-pass.d.ts +94 -0
- package/dist/analysis/passes/cli-main-reflection-suppress-pass.d.ts.map +1 -0
- package/dist/analysis/passes/cli-main-reflection-suppress-pass.js +337 -0
- package/dist/analysis/passes/cli-main-reflection-suppress-pass.js.map +1 -0
- package/dist/analysis/passes/language-sources-pass.d.ts.map +1 -1
- package/dist/analysis/passes/language-sources-pass.js +27 -0
- package/dist/analysis/passes/language-sources-pass.js.map +1 -1
- package/dist/analysis/passes/sink-semantics-pass.d.ts.map +1 -1
- package/dist/analysis/passes/sink-semantics-pass.js +10 -1
- package/dist/analysis/passes/sink-semantics-pass.js.map +1 -1
- package/dist/analyzer.d.ts.map +1 -1
- package/dist/analyzer.js +10 -0
- package/dist/analyzer.js.map +1 -1
- package/dist/browser/circle-ir.js +211 -5
- package/package.json +1 -1
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CliMainReflectionSuppressPass — cognium-dev #162 Option B
|
|
3
|
+
*
|
|
4
|
+
* Drops Java reflection `code_injection` sinks in files that look like
|
|
5
|
+
* a fat-jar CLI tool's own artifact — files that ship a `main(String[])`
|
|
6
|
+
* entry point AND carry no web-framework entry-point signal anywhere
|
|
7
|
+
* in the file. The `main(String[])` on the same compilation unit *is*
|
|
8
|
+
* the trust boundary; the caller is the OS shell that invoked the jar.
|
|
9
|
+
*
|
|
10
|
+
* Motivation (from the ticket):
|
|
11
|
+
*
|
|
12
|
+
* // antlr/tool/.../TestRig.java — 5 reflection sinks reported HIGH
|
|
13
|
+
* public static void main(String[] args) throws Exception {
|
|
14
|
+
* TestRig testRig = new TestRig(args);
|
|
15
|
+
* ...
|
|
16
|
+
* }
|
|
17
|
+
* public void process() throws Exception {
|
|
18
|
+
* String lexerName = grammarName + "Lexer";
|
|
19
|
+
* ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
|
20
|
+
* Class<? extends Lexer> lexerClass =
|
|
21
|
+
* cl.loadClass(lexerName).asSubclass(Lexer.class); // sink
|
|
22
|
+
* Constructor<? extends Lexer> lexerCtor =
|
|
23
|
+
* lexerClass.getConstructor(CharStream.class);
|
|
24
|
+
* Lexer lexer = lexerCtor.newInstance((CharStream)null); // sink
|
|
25
|
+
* ...
|
|
26
|
+
* }
|
|
27
|
+
*
|
|
28
|
+
* This is documented behaviour of ANTLR's `TestRig` developer CLI —
|
|
29
|
+
* same shape as `javac`, `java -jar`, `python -m`. The tool's whole
|
|
30
|
+
* purpose is "give me a grammar name from the command line and I'll
|
|
31
|
+
* run it." Blocked 5/49 HIGH FPs in the top-100 Java harness.
|
|
32
|
+
*
|
|
33
|
+
* ## Signal
|
|
34
|
+
*
|
|
35
|
+
* Language MUST be Java. Per-file signal (all must hold):
|
|
36
|
+
*
|
|
37
|
+
* 1. Some type in the file declares a `main(String[])` method
|
|
38
|
+
* (matches `looksLikeMainMethod` in `entry-point-detection.ts`).
|
|
39
|
+
* 2. NO type in the file carries a Tier-1 class-level web-framework
|
|
40
|
+
* annotation (`@RestController`, `@Controller`, `@Service`,
|
|
41
|
+
* `@Component`, `@Path`, `@WebServlet`, `@ServerEndpoint`,
|
|
42
|
+
* `@FeignClient`, `@Repository`).
|
|
43
|
+
* 3. NO method in the file carries a Tier-1 method-level
|
|
44
|
+
* web-framework annotation (Spring `@*Mapping`, `@KafkaListener`,
|
|
45
|
+
* `@JmsListener`, JAX-RS `@GET/@POST/…`, `@Scheduled`, `@Path`,
|
|
46
|
+
* `@DataBoundConstructor`/`@DataBoundSetter`).
|
|
47
|
+
* 4. NO type in the file extends a Tier-1 supertype (HttpServlet,
|
|
48
|
+
* GenericServlet, Filter, HandlerInterceptor, CommandLineRunner,
|
|
49
|
+
* SimpleChannelInboundHandler, etc.).
|
|
50
|
+
*
|
|
51
|
+
* ## Action
|
|
52
|
+
*
|
|
53
|
+
* When the signal fires, drop from the `SinkFilterResult.sinks` list
|
|
54
|
+
* (the authoritative sink array consumed by `TaintPropagationPass` and
|
|
55
|
+
* folded into `taint.sinks` by `analyzer.ts`) every sink whose
|
|
56
|
+
* `type === 'code_injection'` AND `method` is a Java reflection
|
|
57
|
+
* / ClassLoader surface method. The gate does NOT touch other
|
|
58
|
+
* `code_injection` shapes: ScriptEngine.eval / GroovyShell.evaluate /
|
|
59
|
+
* SpEL `parseExpression` remain flagged in CLI tools because they
|
|
60
|
+
* evaluate scripts (a genuinely dangerous CLI misuse), not just class
|
|
61
|
+
* names.
|
|
62
|
+
*
|
|
63
|
+
* ## Pipeline slot
|
|
64
|
+
*
|
|
65
|
+
* Runs after `SinkSemanticsPass` (so its curated-registry drops have
|
|
66
|
+
* already fired) and before `TaintPropagationPass` (so the flow
|
|
67
|
+
* generators never see the dropped sinks). Emits no findings.
|
|
68
|
+
*
|
|
69
|
+
* ## Pillar I / safety
|
|
70
|
+
*
|
|
71
|
+
* - Pure per-file heuristic; no LLM, no filesystem, no config knobs.
|
|
72
|
+
* - False-negative-safe: any web-framework signal in the file
|
|
73
|
+
* (annotation OR supertype OR Tier-1 method annotation) disables
|
|
74
|
+
* the gate. Recall preserved for `@RestController` classes,
|
|
75
|
+
* `HttpServlet` subclasses, Netty handlers, Jenkins plugins, and
|
|
76
|
+
* Kafka/JMS listeners that happen to also expose a `main`.
|
|
77
|
+
* - Reflection-only: `Runtime.exec`, `ProcessBuilder.start`,
|
|
78
|
+
* `Statement.execute`, `ObjectInputStream.readObject`, SpEL,
|
|
79
|
+
* Groovy, ScriptEngine — all unaffected.
|
|
80
|
+
* - Java-only: non-Java sources fall through untouched.
|
|
81
|
+
*/
|
|
82
|
+
import type { AnalysisPass, PassContext } from '../../graph/analysis-pass.js';
|
|
83
|
+
export interface CliMainReflectionSuppressResult {
|
|
84
|
+
/** Whether the fat-jar CLI signal fired for this file. */
|
|
85
|
+
cliMainSignal: boolean;
|
|
86
|
+
/** Number of reflection `code_injection` sinks dropped. */
|
|
87
|
+
droppedCount: number;
|
|
88
|
+
}
|
|
89
|
+
export declare class CliMainReflectionSuppressPass implements AnalysisPass<CliMainReflectionSuppressResult> {
|
|
90
|
+
readonly name = "cli-main-reflection-suppress";
|
|
91
|
+
readonly category: "security";
|
|
92
|
+
run(ctx: PassContext): CliMainReflectionSuppressResult;
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=cli-main-reflection-suppress-pass.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-main-reflection-suppress-pass.d.ts","sourceRoot":"","sources":["../../../src/analysis/passes/cli-main-reflection-suppress-pass.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgFG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAG9E,MAAM,WAAW,+BAA+B;IAC9C,0DAA0D;IAC1D,aAAa,EAAE,OAAO,CAAC;IACvB,2DAA2D;IAC3D,YAAY,EAAE,MAAM,CAAC;CACtB;AAiKD,qBAAa,6BACX,YAAW,YAAY,CAAC,+BAA+B,CAAC;IAExD,QAAQ,CAAC,IAAI,kCAAkC;IAC/C,QAAQ,CAAC,QAAQ,EAAG,UAAU,CAAU;IAExC,GAAG,CAAC,GAAG,EAAE,WAAW,GAAG,+BAA+B;CA+FvD"}
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CliMainReflectionSuppressPass — cognium-dev #162 Option B
|
|
3
|
+
*
|
|
4
|
+
* Drops Java reflection `code_injection` sinks in files that look like
|
|
5
|
+
* a fat-jar CLI tool's own artifact — files that ship a `main(String[])`
|
|
6
|
+
* entry point AND carry no web-framework entry-point signal anywhere
|
|
7
|
+
* in the file. The `main(String[])` on the same compilation unit *is*
|
|
8
|
+
* the trust boundary; the caller is the OS shell that invoked the jar.
|
|
9
|
+
*
|
|
10
|
+
* Motivation (from the ticket):
|
|
11
|
+
*
|
|
12
|
+
* // antlr/tool/.../TestRig.java — 5 reflection sinks reported HIGH
|
|
13
|
+
* public static void main(String[] args) throws Exception {
|
|
14
|
+
* TestRig testRig = new TestRig(args);
|
|
15
|
+
* ...
|
|
16
|
+
* }
|
|
17
|
+
* public void process() throws Exception {
|
|
18
|
+
* String lexerName = grammarName + "Lexer";
|
|
19
|
+
* ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
|
20
|
+
* Class<? extends Lexer> lexerClass =
|
|
21
|
+
* cl.loadClass(lexerName).asSubclass(Lexer.class); // sink
|
|
22
|
+
* Constructor<? extends Lexer> lexerCtor =
|
|
23
|
+
* lexerClass.getConstructor(CharStream.class);
|
|
24
|
+
* Lexer lexer = lexerCtor.newInstance((CharStream)null); // sink
|
|
25
|
+
* ...
|
|
26
|
+
* }
|
|
27
|
+
*
|
|
28
|
+
* This is documented behaviour of ANTLR's `TestRig` developer CLI —
|
|
29
|
+
* same shape as `javac`, `java -jar`, `python -m`. The tool's whole
|
|
30
|
+
* purpose is "give me a grammar name from the command line and I'll
|
|
31
|
+
* run it." Blocked 5/49 HIGH FPs in the top-100 Java harness.
|
|
32
|
+
*
|
|
33
|
+
* ## Signal
|
|
34
|
+
*
|
|
35
|
+
* Language MUST be Java. Per-file signal (all must hold):
|
|
36
|
+
*
|
|
37
|
+
* 1. Some type in the file declares a `main(String[])` method
|
|
38
|
+
* (matches `looksLikeMainMethod` in `entry-point-detection.ts`).
|
|
39
|
+
* 2. NO type in the file carries a Tier-1 class-level web-framework
|
|
40
|
+
* annotation (`@RestController`, `@Controller`, `@Service`,
|
|
41
|
+
* `@Component`, `@Path`, `@WebServlet`, `@ServerEndpoint`,
|
|
42
|
+
* `@FeignClient`, `@Repository`).
|
|
43
|
+
* 3. NO method in the file carries a Tier-1 method-level
|
|
44
|
+
* web-framework annotation (Spring `@*Mapping`, `@KafkaListener`,
|
|
45
|
+
* `@JmsListener`, JAX-RS `@GET/@POST/…`, `@Scheduled`, `@Path`,
|
|
46
|
+
* `@DataBoundConstructor`/`@DataBoundSetter`).
|
|
47
|
+
* 4. NO type in the file extends a Tier-1 supertype (HttpServlet,
|
|
48
|
+
* GenericServlet, Filter, HandlerInterceptor, CommandLineRunner,
|
|
49
|
+
* SimpleChannelInboundHandler, etc.).
|
|
50
|
+
*
|
|
51
|
+
* ## Action
|
|
52
|
+
*
|
|
53
|
+
* When the signal fires, drop from the `SinkFilterResult.sinks` list
|
|
54
|
+
* (the authoritative sink array consumed by `TaintPropagationPass` and
|
|
55
|
+
* folded into `taint.sinks` by `analyzer.ts`) every sink whose
|
|
56
|
+
* `type === 'code_injection'` AND `method` is a Java reflection
|
|
57
|
+
* / ClassLoader surface method. The gate does NOT touch other
|
|
58
|
+
* `code_injection` shapes: ScriptEngine.eval / GroovyShell.evaluate /
|
|
59
|
+
* SpEL `parseExpression` remain flagged in CLI tools because they
|
|
60
|
+
* evaluate scripts (a genuinely dangerous CLI misuse), not just class
|
|
61
|
+
* names.
|
|
62
|
+
*
|
|
63
|
+
* ## Pipeline slot
|
|
64
|
+
*
|
|
65
|
+
* Runs after `SinkSemanticsPass` (so its curated-registry drops have
|
|
66
|
+
* already fired) and before `TaintPropagationPass` (so the flow
|
|
67
|
+
* generators never see the dropped sinks). Emits no findings.
|
|
68
|
+
*
|
|
69
|
+
* ## Pillar I / safety
|
|
70
|
+
*
|
|
71
|
+
* - Pure per-file heuristic; no LLM, no filesystem, no config knobs.
|
|
72
|
+
* - False-negative-safe: any web-framework signal in the file
|
|
73
|
+
* (annotation OR supertype OR Tier-1 method annotation) disables
|
|
74
|
+
* the gate. Recall preserved for `@RestController` classes,
|
|
75
|
+
* `HttpServlet` subclasses, Netty handlers, Jenkins plugins, and
|
|
76
|
+
* Kafka/JMS listeners that happen to also expose a `main`.
|
|
77
|
+
* - Reflection-only: `Runtime.exec`, `ProcessBuilder.start`,
|
|
78
|
+
* `Statement.execute`, `ObjectInputStream.readObject`, SpEL,
|
|
79
|
+
* Groovy, ScriptEngine — all unaffected.
|
|
80
|
+
* - Java-only: non-Java sources fall through untouched.
|
|
81
|
+
*/
|
|
82
|
+
/**
|
|
83
|
+
* Java reflection + ClassLoader methods that produce `code_injection`
|
|
84
|
+
* sinks via `configs/sinks/code_injection.yaml`. Simple-name match on
|
|
85
|
+
* `sink.method`. Kept intentionally narrow — script-engine /
|
|
86
|
+
* expression-language sinks (`eval`, `evaluate`, `parseExpression`,
|
|
87
|
+
* `getBeanInfo`, `getEngineByName`) are NOT in this set, so those
|
|
88
|
+
* still fire in CLI artifacts.
|
|
89
|
+
*/
|
|
90
|
+
const REFLECTION_SINK_METHODS = new Set([
|
|
91
|
+
'forName',
|
|
92
|
+
'newInstance',
|
|
93
|
+
'invoke',
|
|
94
|
+
'getMethod',
|
|
95
|
+
'getDeclaredMethod',
|
|
96
|
+
'getConstructor',
|
|
97
|
+
'getDeclaredConstructor',
|
|
98
|
+
'loadClass',
|
|
99
|
+
'defineClass',
|
|
100
|
+
]);
|
|
101
|
+
/**
|
|
102
|
+
* Tier-1 class-level web-framework annotations. Simple-name match
|
|
103
|
+
* (annotation strings in `TypeInfo.annotations` may include the `@`
|
|
104
|
+
* prefix and generic args — we strip both). Any single match kills
|
|
105
|
+
* the gate for this file.
|
|
106
|
+
*/
|
|
107
|
+
const TIER_1_CLASS_ANNOTATIONS = new Set([
|
|
108
|
+
// Spring MVC
|
|
109
|
+
'RestController',
|
|
110
|
+
'Controller',
|
|
111
|
+
// Spring stereotype beans
|
|
112
|
+
'Service',
|
|
113
|
+
'Repository',
|
|
114
|
+
'Component',
|
|
115
|
+
// JAX-RS resource class
|
|
116
|
+
'Path',
|
|
117
|
+
// Servlet 3.0 annotation-based servlet
|
|
118
|
+
'WebServlet',
|
|
119
|
+
// JSR-356 WebSocket endpoint
|
|
120
|
+
'ServerEndpoint',
|
|
121
|
+
// Declarative HTTP client
|
|
122
|
+
'FeignClient',
|
|
123
|
+
]);
|
|
124
|
+
/**
|
|
125
|
+
* Tier-1 method-level web-framework annotations. Any single match
|
|
126
|
+
* kills the gate.
|
|
127
|
+
*/
|
|
128
|
+
const TIER_1_METHOD_ANNOTATIONS = new Set([
|
|
129
|
+
// Spring MVC
|
|
130
|
+
'RequestMapping',
|
|
131
|
+
'GetMapping',
|
|
132
|
+
'PostMapping',
|
|
133
|
+
'PutMapping',
|
|
134
|
+
'DeleteMapping',
|
|
135
|
+
'PatchMapping',
|
|
136
|
+
// Spring messaging / WebSocket
|
|
137
|
+
'MessageMapping',
|
|
138
|
+
'SubscribeMapping',
|
|
139
|
+
// Spring messaging listeners
|
|
140
|
+
'KafkaListener',
|
|
141
|
+
'KafkaHandler',
|
|
142
|
+
'RabbitListener',
|
|
143
|
+
'RabbitHandler',
|
|
144
|
+
'JmsListener',
|
|
145
|
+
'StreamListener',
|
|
146
|
+
// Spring Cloud AWS
|
|
147
|
+
'SqsListener',
|
|
148
|
+
'SqsHandler',
|
|
149
|
+
// Spring application events
|
|
150
|
+
'EventListener',
|
|
151
|
+
// CRON / scheduled
|
|
152
|
+
'Scheduled',
|
|
153
|
+
// JAX-RS
|
|
154
|
+
'Path',
|
|
155
|
+
'GET',
|
|
156
|
+
'POST',
|
|
157
|
+
'PUT',
|
|
158
|
+
'DELETE',
|
|
159
|
+
'PATCH',
|
|
160
|
+
'HEAD',
|
|
161
|
+
'OPTIONS',
|
|
162
|
+
// Jenkins Stapler form-binding
|
|
163
|
+
'DataBoundConstructor',
|
|
164
|
+
'DataBoundSetter',
|
|
165
|
+
]);
|
|
166
|
+
/**
|
|
167
|
+
* Tier-1 supertypes whose subclasses declare framework entry points
|
|
168
|
+
* via lifecycle methods (HttpServlet.doGet, ChannelHandler.channelRead,
|
|
169
|
+
* CommandLineRunner.run, etc.). Simple-name match on
|
|
170
|
+
* `TypeInfo.extends` and each `TypeInfo.implements[]` entry (generics
|
|
171
|
+
* stripped).
|
|
172
|
+
*/
|
|
173
|
+
const TIER_1_SUPERTYPES = new Set([
|
|
174
|
+
'HttpServlet',
|
|
175
|
+
'GenericServlet',
|
|
176
|
+
'Filter',
|
|
177
|
+
'HandlerInterceptor',
|
|
178
|
+
'AsyncHandlerInterceptor',
|
|
179
|
+
'CommandLineRunner',
|
|
180
|
+
'ApplicationRunner',
|
|
181
|
+
'SimpleChannelInboundHandler',
|
|
182
|
+
'ChannelInboundHandler',
|
|
183
|
+
'ChannelInboundHandlerAdapter',
|
|
184
|
+
'ChannelDuplexHandler',
|
|
185
|
+
'NettyRequestProcessor',
|
|
186
|
+
'Converter',
|
|
187
|
+
'SingleValueConverter',
|
|
188
|
+
'ConverterMatcher',
|
|
189
|
+
'AbstractReflectionConverter',
|
|
190
|
+
'AbstractSingleValueConverter',
|
|
191
|
+
'AbstractCollectionConverter',
|
|
192
|
+
]);
|
|
193
|
+
/**
|
|
194
|
+
* Normalize an annotation string to its simple name. Handles `@Foo`,
|
|
195
|
+
* `Foo`, `@Foo(...)`, `pkg.Foo`, and `Foo<T>` shapes. Returns the
|
|
196
|
+
* bare identifier (`Foo`) for the lookup.
|
|
197
|
+
*/
|
|
198
|
+
function normalizeAnnotation(raw) {
|
|
199
|
+
let s = raw.trim();
|
|
200
|
+
if (s.startsWith('@'))
|
|
201
|
+
s = s.slice(1);
|
|
202
|
+
const parenIdx = s.indexOf('(');
|
|
203
|
+
if (parenIdx >= 0)
|
|
204
|
+
s = s.slice(0, parenIdx);
|
|
205
|
+
const genericIdx = s.indexOf('<');
|
|
206
|
+
if (genericIdx >= 0)
|
|
207
|
+
s = s.slice(0, genericIdx);
|
|
208
|
+
const dotIdx = s.lastIndexOf('.');
|
|
209
|
+
if (dotIdx >= 0)
|
|
210
|
+
s = s.slice(dotIdx + 1);
|
|
211
|
+
return s.trim();
|
|
212
|
+
}
|
|
213
|
+
/** Strip generics + package qualifier from a supertype reference. */
|
|
214
|
+
function normalizeSupertype(raw) {
|
|
215
|
+
let s = raw.trim();
|
|
216
|
+
const genericIdx = s.indexOf('<');
|
|
217
|
+
if (genericIdx >= 0)
|
|
218
|
+
s = s.slice(0, genericIdx);
|
|
219
|
+
const dotIdx = s.lastIndexOf('.');
|
|
220
|
+
if (dotIdx >= 0)
|
|
221
|
+
s = s.slice(dotIdx + 1);
|
|
222
|
+
return s.trim();
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Detect the `main(String[] args)` entry-point shape. Static isn't
|
|
226
|
+
* required by the JVM launcher spec strictly (some launchers accept
|
|
227
|
+
* instance mains), but every real Java CLI uses `public static void
|
|
228
|
+
* main(String[])`. We match on the parameter shape only — one string
|
|
229
|
+
* array — matching `looksLikeMainMethod` in
|
|
230
|
+
* `src/analysis/entry-point-detection.ts`.
|
|
231
|
+
*/
|
|
232
|
+
function isMainMethod(name, paramTypes) {
|
|
233
|
+
if (name !== 'main')
|
|
234
|
+
return false;
|
|
235
|
+
if (paramTypes.length !== 1)
|
|
236
|
+
return false;
|
|
237
|
+
const t = paramTypes[0];
|
|
238
|
+
if (!t)
|
|
239
|
+
return false;
|
|
240
|
+
const bare = t.replace(/\s+/g, '');
|
|
241
|
+
return bare === 'String[]' || bare === 'java.lang.String[]';
|
|
242
|
+
}
|
|
243
|
+
export class CliMainReflectionSuppressPass {
|
|
244
|
+
name = 'cli-main-reflection-suppress';
|
|
245
|
+
category = 'security';
|
|
246
|
+
run(ctx) {
|
|
247
|
+
const { graph, language } = ctx;
|
|
248
|
+
// Java-only gate. Non-Java IR falls through untouched.
|
|
249
|
+
if (language !== 'java') {
|
|
250
|
+
return { cliMainSignal: false, droppedCount: 0 };
|
|
251
|
+
}
|
|
252
|
+
const types = graph.ir.types;
|
|
253
|
+
if (!types || types.length === 0) {
|
|
254
|
+
return { cliMainSignal: false, droppedCount: 0 };
|
|
255
|
+
}
|
|
256
|
+
// Signal condition (1): main(String[]) present anywhere in file.
|
|
257
|
+
let hasMain = false;
|
|
258
|
+
// Disqualifiers (2), (3), (4): any Tier-1 web-framework signal.
|
|
259
|
+
let hasFrameworkSignal = false;
|
|
260
|
+
for (const type of types) {
|
|
261
|
+
// (2) class-level annotations
|
|
262
|
+
for (const ann of type.annotations) {
|
|
263
|
+
if (TIER_1_CLASS_ANNOTATIONS.has(normalizeAnnotation(ann))) {
|
|
264
|
+
hasFrameworkSignal = true;
|
|
265
|
+
break;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
if (hasFrameworkSignal)
|
|
269
|
+
break;
|
|
270
|
+
// (4) supertype match — `extends` slot + every `implements` slot.
|
|
271
|
+
if (type.extends && TIER_1_SUPERTYPES.has(normalizeSupertype(type.extends))) {
|
|
272
|
+
hasFrameworkSignal = true;
|
|
273
|
+
break;
|
|
274
|
+
}
|
|
275
|
+
for (const impl of type.implements) {
|
|
276
|
+
if (TIER_1_SUPERTYPES.has(normalizeSupertype(impl))) {
|
|
277
|
+
hasFrameworkSignal = true;
|
|
278
|
+
break;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
if (hasFrameworkSignal)
|
|
282
|
+
break;
|
|
283
|
+
for (const method of type.methods) {
|
|
284
|
+
// (3) method-level annotations
|
|
285
|
+
for (const ann of method.annotations) {
|
|
286
|
+
if (TIER_1_METHOD_ANNOTATIONS.has(normalizeAnnotation(ann))) {
|
|
287
|
+
hasFrameworkSignal = true;
|
|
288
|
+
break;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
if (hasFrameworkSignal)
|
|
292
|
+
break;
|
|
293
|
+
// (1) main(String[]) shape
|
|
294
|
+
if (!hasMain) {
|
|
295
|
+
const paramTypes = method.parameters.map((p) => p.type);
|
|
296
|
+
if (isMainMethod(method.name, paramTypes)) {
|
|
297
|
+
hasMain = true;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
if (hasFrameworkSignal)
|
|
302
|
+
break;
|
|
303
|
+
}
|
|
304
|
+
const cliMainSignal = hasMain && !hasFrameworkSignal;
|
|
305
|
+
if (!cliMainSignal) {
|
|
306
|
+
return { cliMainSignal: false, droppedCount: 0 };
|
|
307
|
+
}
|
|
308
|
+
// Drop reflection code_injection sinks in place. The authoritative
|
|
309
|
+
// sink list in the real pipeline is `SinkFilterResult.sinks` — that
|
|
310
|
+
// is what `analyzer.ts` assembles the final `taint.sinks` from and
|
|
311
|
+
// what `TaintPropagationPass` / `InterproceduralPass` consume.
|
|
312
|
+
// `graph.ir.taint.sinks` starts empty and is never populated by the
|
|
313
|
+
// pipeline, so mutating it alone would be a no-op. Prefer the
|
|
314
|
+
// sink-filter result; fall back to `graph.ir.taint.sinks` for
|
|
315
|
+
// stand-alone unit-test harnesses that don't run `SinkFilterPass`.
|
|
316
|
+
const sinks = ctx.hasResult('sink-filter')
|
|
317
|
+
? ctx.getResult('sink-filter').sinks
|
|
318
|
+
: graph.ir.taint.sinks;
|
|
319
|
+
let droppedCount = 0;
|
|
320
|
+
const kept = sinks.filter((sink) => {
|
|
321
|
+
if (sink.type !== 'code_injection')
|
|
322
|
+
return true;
|
|
323
|
+
if (!sink.method)
|
|
324
|
+
return true;
|
|
325
|
+
if (!REFLECTION_SINK_METHODS.has(sink.method))
|
|
326
|
+
return true;
|
|
327
|
+
droppedCount++;
|
|
328
|
+
return false;
|
|
329
|
+
});
|
|
330
|
+
if (droppedCount > 0) {
|
|
331
|
+
sinks.length = 0;
|
|
332
|
+
sinks.push(...kept);
|
|
333
|
+
}
|
|
334
|
+
return { cliMainSignal: true, droppedCount };
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
//# sourceMappingURL=cli-main-reflection-suppress-pass.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-main-reflection-suppress-pass.js","sourceRoot":"","sources":["../../../src/analysis/passes/cli-main-reflection-suppress-pass.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"language-sources-pass.d.ts","sourceRoot":"","sources":["../../../src/analysis/passes/language-sources-pass.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"language-sources-pass.d.ts","sourceRoot":"","sources":["../../../src/analysis/passes/language-sources-pass.ts"],"names":[],"mappings":"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"}
|
|
@@ -4741,6 +4741,22 @@ export function findJavaResponseWriterXssFindings(code, file) {
|
|
|
4741
4741
|
if (respNames.size === 0)
|
|
4742
4742
|
return out;
|
|
4743
4743
|
const safeWrapRe = /\b(?:Encode\.(?:forHtml|forHtmlAttribute|forHtmlContent|forJavaScript)|StringEscapeUtils\.escape(?:Html3|Html4|EcmaScript|Xml)|HtmlUtils\.htmlEscape(?:Decimal|Hex)?|Escaper\.escapeHtml|HtmlEscapers\.(?:escapeHtml|htmlEscaper)|Encoder\.encodeForHTML(?:Attribute)?|Jsoup\.clean)\s*\(/;
|
|
4744
|
+
// cognium-dev#153 — same-file sanitized-variable tracking.
|
|
4745
|
+
// Collect names of local variables that were assigned from a recognized
|
|
4746
|
+
// HTML/attribute encoder in this file. When ALL non-literal identifiers
|
|
4747
|
+
// in the sink args are in this set, the write is treated as sanitized.
|
|
4748
|
+
const sanitizedVars = new Set();
|
|
4749
|
+
const sanAssignRe = /(?:^|[\s;{},(])(?:final\s+)?(?:[A-Za-z_][\w.<>\[\]]*\s+)?([A-Za-z_]\w*)\s*=\s*[^=]/;
|
|
4750
|
+
for (const line of lines) {
|
|
4751
|
+
const t = line.trim();
|
|
4752
|
+
if (!t || t.startsWith('//') || t.startsWith('*'))
|
|
4753
|
+
continue;
|
|
4754
|
+
if (!safeWrapRe.test(t))
|
|
4755
|
+
continue;
|
|
4756
|
+
const am = t.match(sanAssignRe);
|
|
4757
|
+
if (am)
|
|
4758
|
+
sanitizedVars.add(am[1]);
|
|
4759
|
+
}
|
|
4744
4760
|
for (let i = 0; i < lines.length; i++) {
|
|
4745
4761
|
const raw = lines[i];
|
|
4746
4762
|
const trimmed = raw.trim();
|
|
@@ -4764,6 +4780,17 @@ export function findJavaResponseWriterXssFindings(code, file) {
|
|
|
4764
4780
|
continue;
|
|
4765
4781
|
if (!/[A-Za-z_]\w*/.test(argsTrim))
|
|
4766
4782
|
continue;
|
|
4783
|
+
// cognium-dev#153 — if every non-literal identifier in the args is a
|
|
4784
|
+
// locally-sanitized var, the concatenation was pre-encoded. Skip.
|
|
4785
|
+
if (sanitizedVars.size > 0) {
|
|
4786
|
+
const stripped = argsTrim.replace(/"(?:\\.|[^"\\])*"/g, '');
|
|
4787
|
+
const idents = stripped.match(/\b[A-Za-z_]\w*\b/g) ?? [];
|
|
4788
|
+
const nonKeyword = idents.filter((x) => x !== 'null' && x !== 'true' && x !== 'false');
|
|
4789
|
+
if (nonKeyword.length > 0 &&
|
|
4790
|
+
nonKeyword.every((x) => sanitizedVars.has(x))) {
|
|
4791
|
+
continue;
|
|
4792
|
+
}
|
|
4793
|
+
}
|
|
4767
4794
|
out.push({
|
|
4768
4795
|
id: `xss-${file}-${i + 1}`,
|
|
4769
4796
|
pass: 'language-sources',
|