[BUG] Logging console desensitization algorithm leaks across concurrent requests
- Dominant language
- Java
- Stars
- 8.8k
- Forks
- 3.1k
- Avg merge
- 7d 1h
- Merged PRs (30d)
- 85
Description
### Search before asking
- [x] I had searched in the [issues](https://github.com/apache/shenyu/issues) and found no similar issues.
### Apache ShenYu Component
shenyu-plugin
### What happened
`LoggingConsolePlugin` stores the desensitization algorithm in a static mutable field:
```java
private static String dataDesensitizeAlg = DataDesensitizeEnum.CHARACTER_REPLACE.getDataDesensitizeAlg();
```
For every request whose logging rule enables masking, the plugin overwrites that static field from the current rule:
```java
if (desensitized) {
Collections.addAll(keywordSets, keywords.split(";"));
dataDesensitizeAlg = Optional.ofNullable(commonLoggingRuleHandle.getMaskType())
.orElse(DataDesensitizeEnum.MD5_ENCRYPT.getDataDesensitizeAlg());
keyWordMatch = new KeyWordMatch(keywordSets);
}
```
Later, when the response body is logged, the response decorator reads the same static field:
```java
String responseBody = DataDesensitizeUtils.desensitizeBody(desensitized, writer.output(), keyWordMatch, dataDesensitizeAlg);
```
Because response logging happens asynchronously and after the plugin has already returned control to the chain, another concurrent request matching a different logging rule can overwrite `dataDesensitizeAlg` before the first response reaches `doFinally(...)`. The first request then logs with the second rule's masking algorithm.
This makes console logs nondeterministic when different logging rules use different `maskType` values.
### Expected behavior
The desensitization algorithm should be request-scoped, like `desensitized` and `keyWordMatch`. It should be captured in a local final variable and passed into `LoggingServerHttpRequest`/`LoggingServerHttpResponse` instead of being stored in a static mutable field.
### How to reproduce
1. Configure two logging-console rules with different `maskType` values.
2. Send concurrent requests matching both rules.
3. Let one response complete after the other request has entered `LoggingConsolePlugin.doExecute(...)` and overwritten `dataDesensitizeAlg`.
4. The first request's response log can be masked using the second rule's algorithm.
### Debug logs
_No response_
### Environment
Current `master` branch.
### Are you willing to submit a PR?
- [ ] Yes I am willing to submit a PR!
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by reading LoggingConsolePlugin.doExecute(...) and tracing how desensitized, keyWordMatch, and dataDesensitizeAlg reach LoggingServerHttpRequest, LoggingServerHttpResponse, and doFinally(...). Verify the behavior with concurrent requests using different maskType values; done means each response log consistently uses the algorithm selected for its own request without shared mutable state.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- backend, observability
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100