IDOR in Report Test — Low-Privilege User Can Access Any User's Dashboard Reports
The report.test trapper endpoint allows an authenticated low-privilege user to supply an arbitrary userid in the request body. The server creates a real session for that user, renders their dashboard as a PDF, and emails it to the attacker — with no check that the requested viewer identity matches the authenticated caller.
- Vendor
- Zabbix
- Product
- Zabbix Server
- Affected
- 8.0.0beta2 (commit 31eccf9)
Summary
The report.test trapper endpoint accepts a data.userid field that controls which user's dashboard is rendered. An authenticated User-role account can set this to any other user's ID, including the Super Admin. The report manager creates a live database session for the victim, renders their dashboard using the victim's cookie, and emails the resulting PDF to an attacker-controlled address. No authorization check is performed.
Affected Versions
- Zabbix Server
8.0.0beta2(commit31eccf9ddaf7adf129f9cd611c85b7451b188eb9)
Details
The call chain is:
trapper_server.c:68authenticates the caller via session ID and obtains the authenticateduser.userid.- It calls
zbx_report_test(&jp_data, user.userid, &j), passing the authenticated userid. report_protocol.c:370–394deserializesdata.useridfrom the attacker-controlled JSON intoviewer_userid(internallyaccess_userid). The authenticated userid is passed along but never compared toaccess_userid.report_manager.c:654callsrm_session_start(manager, access_userid), inserting a real row into thesessionstable for the victim user.- The web service receives a rendering request with the victim's session cookie and fetches their dashboard.
The fix is a single equality check — access_userid == authenticated_userid — that is absent from the entire call chain.
Impact
Any authenticated user can receive a PDF rendering of any other user's dashboards, including those of the Super Admin. Dashboards may display sensitive monitoring data, credentials stored as macros, or infrastructure topology. The attack is also a session-creation primitive: a live sessions row is inserted for the victim user as a side effect.
Remediation
Enforce access_userid == authenticated_userid before calling rm_session_start in report_manager.c. The authenticated userid is already present at the call site; the check is a single conditional.