Description
Both generators hold a private static final EvaluationContext CONTEXT (a single shared instance across all requests). doGenerate calls CONTEXT.setVariable("req", mockRequest) then PARSER.parseExpression(expression).getValue(CONTEXT). Under concurrent load (multiple Netty event-loop threads), thread A's setVariable("req", reqA) can be overwritten by thread B's setVariable("req", reqB) before thread A's getValue(CONTEXT) executes. The SpEL expression then evaluates against the wrong request's MockRequest (body, headers, query params, URI).
Location
shenyu-plugin/shenyu-plugin-mock/src/main/java/org/apache/shenyu/plugin/mock/generator/ExpressionGenerator.java:44,56-58
shenyu-plugin/shenyu-plugin-mock/src/main/java/org/apache/shenyu/plugin/mock/generator/StandardExpressionGenerator.java:43,55-57
Impact
Cross-request data leak: a mock response for request A may contain request B's body/headers/query parameters. Non-deterministic, intermittent wrong mock responses under concurrency.
Suggested fix
Create a new EvaluationContext per request (or per doGenerate call) instead of sharing a static one.
Related existing
None — distinct from #6544 (DividePlugin beginTime shared mutable) which is a different shared-state race in a different plugin.
Description
Both generators hold a
private static final EvaluationContext CONTEXT(a single shared instance across all requests).doGeneratecallsCONTEXT.setVariable("req", mockRequest)thenPARSER.parseExpression(expression).getValue(CONTEXT). Under concurrent load (multiple Netty event-loop threads), thread A'ssetVariable("req", reqA)can be overwritten by thread B'ssetVariable("req", reqB)before thread A'sgetValue(CONTEXT)executes. The SpEL expression then evaluates against the wrong request'sMockRequest(body, headers, query params, URI).Location
shenyu-plugin/shenyu-plugin-mock/src/main/java/org/apache/shenyu/plugin/mock/generator/ExpressionGenerator.java:44,56-58shenyu-plugin/shenyu-plugin-mock/src/main/java/org/apache/shenyu/plugin/mock/generator/StandardExpressionGenerator.java:43,55-57Impact
Cross-request data leak: a mock response for request A may contain request B's body/headers/query parameters. Non-deterministic, intermittent wrong mock responses under concurrency.
Suggested fix
Create a new
EvaluationContextper request (or perdoGeneratecall) instead of sharing a static one.Related existing
None — distinct from #6544 (DividePlugin
beginTimeshared mutable) which is a different shared-state race in a different plugin.