mirror of
https://github.com/ZoneMinder/zoneminder.git
synced 2026-11-05 12:12:58 -05:00
Two ways a System=View account could read secrets through the Config API. The oracle: ConfigsController::index() passed the caller's named filter to buildFilter() and returned the matched rows. redactSecret() blanked a secret Value in the response but not in the WHERE clause, so a filter such as Name:ZM_AUTH_HASH_SECRET/Value LIKE:a% returned the row for a correct prefix and nothing otherwise - the row count leaked the secret a character at a time, and that secret signs auth tokens. index() now detects a filter on the Value column and drops the secret rows from the result, so their presence reveals nothing; a filter on any other column is unaffected. The flags: ZM_JANUS_SECRET, ZM_UPLOAD_PASS and ZM_MQTT_PASSWORD held secrets but were not marked Private, so the API returned them to System=View and skin.js.php wrote them into every page as JavaScript constants. Mark them private in ConfigData.pm.in (fresh installs) and add a Config UPDATE to the untagged 1.39.41 migration (existing installs). No web page reads the three; zmfilter, zmc and the Janus integration read them server side. Tested: tests/php/test_config_value_filter.php (11 cases) covers the Value detection, including Model.Value, case, and the DefaultValue non-match. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>