Commit Graph
19 Commits
Author SHA1 Message Date
Isaac ConnorandClaude Opus 4.8 5f702842a5 fix: stop the Config API leaking secret values refs GHSA-8g63-hqg8-82cv
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>
2026-10-28 19:20:54 -04:00
Isaac Connor 713d565776 fix: require System permission to read the Config API and withhold secrets
Any enabled, API-enabled account could read the effective configuration,
including secrets, whatever its permissions. Confirmed on a live instance: a
user with every area set to None retrieved ZM_DB_PASS from
/api/configs/viewByName/ZM_DB_PASS.json.

The controller already required System Edit to change a config but checked
nothing at all to read one, so index, view, viewByName and categories were open
to anyone the API let in. They now require the same System permission the web
ui's Options page requires.

Permission alone is not enough, because nothing outside the server has any use
for these values. Two kinds are now withheld from every caller, administrators
included:

  - Rows flagged Private in the Config table. That flag already existed and was
    loaded into $zm_config, but nothing ever acted on it. It covers
    ZM_AUTH_HASH_SECRET, which is enough to forge an authentication hash for any
    user, and the reCaptcha secret.

  - The database credentials. These are read from zm.conf and conf.d rather than
    the table, so they have no row to flag and are listed by name. This is also
    why filtering the table alone would not have been enough: index appends the
    file-backed values to its response.

Requesting an unknown name logged print_r($zm_config, true), copying the whole
effective configuration into the log and anything collecting it. It now logs the
name at Debug.

Verified against a live instance, before and after, with a temporary System=None
API user: reading ZM_DB_PASS returned the password and now returns 401; an
administrator gets an empty Value for ZM_DB_PASS and ZM_AUTH_HASH_SECRET, the
293-entry index carries no secret values, and ordinary settings such as
ZM_WEB_TITLE still read normally.
2026-08-15 22:18:47 -04:00
Isaac ConnorandClaude Opus 4.8 2f57a4f606 fix: use method call for System permission check in ConfigsController
The config-api RCE fix (b036408a5) guards edit() and delete() with
($user['System'] == 'Edit'), but $user is a ZM\User object that does
not implement ArrayAccess and whose System property is protected. Array
access on it raises "Error: Cannot use object of type ZM\User as array",
so the endpoint fatals with HTTP 500 for every authenticated user. This
blocks the RCE only by accident and also breaks config editing for
legitimate System=Edit admins.

Use $user->System(), matching the idiom in every other API controller
(States, Servers, Monitors, Users, etc.).

Refs GHSA-mvj8-mqqq-2w5f.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 16:17:51 -04:00
Isaac ConnorandClaude Opus 4.6 b036408a5b Fix RCE vulnerability via API config edit privilege escalation
Add RBAC checks to ConfigsController edit() and delete() requiring
System=Edit permission, matching the pattern used by other controllers.
Harden System/Readonly column checks with !empty() to handle missing
columns gracefully. Fix command injection in Event.php by using
ZM_PATH_FFMPEG constant with escapeshellarg() instead of hardcoded
unsanitized ffmpeg call. Add is_executable() validation at all exec()
sites using ZM_PATH_FFMPEG as defense-in-depth against poisoned config
values.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 13:51:30 -05:00
Isaac Connor 68f91acf10 Remove zm_configvals. Just use zm_config. Move code into loadConfig. 2025-12-22 13:17:01 -05:00
Isaac Connor cdbeea439b Add named paramter filtering to Configs api index. Add updating returned config entry with values from zm_config which may have been overridden in /etc/zm/conf.d 2025-12-19 16:48:25 -05:00
Isaac Connor 74aab0a76e Prevent editing of system config entries through the api 2022-05-30 10:02:49 -04:00
Isaac Connor e04eac57ae Include values in /etc/zm files in viewByName 2018-06-25 15:43:01 -04:00
Isaac Connor 2a5f05499e Munge the config in the global configvals into the configs array before returning it. 2018-05-10 13:44:46 -04:00
arjunrc 38b4785557 PP - Gone,flitted away, Taken the starts from the night and sun, From the day! Gone, and a cloud in my heart. - Tennyson 2015-12-19 18:36:38 -05:00
Pliable Pixels e332fc36a9 Fixed Configs API to return all values 2015-07-21 13:28:37 -04:00
Ubuntu dd9603f70f Merged Angular UI branch API to master 2015-06-11 02:58:58 +00:00
Kyle Johnson 9f80a7d5f5 Show a list of Config Key:Value pairs 2014-11-15 19:01:32 +00:00
Kyle Johnson 9268c503af Do not display the "hidden" config category 2014-11-15 19:01:19 +00:00
Kyle Johnson 0d57306790 Find category configs only when $category is not null. API 2014-11-15 18:58:58 +00:00
Kyle Johnson 9f150c4e46 Revert "Find category configs only when $category is not null. API"
This reverts commit efbbcadc7d.
2014-11-15 18:58:51 +00:00
Kyle Johnson b88febeaee Find category configs only when $category is not null. API 2014-11-15 18:58:43 +00:00
Kyle Johnson 0a7ba112ab API support for querying config categories.
Either return a list of distinct categories, or all configs under a
certain category
2014-11-15 18:55:20 +00:00
Kyle Johnson f1f3de6d7d Moved the api to underneath the web directory 2014-04-29 20:41:04 +00:00