unbridled-41 opened a new issue, #5477:
URL: https://github.com/apache/rocketmq-dashboard/issues/5477

   ### Studio Version
   branch: `rocketmq-studio` @ `6a68042f` (the revision verified; the branch is 
based on it)
   deployed as: built from source (unit test)
   
   ### Runtime Environment
   
   Not environment-specific: the service layer, verified with unit tests.
   
   ### Connected RocketMQ Cluster
   
   Two Apache instances registered against the same cluster (only the names 
must be unique).
   
   ### Describe the Bug
   
   `DLQService.resendMessages` / `resendSelectedMessages` only check the 
instance's vendor before delegating, so any Apache instance pointing at the 
same cluster can read and replay another instance's dead letters and publish 
them into a topic it does not own. The DLQ topic `%DLQ%<group>` belongs to the 
group's owner, and an explicit `targetTopic` is a topic write of its own; every 
sibling write path (`sendMessage`, `redeliverMessage`, `resetOffset`, 
`consumeMessageDirectly`) goes through `ResourceOwnershipGuard` for exactly 
these resources.
   
   ### Steps to Reproduce
   
   1. Register instances A and B as `APACHE` against one cluster; let A own 
group `G` and topic `T`.
   2. `POST /api/dlq/resend 
{"instanceId":"B","groupName":"G","targetTopic":"T"}`.
   3. Observe B reads A's `%DLQ%G` and publishes into A's `T` (also reachable 
through the AI `redelivery_dlq` tool).
   
   ### What Did You Expect to See?
   
   A foreign group or topic answers 409/404 from the ownership guard, as it 
does on every other write path.
   
   ### What Did You See Instead?
   
   The resend succeeds and is audited as such.
   
   ### Evidence
   
   - `instance/dlq/DLQService.java` (both resend entry points), 
`provider/apache/RocketMQDLQProvider.java` (no guard reference), 
`instance/ResourceOwnershipGuard.java` (the resource model, which maps 
`%DLQ%<group>` onto the group's ownership), 
`instance/topic/MetadataService.java` (the sibling pattern).
   - `cd server && mvn -o test 
-Dtest='DLQServiceTest,DLQControllerTest,RocketMQDLQProviderTest'` — the added 
cases fail before the change (the guard is never consulted; a refusal does not 
stop the provider) and pass after (`Tests run: 91`).
   
   ### Impact
   
   A cross-instance authorization bypass: another instance's dead letters are 
read and republished, and the audit log reports success.
   
   ### Acceptance Criteria
   
   - Both resend entry points check the GROUP resource, plus the TOPIC resource 
when a target is named, before anything is read or published.
   - Regression tests pin the check and the refusal.
   
   Related: #5010 (the same class of bypass on another path).
   
   **Corresponding PR:** #5448
   


-- 
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