Loading
Phoenix
This merge is called Phoenix because Shinobi is being reborn with this massive number of fixes.
Security
- #560 (reported by Sadık Ertürk, sadik.erturk): Child node connectivity vulnerability fix, plus follow-ups —
childNodes.keynow also accepts a single string (not just an array), and the security notice for a missing/default key only shows when child nodes are actually enabled. - #561 (reported by Matteo Panzeri, matte1782): OS command injection via monitor
detector_command, plus a feature flag to fully disable the on-detect command. - #562 (reported by Youngjin Kong, 0jinkong): OS command injection via
detector_commandplaceholders, and path traversal on the videos file route. - #563 (closed) (reported by Klaus Stock, ks17041968): RTSPS support / URL mangling fix.
- #564 (reported by Abdullah Kareem, cyberkareemx): Cross-group bypass, missing PTZ permission check, and command injection on probe; also disallow editing privileged fields on the Users row.
- #565 (reported by Sajjad Haqi, lri5r1js4h2k9nl): 10-vulnerability coordinated disclosure, fixed and re-tested across three rounds:
- Round 1: unauthenticated DB write via socket
ocv, detector-filtereval()RCE, Mount Manager command injection, ffprobe/ONVIF SSRF,isInternallocalhost auth bypass, cross-tenant IDOR, account takeover viasettings/edit, reflected XSS in embedhost. - Round 2: stored XSS via matrix drawing on the UI (
escapeHtmlon all event fields). - Round 3: unauthenticated cross-tenant write via the
r(recorder) socket handler, cross-tenant group join via thea(admin) socket handler, SSRF on monitor save/connect (new self/metadata-target filter, configurable viadisableSSRFSelfTargetFilter), remainingsettings/editHTTP path and timelapse-buildkebinding, and closing the remote-origin gap left in the embed page'shostparameter fix. - Follow-up: the embed
hostorigin check missed the server's own non-standard port (any deployment not on 80/443 would have its own assets rejected and silently downgraded to port 80); and a template comment containing a literal<%- %>broke EJS parsing on render. Both fixed.
- Round 1: unauthenticated DB write via socket
- #566 (reported by Abdullah Kareem, cyberkareemx): Default super-admin credential could be chained through module install to RCE; follow-up hardening on cyberkareemx's own re-test findings.
- #559 (closed) (reported by Peter Srinivasan, petersrinivasan): Multiple allowed IPs not working as expected (was also a latent auth-check bug, not just a usability issue).
users_onlineinfo disclosure: The socketinithandler broadcast the full server-side session cache to every client in a group — including each user's raw session auth token (as the object key) and their entire accountdetailsblob (which can hold cloud/notification credentials). Now sends a minimal, sanitized{uid, mail, sub}list instead.- ONVIF scanner SSRF guard: Reject internal/loopback/metadata targets and require an authenticated socket before initiating scans.
Bug fixes
"Dead until restart" class of bugs
- !552 (merged) (Andrew Linkoln, elador13): Global webhook stopped sending after every process restart, only working again after re-saving Account Settings. Root cause:
loadGroupApps()ran the load extensions before populatings.group[ke].init, so the webhook'sallowedSendgate was evaluated against an empty config on every cold start. - cd68f22b (Andrew Linkoln, elador13): Motion events stopped firing after a monitor restart.
motion_lockwas cleared viaclearTimeouton stop but the property itself was never deleted, so a stale truthy value permanently blocked new motion detections until the whole process restarted.
Media / recording
- #492 (closed) (reported by v, spamosmail): Timelapse frame writer file-descriptor leak. The per-frame writer created a new
WriteStreamfor every chunk of a frame due to anawaitbetween the null-check and assignment. Made stream creation synchronous so exactly one writer is created per frame. - #433 (closed) (reported by laviddichterman):
stream_channels.forEach is not a function. HardenedbuildMainStreamandcreatePipeArrayto work off a parsed array so a string value can't crash the build or mis-count stdio pipes. - #547 (closed) (reported by Dmitry Lunev, khyonox): Video merge issues; a separate follow-up fixed the copy codec used during video merge.
- #563 (closed) (reported by Klaus Stock, ks17041968): RTSPS support / URL mangling fix.
- #529 (closed) (reported by Matthew M. Dean, fireculex): Add RW timeout option.
- #436 (reported by Meow, GrumpyMeow): Region points outside of canvas — Region Editor update.
- #400 (closed) (reported by Caennanu, caennanu): Feed freeze on dashboard using substreams.
- #484 (closed) (reported by It's a me, madri2): Events with null confidence — added percent/type checks in the motion detector path.
- Fixed toggling substream on/off.
pipe4BufferPiecesreset on data stream frame checks (buffer state could persist stale data across reconnects).- Monitor Stream Window cleanup pass.
- Removed the unused "eventListWithPics" tab entirely (dead code, was never actually wired up).
Storage / disk accounting
- #446 (closed) (reported by v, spamosmail): Over-limit purge could permanently wedge. The purge
async.queueworker didn't always resolve its callback (e.g. group unloaded mid-purge), stalling all future purges until restart. Worker now always resolves, with a backstop timeout. - Cloud storage in-memory math: The "mount" uploader (and other cloud uploaders) could poison used-space counters with
NaN/string values, disabling purge and showingNaNuntil restart. Centralized sanitization of deltas and counters;kilobyteToMegabytenow returns a Number. Rechecked and fixed again for uploader types not covered by the first pass. - Additional memory management for the B2, mount, and WebDAV uploaders.
- Safeguards added to the
mount.jsorphan scanner. - Fixed the target type used for cloud deletion.
- Google Drive uploader updated; the "moving things" tracker updated alongside it.
Cameras / nodes / PTZ
- #485 (closed) (reported by imtiaz-nafiz): Child node monitor process not starting. The child read the command mode from the config object instead of the master's command (
d.d.modechanged tod.mode). - #495 (closed) (reported by LeBizz333): Broader ONVIF event parsing. Handle numeric
State(AxisVideoSource/MotionAlarm) alongside boolean styles, and guard against array/missing SimpleItems. Event handling later switched onto theshinobi-onvifmodule; ONVIF error codes normalized andmoveResponse"ok" handling fixed. - #477 (closed) (reported by SirLouen, SirLouen): API for Activate Monitor States presets not working — updated
s.activateMonitorStates. - #450 (closed) (reported by Alex Gilko, alex.gilko): Missing Jetson NVDEC hwaccel; added Jetson hwaccels and cleaned up
base.js. - #515 (closed) (reported by Hesam Monfared, monfared.hesam): Disconnected monitors — updated Live Grid
scrolledIntoViewhandling. - #559 (closed) (reported by Peter Srinivasan, petersrinivasan): Multiple allowed IPs not working as expected.
- PTZ control now handles the "not configured or not available" case instead of erroring.
- ONVIF scanner: surface
502/reset/timeout/unexpected responses as visible rows instead of silently dropping them; suppress only true dead-port noise. Tapo's ONVIF port added to the scanner. Additional QoL pass on top.
Notifications
- #423 (closed) (reported by Dedy Martadinata Supriyadi, dedyms): Notification errors — added a safeguard on Telegram photo sends. Telegram bot module updated to a stable package and pinned in
package.json; error notice improved. - Firebase Cloud Messaging (FCM) notifications added, later updated to route through
push.shinobi.cloud; push tokens now save to their own table instead of being bolted onto an existing one. - Matrix notifications no longer depend on
matrix-js-sdk. - Discord bot can now send to a specific User ID instead of only a channel.
- Notification messages can include an app link; added the app-link-opener endpoint and auto-detection of the notification base URL when not explicitly configured.
- Detector notify moved onto
runExtensionsForArrayAwaitedforonEventTrigger, with a try/catch error handler added around that extension runner so one bad extension can't take down the rest.
Container / platform
- #461 (closed) (reported by Jack Pan, panxiaoqi): Zombie processes on podman/Docker. Run under
tinias PID 1 so reparented ffmpeg orphans are reaped instead of accumulating. - #482 (closed) (reported by Florian Asche, florian-asche): Missing
procpspackage in the Docker image — wrappedtree-killso a missingpsbinary doesn't break process management. - CPU/RAM health checks: Fixed for FreeBSD, OpenBSD, openSUSE, FreeNAS, and macOS (corrected inverted/misparsed values and broken vmstat flags).
UI / misc
- Fixed capitalization on "Ignore Server Certificate".
- Fixed a
language.jsbug. - Separated the Account Settings page layout out of
base.js. - Removed a stray generated
index.mdfile that had been committed by mistake.
Other issue fixes
- #270 (closed) (Felipe Morato, famor), #274 (closed) (Justin Lavan, justin.lavan3), #483 (closed) (edrikk), #524 (closed) (bchhabra), #525 (closed) (MasterPrenium, masterprenium), #526 (closed) (Aleksandr "kidi" Saponchik, alumnikidink), #531 (closed) (Fengikjing), #533 (closed) (David Masshardt, TheNetStriker), #534 (closed) (Matthew M. Dean, fireculex), #536 (closed) (FedericoHeichou), #538 (closed) (Robert Davis, robert-e-davis), #539 (closed) (Atticus Maximus, amaximus), #545 (closed) (hamgooof), #554 (closed) (sono, keisukesonoda).
- Cleanup for #527 (closed) / !502 (merged) (Rene Hollan, rhollan).
Features & options
- #564 (reported by Abdullah Kareem, cyberkareemx): Separate PTZ ("Can Control Monitor") permission.
- #561 (reported by Matteo Panzeri, matte1782): Allow completely disabling the on-detect command.
- #528 (closed) (reported by Pete Rawlings, pjr21121957): Discord notification module update.
- Unicode support: Regex now matches Unicode letters/digits (incl. Cyrillic) via
\p{L}\p{N}plus theuflag; completed Russian (ru.json) translation. - Icelandic translation (Sveinn í Felli, sveinki): initial translation, plus a
!549follow-up patch. - New config option:
disableSSRFSelfTargetFilter(defaultfalse) — opt-out for the SSRF self/metadata-target filter on monitor save/connect and the probe endpoint, exposed in the Super Admin Config Editor. - Firebase Cloud Messaging (FCM) push notifications.
- Detector event subscription over socket.io.
- App-link support in notification messages.
Installers
- macOS: Reworked to a touchless Docker-based install with Apple Silicon vs Intel image selection; clones into
/Applications/Shinobi. - FreeBSD, OpenBSD, openSUSE, FreeNAS: Modernized to touchless installs (current package names, MariaDB setup, boot persistence); FreeNAS script further updated.
- Arch Linux: New installer added.
Dependencies
- #542 (closed) (reported by wangcw, redgreat): Default database driver to
mysql2. - #497 (closed) (reported by Elad Bar, elad.bar): npm deprecation warnings — updated MQTT and LDAP modules to current packages.
npm audit fix;package.json/package-lock.jsonupdates.