apache / apache/rocketmq-dashboard

[Studio][Bug] Stored message query results can be read by any authenticated user without an ownership check

Open
#4,007 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
1.4k
Forks
683
Avg merge
2d 14h
Merged PRs (30d)
58

Description

## Problem

`GET /api/query-history/messages/{id}/results` returns the stored message-query snapshot for any record id without verifying that the requesting user owns the record. Record ids are sequential, so any authenticated user can enumerate ids and replay another user's stored snapshots.

## Evidence

`QueryHistoryService.getMessageQueryResults` (`server/src/main/java/org/apache/rocketmq/studio/instance/message/QueryHistoryService.java:134-150`) reads the row with `messageQueryMapper.selectById(id)` and no owner predicate, while every other read in the same service filters by the authenticated user: `listMessageQueries` (`:184`), `listTraceQueries` (`:204`), `summarize` (`:221-234`), and the owner is stamped at insert (`:93`). The stored snapshot contains msgIds, topics, tags, message keys, broker names, queue offsets and `bornHost`/`storeHost` addresses (`buildResultSnapshot`, `:109-124`).

The per-user boundary was established by the merged fix for #2265 ("Query-history reads and summaries are scoped to the current authenticated user by default"); the results endpoint was introduced later (by #2839) and never picked the boundary up.

## Impact

In multi-user deployments (login required by default), one authenticated user can enumerate other operators' query history snapshots, including which topics/keys/msgIds they searched and internal broker/producer host addresses. The response for a foreign id also differs from a missing id, leaking record existence.

## Expected behavior

The by-id results read applies the same owner scope as the list/summary reads (`queried_by = currentUsernameOrSystem()`); foreign and missing ids return the same 404. No admin bypass, matching the list paths.

## Related work

#2265 (closed, merged via the queried_by scoping), #3295 (delete own history — per-user ownership is the model), #3388 (open test-only coverage of the endpoint's happy path).

## PR

#4003

Contributor guide

No contributing guide indexed for this repository

Research direction

Start in server/src/main/java/org/apache/rocketmq/studio/instance/message/QueryHistoryService.java at getMessageQueryResults and compare it with listMessageQueries, listTraceQueries, and summarize. Review the endpoint coverage referenced by #3388 and verify that foreign and missing record IDs have the same 404 behavior while owned results remain available.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
api, authorization, backend, security
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.