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&timestamp=1791023309332&sign=JVqsMk%2FICWYHzRweTF%2F5nIWBzvFzTTGCUnOWMDyh8%2FY%3D
   
   Transmitted raw query:
   
access_token=synthetic&timestamp=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]

Reply via email to