66 Commits
Author SHA1 Message Date
Isaac Connor 4582091e5e fix: require permission on the monitor daemon API actions
daemonStatus() and daemonControl() checked nothing at all. Any enabled,
API-enabled account could read the state of, and start or stop, the capture and
analysis daemons of any monitor, including monitors it was not permitted to see.
index() and view() have always filtered on ZM\Monitor::canView(), so these two
were the odd ones out.

Confirmed on a live instance with a user whose every permission was None:
monitors.json returned an empty list, while
monitors/daemonControl/1/status.json ran zmdc against that same monitor. On a
running system the equivalent stop call would have halted recording.

Reporting state now needs view on the monitor, and starting or stopping it needs
edit, matching the rest of the controller.

zmdc.pl takes the daemon and the command as separate arguments and they were
interpolated into the command line, escaped only by escapeshellcmd() over the
whole string. That stops metacharacters but not extra arguments, so both are now
checked against the set of names zmdc accepts.

add() and delete() call this internally, having already made their own
permission decision, and a System Edit account need not hold Monitors Edit. They
call an ungated private runner so that re-checking here cannot stop them.
2026-08-15 22:18:47 -04:00
SteveGilvarry 18011e3e62 fix: make monitors API index portable under ONLY_FULL_GROUP_BY
The monitors index unconditionally LEFT JOINed Groups_Monitors and collapsed
the duplicate rows (monitors in multiple groups) with GROUP BY `Monitor`.`Id`.
That GROUP BY fails under ONLY_FULL_GROUP_BY on engines without functional
dependency detection (MariaDB), raising 1055 'Monitor.Name isn't in GROUP BY',
so /api/monitors.json returned a 500 while /api/monitors/<id>.json worked.

Only join Groups_Monitors when the request filters by group (matching the
existing EventsController pattern and the original commented-out intent), drop
the GROUP BY, and dedupe by monitor Id in the existing result loop to cover
multi-value GroupId filters. Portable across MySQL and MariaDB.

refs #3633
2026-06-14 00:18:26 +10:00
Isaac ConnorandClaude Opus 4.6 ffe6362dc3 fix: harden web interface against injection and SSRF vulnerabilities
FilterTerm.php:
- Replace eval() with safe compare() method for SystemLoad, DiskPercent,
  and DiskBlocks filter conditions (RCE via crafted op/val)
- Validate operator against allowlist in constructor
- Sanitize collate field to alphanumeric/underscore only (SQLi)

onvifprobe.php:
- Use escapeshellarg() on interface, device_ep, soapversion, username,
  and password arguments passed to execONVIF() (command injection)

Event.php:
- Use escapeshellarg() on all arguments to zmvideo.pl instead of
  escapeshellcmd() on the whole command (command injection via format)
- Anchor scale regex with ^ and $ to prevent partial matches

image.php:
- Restrict proxy URL scheme to http/https only (SSRF via file:// etc)

filterdebug.php:
- Use already-sanitized $fid instead of raw $_REQUEST['fid'] (XSS)

MonitorsController.php:
- Use escapeshellarg() on token, username, password, and monitor id
  in zmu shell command instead of escapeshellcmd() on whole command

HostController.php:
- Use escapeshellarg() on path in du command (command injection via mid)
- Remove space from daemon name allowlist (argument injection)

EventsController.php:
- Remove single quotes from interval expression regex (SQLi)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 23:30:49 -04:00
Isaac ConnorandClaude Opus 4.6 419846c875 fix: sanitize monitor Device path to prevent command injection (GHSA-g66m-77fq-79v9)
The Device field from the Monitors table was interpolated directly into
shell commands (qx(), backticks, exec()) without sanitization, allowing
authenticated users with monitor-edit permissions to execute arbitrary
commands as www-data via the Device Path field.

Defense in depth:
- Input validation: reject Device values not matching /^\/dev\/[\w\/.\-]+$/
  at save time in both web UI and REST API
- Output sanitization: use escapeshellarg() in PHP and quote validated
  values in Perl at every shell execution point

Affected locations:
- scripts/ZoneMinder/lib/ZoneMinder/Monitor.pm (control, zmcControl)
- scripts/zmpkg.pl.in (system startup)
- web/includes/Monitor.php (zmcControl)
- web/includes/functions.php (zmcStatus, zmcCheck, validDevicePath)
- web/includes/actions/monitor.php (save action)
- web/api/app/Model/Monitor.php (daemonControl, validation rules)
- web/api/app/Controller/MonitorsController.php (daemonStatus)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 13:19:03 -04:00
Isaac Connor 28e4fa4d7f Replace Function=>Capturing 2025-11-17 11:55:58 -05:00
Isaac Connor 974e9fd0f2 When editing a monitor via api, if Capturing=None don't start zmc. Fixes #4348 2025-07-04 16:28:39 -04:00
Isaac Connor ad168ca23a Allow monitor creation if Monitors()==Create 2024-01-22 14:25:57 -05:00
stefan 1bd9def63e [API] Fix User variable from array to object
Fix $user variable from array to object to make API work again.
2023-04-23 22:07:24 +02:00
Isaac Connor 79d19c21d1 Update validating access to Monitors, using canView due to Monitor and Groups permissions 2023-02-25 16:13:39 -05:00
Isaac Connor e949a5554f Must convert strings into integers before doing math as of php 8.2 Fixes Unsupported operand types: string - int 2022-11-17 14:54:05 -05:00
Isaac Connor 0515a1ba74 implode the output from zmu to fix php complaint abou array to string conversion 2022-11-17 14:53:56 -05:00
Isaac Connor 460695202f Add Janus_Pin to monitor API 2022-09-28 18:35:30 -04:00
Isaac Connor 363c589975 More properly fix the alarm status api changing. The previous hack broken doing alarm on/off. 2022-09-21 14:35:27 -04:00
Isaac Connor 834dc3c986 Restore status value to pre 1.36.16 value by substracting 1. So Unknown == -1, 0 = IDLE etc. Fixes #3584 2022-09-08 13:01:45 -04:00
Isaac Connor 5312d11e78 Don't both running zmu if monitor Function is set to None 2021-12-10 16:08:43 -05:00
Isaac Connor dbe16a9cb4 Don't use AUTH_HASH_IPS when talking to zmu as it doesn't support that at this time. 2021-08-26 10:45:36 -04:00
Isaac Connor 8511d814df Restore api behaviour. Add zmu output to response 2021-05-28 12:28:35 -04:00
Isaac Connor 0b4c35c58e Merge pull request #3241 from connortechnology/fix_3239
Fix 3239
2021-05-19 20:39:42 -04:00
Isaac Connor 007dce45fb Add disable alarms as an alarm command 2021-04-12 15:59:31 -04:00
Isaac Connor 1b876f24f9 Must have Id as well in order to know which monitor to control 2021-03-17 17:15:04 -04:00
Isaac Connor 28a004c324 Must load ServerId so that we can tell if it is local or remote 2021-01-27 11:48:32 -05:00
Isaac Connor 3132820a71 Move daemonControl logic into the model. daemonControl needs to be called on the previous monitor data so that it knows which daemons to stop. 2020-12-23 13:48:12 -05:00
Isaac Connor 10c0a6617c Return Debug to a regular function to match other logging functions. Since we switched to using namespaces we no longer clash with cake_php. 2020-10-14 10:39:25 -04:00
Isaac Connor 3e55795cad Handle different command line syntax for zmcontrol.pl 2020-03-26 13:57:43 -04:00
Javier Gonzalez 8b375de455 Avoid duplicate Monitors in API 2020-01-15 20:31:05 +01:00
Isaac Connor 76b54a468f use left join instead of inner join when listing monitors 2019-12-22 18:43:53 -05:00
Isaac Connor bcda92058e proper way to make cakephp filter by group. Make Group containable, always add the join 2019-12-20 14:56:01 -05:00
Isaac Connor eee3729b85 dirty fix filtering Monitors by GroupId. Change occurrences of GroupId to ' ' as that is what the key is in conditions. Please note that other operators like != won't work. 2019-12-04 22:23:55 -05:00
Isaac Connor 0b2853095e cleanup auth in monitors alarm method 2019-12-01 12:30:27 -05:00
Pliable Pixels 16a6938710 add model validation so that we don't create empty monitors 2019-11-02 08:30:25 -04:00
Pliable Pixels a9d01ba3d2 Alarm api (#2665)
* fixed alarm api to use tokens if present

* clearer debug logs for tokens

* space
2019-07-17 20:38:58 -04:00
Isaac Connor 110e5075f4 fix namespace fixes #3566 2019-04-01 17:21:01 -04:00
Isaac Connor 520c41da23 Merge ../ZoneMinder.connortechnology.bad into storageareas 2019-03-18 14:40:03 -04:00
Matthew Noorenberghe 056b96f7fc API: Monitor and Event 'index' SQLi. Fixes #2099 2019-03-11 00:21:51 -07:00
Isaac Connor f5328265ef fix missing daemons definition 2018-11-28 09:12:22 -05:00
Isaac Connor 51d8c0ea73 add back daemon parameter, but make it actually work 2018-11-14 12:59:44 -05:00
Isaac Connor d671761a35 simplify params to daemonControl since they really aren't being used anyways. Return the status text 2018-11-14 12:54:10 -05:00
Isaac Connor 9a2d58adce We don't store all the permissions in the session anymore. We just use the global user object 2018-10-29 11:03:03 -04:00
Isaac Connor 23ddc83ad4 fix_2167 (#2168)
* Populate a global  from the session on every request. Use the  object instead of using allowedMonitors in session.

* fix when  gets loaded.

* use  for auth, and add Monitor Edit checks to Zone add/delete/edit

* add back the ZM_OPT_USE_AUTH test for being logged in in AppController

* Update permissions code to use

* change quotes

* Update permission code to use

* Use  instal of session for systemPermission

* deprecate montiorPermision in session

* use  instead of session streamPermission

* move login code back into AppController. Has to be done for every request

* deprecate eventPermission, controlPermission and systemPermission in session.

* handle auth params in query string as well as post

* exit on HUP to free up memory.

* add missing global user

* system should be System
2018-08-08 09:59:46 -04:00
Isaac Connor dc57a3c91c fix spacing/quotes/google code style 2018-07-24 16:41:09 -04:00
Isaac Connor cd64619743 Fix controlling daemon when the monitor is Local 2018-06-06 12:56:33 -04:00
Isaac Connor 475c465b0d define 2018-01-26 10:39:12 -05:00
Isaac Connor 1503c586d2 When there is an error saving, add the invalidFields() info to the error message. Only restart the daemon on success. 2018-01-26 10:30:29 -05:00
Isaac Connor 933259f9a5 fix bracket 2018-01-23 13:16:21 -08:00
Isaac Connor bd2da456f4 handle non-multi-server case when restarting monitors via API 2018-01-19 21:09:33 -05:00
Isaac Connor d586faf7fb Fix restarting Monitor 2018-01-19 08:16:28 -08:00
Isaac Connor 1b1b93f811 use CakePHP-Enum-Behavior to add support for ENUMs to the Monitor model. This should fix #48 2018-01-01 14:43:02 -05:00
Isaac Connor bb8e326392 Fix not restarting a monitor if it has moved to a different server 2017-12-22 09:16:56 -08:00
Isaac Connor ef1af9cc15 disable FilterComponent as it doesn't actually do anything. Add Groups join when needed 2017-12-09 14:03:42 -05:00
Isaac Connor 6270408c8f rework group MonitorIds and add GroupId filters to api 2017-12-04 15:52:16 -05:00