Long story short: SID should not be available in URL.
Consider the following attack vector:
Environment contains Zabbix with guest account enabled. The following actions are performed from guest account (this can be any other least-privilege account):
- Create a screen with URL element. URL elements are rendered as iframe and parent window cannot be accessed from the frame, but attacker can get some metadata from frame (like referrer). Referrer will always contain URL of the parent window. And thats where SID in URL becomes a problem.
- Script gets referrer and checks it for SID parameter and uses that to bypass CSRF check in session surfing attack. If SID is set, then script creates an image with src attribute set to user creation page (as an example). After that, request is sent to Zabbix API to ensure that user was created. If SID is not set, script shows some error message in order to make user to perform some action.
After that attacker just waits until script is executed.
As a PoC I created this kind of script (~45 lines of JS code). When script is executed without SID, the following error (part of social engineering attack) is shown:
When user clicks on "Edit screen", there are two options:
- User is created (if permissions are not limited), then the following message is shown (the goal of PoC):
- User was not created (no permissions), then the following message is shown (still a part of social engineering attack):
Additional problems with CSRF check:
- SID is always the same, so stealing one SID will result broken CSRF solution.
- SID is not a surrogate key
- SID exposes part of sessionId
- SID is not bound to action (form)
Additional problems with URL elements:
- URL elements are a great platform for social engineering attacks
- If attacker can host a script on a same domain as Zabbix frontend is running at, then scripts can be executed in a parent window context (same origin policy).