Skip to content

Unauthenticated code execution, SSRF, and path traversal in the video rendering API

Critical
marcelo-earth published GHSA-gv87-qv6x-q8wc Jul 12, 2026

Software

generative-manim

Affected versions

<= 314ef64

Patched versions

211600e

Description

Summary

The Flask API under api/ had no authentication on any route, including
/v1/video/rendering, which writes user-submitted code verbatim to a
.py file and executes it via the manim CLI. Combined with a Dockerfile
that ran the container as root, this allowed any unauthenticated network
caller to execute arbitrary code as root inside the container. Two related
issues were found alongside it: an SSRF in the video-export endpoint and a
path-traversal issue via an unsanitized file_class field.

Details

1. Unauthenticated remote code execution (Critical, CWE-94)

POST /v1/video/rendering wrote the code field from the request body
directly into a .py file and ran it via manim, which imports the file
as a module, meaning module-level statements execute immediately without
needing a valid Scene class. No authentication, sandboxing, or isolation
gated this route. The shipped Dockerfile had no USER directive, so the
process ran as root, confirmed via a proof-of-concept that wrote
uid=0(root) gid=0(root) to a file inside the container.

2. Server-side request forgery (High, CWE-918)

POST /v1/video/exporting called requests.get(video_url) on a fully
user-controlled URL (scenes[].videoUrl) with no validation, allowing the
server to be made to issue requests to internal services or cloud
metadata endpoints (e.g. 169.254.169.254).

3. Path traversal via file_class (High, CWE-22 / CWE-200)

file_class in POST /v1/video/rendering was used unsanitized to locate
the rendered output file, which was then moved into the public web
directory. A value such as ../../../../tmp/secret could be used to move
an arbitrary .mp4-suffixed file into the public directory and serve it.
In practice, reaching this path also required control over code (to get
manim to exit successfully against the crafted file_class), so it was
primarily a compounding factor on top of (1) rather than an independently
exploitable bug.

Fixes

  • #85 validates and restricts outbound URLs in the export endpoint,
    blocking private/loopback/link-local/reserved addresses and disabling
    redirects (fixes SSRF).
  • #86 requires file_class to be a bare identifier, eliminating the
    traversal primitive (fixes path traversal).
  • #87 adds an API_KEY-based authentication requirement (X-API-Key
    header) enforced on all routes except health/root/static assets (closes
    the fully unauthenticated gap).
  • #88 runs the container as a dedicated non-root user, limiting the impact
    of any future code-execution bug in the render path.

Executing user-submitted code is inherent to this project's rendering
feature; authentication and non-root execution reduce risk but do not
replace full sandboxing. Deployers who accept code or prompts from
untrusted users should still isolate render workers, per the Security
section of docs/cloud-deployment.md.

Credits

Reported privately by Saher Boujemline (@KezoSec),
who reproduced all three issues locally and coordinated disclosure with
advance notice before any public write-up. Thank you for the responsible
disclosure.

Severity

Critical

CVE ID

No known CVE

Weaknesses

Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')

The product uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the product does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory. Learn more on MITRE.

Improper Control of Generation of Code ('Code Injection')

The product constructs all or part of a code segment using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the syntax or behavior of the intended code segment. Learn more on MITRE.

Exposure of Sensitive Information to an Unauthorized Actor

The product exposes sensitive information to an actor that is not explicitly authorized to have access to that information. Learn more on MITRE.

Server-Side Request Forgery (SSRF)

The web server receives a URL or similar request from an upstream component and retrieves the contents of this URL, but it does not sufficiently ensure that the request is being sent to the expected destination. Learn more on MITRE.

Credits