Improper authorization control for web services In motioneye
Description
motionEye's missing authentication on ActionHandler allows unauthenticated camera action execution
Summary
The ActionHandler.post() method in motionEye has no authentication decorator, allowing any unauthenticated attacker to trigger camera actions including snapshots, recording start/stop, and configured action scripts (PTZ controls, alarm triggers, etc.).
Vulnerability Details
File: motioneye/handlers/action.py — ActionHandler.post() line 36
CWE: CWE-862 — Missing Authorization
CVSS: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N = 5.3 Medium
Vulnerable Code
class ActionHandler(BaseHandler): async def post(self, camera_id, action): # ← NO @BaseHandler.auth() decorator camera_id = int(camera_id) if camera_id not in config.get_camera_ids(): raise HTTPError(404, 'no such camera') ... if action == 'snapshot': await self.snapshot(camera_id) # executed without auth...
Compare with other handlers that correctly require authentication:
@BaseHandler.auth(admin=True) # ← properly protected async def delete(self, camera_id, filename): ...
Steps to Reproduce
Deploy motionEye with at least one camera configured
Send unauthenticated POST:
POST /action/1/snapshot HTTP/1.1 Host: motioneye-host:8765 Content-Length: 0
Observe {} (HTTP 200) response — snapshot triggered without any credentials
For action scripts (lock, unlock, alarm_on, alarm_off, light_on, etc.):
POST /action/1/alarm_on HTTP/1.1 Host: motioneye-host:8765
Impact
Unauthenticated attacker can trigger camera snapshots on demand
Unauthenticated attacker can start/stop video recording
If action scripts are configured by admin: attacker can trigger PTZ movement, alarm control, lighting changes — physical security bypass
Via remote cameras: SSRF by triggering action on a remote motionEye server
Verification
Dynamically confirmed on v0.43.1 in Docker lab — POST /action/2/snapshot with no credentials returns HTTP 200 {}. Server log shows the action was processed (failed only because motion daemon was not running for the test camera, not due to an auth rejection).
Recommended Fix
class ActionHandler(BaseHandler): @BaseHandler.auth() # add authentication requirement async def post(self, camera_id, action): ...
Mitigation
Update Impact
Minimal update. May introduce new vulnerabilities or breaking changes.
Ecosystem | Package | Affected version | Patched versions |
|---|---|---|---|
pypi | 0.44.0 |
Aliases
References