CVE case study
CVE-2026-78871: Missing Authorization on the Shinobi PTZ Camera-Control Route
Shinobi 2.0.0 and earlier is missing an authorization check on its PTZ camera-control route, so any authenticated user, including a restricted sub-account or an API key marked control_monitors_disallowed, can pan, tilt, or zoom any camera in their group. No fixed version was available at disclosure.
- Weakness
- CWE-862
- Affected
- Shinobi 2.0.0 and earlier (commit 9ddc2c3c71203a22f89fc72580270217a47c1347); no fixed version released
- Remediation state
- No fixed version at disclosure; reported through a confidential GitLab issue
- Advisory published
- 4 Sep 2026
Official vectorCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:L
Why it matters
Shinobi is a self-hosted video management system for network cameras. Its PTZ feature drives the physical pan, tilt, and zoom motors of a camera through the route GET /:auth/control/:ke/:id/:direction in libs/webServerPaths.js. The root cause is that this route is the only monitor route with no permission check, and the underlying ptzControl function in libs/control/ptz.js takes no user or permission parameter. It gates only on whether the target monitor exists and has control enabled, never on whether the caller is allowed to move it.
Because the check is absent, any authenticated caller can issue the request, including a restricted sub-account or an API key explicitly marked control_monitors_disallowed. Such a caller can pan, tilt, or zoom any camera in their group, aiming a camera away from what it is meant to watch or otherwise disrupting surveillance across a trust boundary that was supposed to keep low-privilege accounts from touching camera hardware. The submitted vector scores it 5.4 (Medium); when combined with the separate group-key authorization bypass filed in the same batch, the reach extends to cameras in other groups.
The issue was reported through the confidential GitLab issue Shinobi-Systems/Shinobi #564. Because no CNA covers the project, it was submitted to MITRE (CNA-LR), and no fixed version was available at disclosure. The engineering lesson is that a permission check belongs in the function that performs a privileged action, not only in the routes around it, so a single unguarded handler cannot silently bypass every account restriction.