FilterTerm.php:
- Use intval() on AlarmedZoneId value in SQL subquery to prevent
injection via crafted filter val
report_event_audit.php, montagereview.php:
- Cast $selected_monitor_ids through array_map('intval') before
interpolating into SQL IN clause (values come from $_REQUEST)
download_functions.php:
- Replace manual single-quoting with escapeshellarg() for merged
file name in ffmpeg, tar, and zip commands (monitor names can
contain shell metacharacters including single quotes)
- Same fix for export list file path
export_functions.php:
- Use escapeshellarg() on source and destination paths in cp -as
commands during event export
functions.php:
- Validate column keys in getFormChanges() against /^[a-zA-Z0-9_]+$/
to prevent SQL injection via crafted array keys from $_REQUEST
- Use dbEscape() and intval() for image/document MIME type and size
fields instead of raw string interpolation
- Replace escapeshellcmd() with escapeshellarg() in deletePath()
rm -rf command
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>
- Add IS NOT operator check alongside != in PHP FilterTerm.php
(was already handled in Perl but missing from PHP)
- Add defined() guard on $term->{val} in Perl Filter.pm to avoid
uninitialized value warnings with malformed/legacy saved filters
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The filter system ignored the operator (= vs !=) when generating SQL
for the special tag values "No Tag" (0) and "Any Tag" (-1).
In PHP (FilterTerm.php), "Tag != Any Tag" produced EXISTS instead of
NOT EXISTS, returning events WITH tags instead of events WITHOUT tags.
In Perl (Filter.pm), != was not handled as a special case and fell
through to generic SQL (T.Id != -1), which excluded events with no
tags because LEFT JOIN produces NULL and NULL != -1 evaluates to
UNKNOWN in SQL. Additionally, T.Id was unconditionally prepended for
all tag values, producing invalid SQL (T.IdEXISTS) for the special
cases that use EXISTS/NOT EXISTS subqueries.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Added "Any Tag" entry with value -1 to availableTags in Filter.php (widget and simple_widget methods)
- Added "Any Tag" entry to filter.php view
- Added translation for "Any Tag" in en_gb.php language file
- Implemented SQL logic in FilterTerm.php to handle "Any Tag" (value -1) using EXISTS query
- Implemented SQL logic in Filter.pm (Perl) to handle "Any Tag" (value -1) using EXISTS query
Co-authored-by: connortechnology <925519+connortechnology@users.noreply.github.com>
fix(tag): Create tags on mobile
chore(tags): Change TagName to Name
chore(tags): eslint
chore(tags): dbFetchAll to dbQuery for removetag
chore(events): eslint (attempt 2)
feat(tags): Better handling of keyboard
fix(tags): Enter key for creating new tag
fix(tags): Don't allow space as a tag name
feat(tags): Delete tag if last assignment removed
fix(tags): Increase height of dropdown
in progress
fix(Tags): Use T.Id on the events page dropdown
fix(Tags): Remove $availableTags from events.php
chore(sql): Formatting sql statements
feat(Tags): Working OR on filters and events pages
fix(filter): Populate availableTags
chore(Tags): code formatting
fix(tag): Add tag on create tag
Fix(tags): Remove tag from available if last
feat(tags): Add zm_update.sql
fix(chosen): Undo css width
fix(chosen): tags dropdown width
fix(tags): dropdown over timeline
fix(tags): Full width input
fix(events): Refresh table on page show
chore(filter): Clean up availableTags
chore(event): Clean up available & selected Tags
fix(event): Update available tags on remove
fix(event): Remove hack for selected tags
feat(tags): Blur input after adding tag
doc(tags): Initial tags documentation
fix(tags): Dark theme dropdown
fix(tags): Dark theme for tags on input
fix(tags): Dark theme for highlight in dropdown
fix(tags): Populate filter tags droplist
chore(): Bump zm_update to 1.37.42
chore(tags): Move mobile check to skin.js
chore(tags): Comment debug statements
fix(tags): Enter key to create tag on mobile Chome
chore(tags): Space in 'All Tags' for translation
Temporary commit to handle cookie expiration times
chore(tags): Remove unnecessary Tag(s) from en_gb
chore(): Cleanup unnecessary Error and Debug
chore(): Resolve merge conflicts
chore(): Address merge conflicts with master