zmuxuny opened a new issue, #5492: URL: https://github.com/apache/rocketmq-dashboard/issues/5492
### Before Creating the Bug Report - [x] I have searched the [open issues](https://github.com/apache/rocketmq-dashboard/issues) of this repository and believe that this is not a duplicate. - [x] This is a defect in RocketMQ Studio, not a usage question and not a defect in another Apache RocketMQ repository. - [x] I can reproduce this on the current `master` branch, or I have stated the exact version I am running below. ### Studio Version Branch: rocketmq-studio Commit: 6a68042fa73a513f40436ca721944b4de48181ec Tested from source. ### Runtime Environment Linux; JDK 21; resolved Spring Web 7.0.8. Reproduced with MockRestServiceServer attached to a real RestTemplate. No DingTalk account, credentials, database, or external request is needed. ### Connected RocketMQ Cluster Not required. The defect is in notification delivery after an alert is generated, and also affects the settings test-notification action. ### Build Toolchain _No response_ ### Describe the Bug NotificationOutboxService.dingTalkWebhook URL-encodes the Base64 HMAC before adding it to the webhook query. sendWebhook then passes this already-encoded URL to RestTemplate.postForEntity(String, ...), which treats the string as a URI template and encodes it again. For example, Base64 padding = becomes %3D, then %253D in the outgoing request. After normal query decoding, the signature ends in literal %3D rather than =. Encoded + and / characters are similarly affected. A correctly configured signing secret therefore produces a signature that cannot verify. Both sendTestMessage("dingtalk") and queued DingTalk deliveries use this path; retries regenerate the signature but repeat the encoding error. ### Steps to Reproduce 1. Use a synthetic signing secret, such as synthetic-test-secret, and webhook https://example.com/robot/send?access_token=synthetic. 2. Obtain the URL produced by dingTalkWebhook, or invoke the service test-notification path. 3. Attach MockRestServiceServer to a real RestTemplate; call the same postForEntity(String, ...) overload used by sendWebhook and capture request.getURI().getRawQuery(). 4. Decode sign once using URLDecoder. 5. Compare with the Base64 HMAC-SHA256 of timestamp + "\n" + secret, keyed by the same synthetic secret. This captures the actual URI produced by Spring request construction, not only the pre-request URL string. ### What Did You Expect to See? The query-decoded sign equals the expected Base64 HMAC, with exactly one layer of URL encoding on the wire. ### What Did You See Instead? A baseline run using only synthetic values produced: Before request construction: access_token=synthetic×tamp=1791023309332&sign=JVqsMk%2FICWYHzRweTF%2F5nIWBzvFzTTGCUnOWMDyh8%2FY%3D Transmitted raw query: access_token=synthetic×tamp=1791023309332&sign=JVqsMk%252FICWYHzRweTF%252F5nIWBzvFzTTGCUnOWMDyh8%252FY%253D Expected decoded signature: JVqsMk/ICWYHzRweTF/5nIWBzvFzTTGCUnOWMDyh8/Y= Actual decoded signature: JVqsMk%2FICWYHzRweTF%2F5nIWBzvFzTTGCUnOWMDyh8%2FY%3D Signature matches after one URL decode: false This reproduces the malformed request locally. No live DingTalk rejection was needed or claimed. ### Additional Context The narrow fix is to pass the fully constructed, already-encoded webhook URI to the RestTemplate URI overload. Existing URL-host validation, signing, response validation, and retry policy can stay unchanged. Regression coverage should inspect the final request URI, compare the decoded signature with the HMAC, cover signed webhooks with and without existing queries, and cover queued delivery and test notifications. Existing percent escapes in unsigned DingTalk/SMS URLs should remain intact. Spring URI encoding documentation: https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-uri-building.html Issue and PR searches for DingTalk, signing and double encoding found no duplicate. AI assistance was used for investigation. ### Are You Willing to Submit a Pull Request? - [ ] Yes, I am willing to submit a pull request. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
