VAITP Dataset

← Back to the dataset

CVE-2026-55488

motionEye < 0.44.0 absolute path traversal allows arbitrary file read.

  • CVSS 7.7
  • CWE-22
  • Input Validation and Sanitization
  • Remote

motionEye (mEye) is an online interface for a piece of software called "motion," which is a video surveillance program with motion detection. Versions prior to 0.44.0 contain an absolute path traversal vulnerability in multiple media file handlers that allows an attacker to read arbitrary files from the filesystem. The affected handlers accept a user-controlled filename parameter and construct filesystem paths using `os.path.join()`. When an absolute path is supplied, Python discards the configured media directory and returns the attacker-supplied path directly. The application then bypasses Tornado's built-in path validation by overriding the relevant safety checks. As a result, an attacker can access files outside of the configured camera media directory, subject to the permissions of the motionEye process. Version 0.44.0 fixes the issue.

CVSS base score
7.7
Published
2026-06-24
OWASP
A01 Broken Access Control
Orthogonal defect classification
Checking
Code defect classification
Missing Check
Category
Input Validation and Sanitization
Subcategory
Path Traversal
Accessibility scope
Remote
Impact
Information Disclosure
Affected component
motionEye
Fixed by upgrading
Yes

Solution

Upgrade to motionEye version 0.44.0 or later.

Vulnerable code sample

import os
import tornado.ioloop
import tornado.web

# In a real application, this would be a configurable path.
# For this example, we assume it's a fixed directory.
MEDIA_ROOT = "/var/lib/motioneye/Camera1"

# This custom handler is created to serve media files.
# It inherits from Tornado's StaticFileHandler but overrides a key security method.
class UnsafeMediaFileHandler(tornado.web.StaticFileHandler):
    def validate_absolute_path(self, root, absolute_path):
        # This override is the core of the vulnerability.
        # Tornado's default implementation checks if `absolute_path` is within `root`
        # and raises an HTTP 403 error if it's not, preventing path traversal.
        # By simply returning the path without validation, this security check is bypassed.
        #
        # When a user provides an absolute path like '/etc/passwd', os.path.join(root, absolute_path)
        # results in '/etc/passwd', which is then returned here and served.
        return absolute_path

def make_app():
    return tornado.web.Application([
        # The handler is configured to serve files from the MEDIA_ROOT directory.
        # Any path matching /media/(.*) will be handled.
        # e.g., /media/2023-10-27/video.mp4 -> /var/lib/motioneye/Camera1/2023-10-27/video.mp4
        # e.g., /media//etc/passwd -> /etc/passwd (due to the vulnerability)
        (r"/media/(.*)", UnsafeMediaFileHandler, {"path": MEDIA_ROOT}),
    ])

if __name__ == "__main__":
    print("Starting vulnerable web server on http://localhost:8888")
    print(f"MEDIA_ROOT is '{MEDIA_ROOT}'")
    print("Try accessing http://localhost:8888/media/some_file.txt")
    print("Then try the exploit: http://localhost:8888/media//etc/passwd")
    app = make_app()
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()

Patched code sample

import os

# The base directory where media files are stored.
# In a real application, this would be read from a configuration file.
MEDIA_DIRECTORY = '/var/lib/motioneye/media'

def get_safe_media_path(user_supplied_filename):
    """
    Safely constructs a path to a media file, preventing path traversal.

    This function represents the fix for the vulnerability. The vulnerable
    version would pass user_supplied_filename directly to os.path.join().
    """
    # By using os.path.basename(), we strip any directory information from the
    # user input. This includes leading slashes ('/') which would make the
    # path absolute, and parent directory traversals ('../').
    # For example:
    #   '/etc/passwd' becomes 'passwd'
    #   '../../boot.ini' becomes 'boot.ini'
    #   'camera-1/video.mp4' becomes 'video.mp4'
    safe_filename = os.path.basename(user_supplied_filename)

    # Now, joining the trusted base directory with the sanitized filename is
    # safe. os.path.join() will no longer discard the base directory because
    # safe_filename is guaranteed not to be an absolute path.
    full_path = os.path.join(MEDIA_DIRECTORY, safe_filename)

    # For an even more robust solution, we can resolve the real path and
    # verify it is inside the allowed media directory.
    real_base_path = os.path.realpath(MEDIA_DIRECTORY)
    real_full_path = os.path.realpath(full_path)

    if os.path.commonprefix([real_base_path, real_full_path]) != real_base_path:
        # This check prevents sophisticated attacks (e.g., via symlinks)
        # where the path might appear safe but resolves to a location
        # outside the intended directory.
        raise ValueError("Path traversal attempt detected.")

    return real_full_path

Payload

/media/download?filename=/etc/passwd

Cite this entry

@misc{vaitp:cve202655488,
  title        = {{motionEye < 0.44.0 absolute path traversal allows arbitrary file read.}},
  author       = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
  year         = {2026},
  note         = {VAITP Python Vulnerability Dataset, entry CVE-2026-55488},
  howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2026-55488/}}
}
Introducing the "VAITP dataset": a specialized repository of Python vulnerabilities and patches, meticulously compiled for the use of the security research community. As Python's prominence grows, understanding and addressing potential security vulnerabilities become crucial. Crafted by and for the cybersecurity community, this dataset offers a valuable resource for researchers, analysts, and developers to analyze and mitigate the security risks associated with Python. Through the comprehensive exploration of vulnerabilities and corresponding patches, the VAITP dataset fosters a safer and more resilient Python ecosystem, encouraging collaborative advancements in programming security.

The supreme art of war is to subdue the enemy without fighting.

Sun Tzu – “The Art of War”

:: Shaping the future through research and ingenuity ::