Repository navigation
v1.37.3 - security release
Security release. One authorization bug in OAuth, reported privately through SECURITY.md, plus a related gap in the MCP resources. Please upgrade if you have [oauth] enabled = true.
Thank you, kta1kri. The report arrived the way SECURITY.md asks for and better than we had any right to expect: exact file and line references, a reproduction against the real authorization check, a CVSS vector we agree with, and the related resources gap found in the same pass. Every point was correct. Reports like this are why the policy exists, and we are grateful for the time it took.
Security
- OAuth tokens were never read-only, so a
viewergot write tools (reported privately on 2026-10-07 by kta1kri, followingSECURITY.md; affects v1.28 - v1.37.2). Every OAuth access token was published to the authorization layer withread_only=False, whatever the portal role of the user who consented. The consent screen caps aviewerto themonitoringandextensionsscopes - butmonitoringcontains host, item, trigger, discovery rule and web scenario create / update / delete, so a user documented as read-only could create, change and delete those on every configured server not setread_only = true. Needs OAuth enabled, a portal account with theviewerrole, and a writable server; CVSS 4.0 6.0 (medium) as scored by the reporter, which we agree with. Now the role rides on the authorization code, the access token and the refresh token;load_access_tokenderivesread_onlyfrom it (viewerand anything unknown or missing are read-only,operatorandadminmay write), a refresh after the access token expired keeps it, anddocs/OAUTH.md, README andSECURITY.mdsay what "read-only" means. Demoting a user does not shrink tokens already issued; revoke the client from the portal. - MCP resources bypassed the token authorization check (same report).
zabbix://<server>/hosts,/problems,/hostgroupsand/templatescalled the Zabbix API directly, so a token bound to another server, or without the scope that covers the data, could read them. Each resource now runs the samecheck_token_authorizationas the tools. Registration moved out ofrun_serverinto_register_resourcesso this is testable.
Verified
- 511 unit + e2e tests, all passing. 14 new: the role-to-read-only rule (viewer, operator, admin, unknown, missing, case), the reporter's reproduction against the real
check_token_authorizationwith the token the provider now builds, the role surviving a refresh after the access token is gone (in both directions - an operator must not become read-only either), the role riding from consent through the authorization code to the token, and the four resources refusing a token bound to another server or lacking the scope while a wildcard token and the no-token (stdio) path still read. Four of them boot the real server and run the real authorization code flow (register, authorize, login, consent, token) for aviewerand anoperatoraccount against a writable placeholder Zabbix: the viewer'shost_createis refused as read-only while itshost_getreaches Zabbix, the operator'shost_createreaches Zabbix, the viewer stays read-only after a refresh, the scope cap still refuses a viewerusers, andresources/readrefuses analerts-only token while amonitoringtoken gets through (on MCP SDK 2.2+ the refusal carries the reason; SDK 2.0 masks it as a generic "Error reading resource" and logs the reason server-side - the refusal itself is the same). The reporter's reproduction was re-run against the pre-fix provider as a proof: a viewer token came backread_only=Falseandhostwrite allowed; on the fixed code the same token is read-only and the write is refused. - Live on a public HTTPS deployment (student-postgresql-01, behind Apache, MCP SDK 2.0.0, writable Zabbix 7.4): the real authorization code flow for a
viewerand anoperatoraccount; the viewer'shost_create,item_deleteandaction_preparerefused as read-only, itshost_getandzabbix://main/hostsreturning real data, still read-only after a refresh, still unable to grantusers; the operator'shost_createcreated a host in Zabbix andhost_deleteremoved it,user_getrefused by scope, and analerts-only token refused the hosts resource. - CRUD smoke against live Zabbix 7.4; installer matrix 18/18.