mirror of
https://github.com/ZoneMinder/zoneminder.git
synced 2026-10-03 16:05:24 -04:00
/api/host/login took the token's subject from the `user` request parameter and
authenticated the request from a different one. beforeFilter() validates
user=/pass=, and zm_authenticate_request() logs in from username=/password=,
but nothing ever checked that the two named the same account. A caller could
authenticate with their own credentials and ask for a token issued to someone
else.
Reproduced end to end against a live instance. A System=None, Events=View
account posting
username=lowpriv&password=testpass123&user=admin
received an access and a refresh token whose claims read {"user":"admin"}, and
that token was accepted by a System-gated endpoint. Any enabled API account
escalated to administrator without knowing the administrator's password or
ZM_AUTH_HASH_SECRET.
The subject now comes from the authenticated user rather than from the request,
and a request that reached this point without authenticating is refused instead
of being handed a token for whoever it named.
Verified after the change on the same instance: the request above mints a token
for lowpriv, an ordinary user=/pass= login still returns tokens for the caller,
and the refresh-token path still issues a new access token.
See GHSA-m77q-66v7-j3fq.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WBHBB95RBX7D9p8ge2WDZb
(cherry picked from commit 72cb485655c53babfcfecaed572e0ef24e96db06)