CVE-2026-73291 Overview
CVE-2026-73291 is a path traversal vulnerability [CWE-22] in Seerr, an open-source media request and discovery manager for Jellyfin, Plex, and Emby. Versions prior to 3.4.0 contain a flaw in server/lib/imageproxy.ts where the unauthenticated GET /avatarproxy/:jellyfinUserId route builds cache filenames from upstream ETag and Content-Type response headers without sanitization. A malicious or compromised Jellyfin or Emby server, or a network attacker positioned to intercept plaintext media-server traffic, can inject traversal sequences that escape the cache directory. Attackers can overwrite /app/dist/index.js and gain code execution as the node user after a container restart.
Critical Impact
Path traversal in the unauthenticated avatar proxy allows arbitrary file overwrite and remote code execution as the node user following a container restart.
Affected Products
- Seerr versions prior to 3.4.0
- Deployments integrated with Jellyfin or Emby media servers
- Containerized Seerr installations using the default /app/dist/index.js entrypoint
Discovery Timeline
- 2026-08-12 - CVE-2026-73291 published to NVD
- 2026-08-12 - Last updated in NVD database
Technical Details for CVE-2026-73291
Vulnerability Analysis
The vulnerability resides in the ImageProxy class within server/lib/imageproxy.ts. When Seerr proxies avatar images through the GET /avatarproxy/:jellyfinUserId endpoint, it constructs a cache filename by concatenating values derived from the upstream response headers. The ETag header value and the file extension resolved from the Content-Type header are both incorporated directly into the on-disk filename.
Because neither value is filtered for path separators or traversal sequences, path.join normalizes attacker-supplied ../ fragments and fs.writeFile writes the fetched image bytes outside the intended cache directory. Overwriting /app/dist/index.js replaces the Node.js entrypoint; when the container restarts, the injected JavaScript executes as the node user.
Root Cause
The root cause is missing input validation on untrusted upstream HTTP response headers. Seerr treats the connected Jellyfin or Emby server as a trusted source and passes header content directly into filesystem path construction, violating standard path canonicalization practices [CWE-22].
Attack Vector
Exploitation requires one of two positions. An attacker who controls or has compromised the linked Jellyfin or Emby server can return crafted ETag and Content-Type headers when Seerr requests an avatar. Alternatively, a network attacker on the same segment as a plaintext (non-TLS) media-server connection can intercept the response and inject malicious headers. The /avatarproxy/:jellyfinUserId route is unauthenticated, so any Seerr user identifier is sufficient to trigger the outbound fetch.
const buffer = Buffer.from(response.data, 'binary');
const contentType = response.headers['content-type'] || '';
- const extension = mime.getExtension(contentType) || '';
+ const extension = (mime.getExtension(contentType) || '').replace(
+ /[^\w-]/g,
+ ''
+ );
let maxAge = Number(
(response.headers['cache-control'] ?? '0').split('=')[1]
);
if (!maxAge) maxAge = 86400;
const expireAt = Date.now() + maxAge * 1000;
- const etag = (response.headers.etag ?? '').replace(/"/g, '');
+ const etag = (response.headers.etag ?? '').replace(/[^\w-]/g, '');
await this.writeToCacheDir(
directory,
Source: GitHub Commit f484791. The patch restricts both the extension and ETag values to word characters and hyphens, eliminating path separators and traversal sequences.
Detection Methods for CVE-2026-73291
Indicators of Compromise
- Unexpected modifications to /app/dist/index.js or other files within the Seerr container filesystem outside the designated cache directory.
- Files in the Seerr avatar cache directory with names containing .., /, or other non-alphanumeric characters.
- Outbound HTTP requests from Seerr to Jellyfin or Emby endpoints returning ETag headers containing traversal sequences.
Detection Strategies
- Monitor the Seerr container filesystem for write operations targeting paths outside the configured cache directory.
- Inspect HTTP responses to the /avatarproxy/:jellyfinUserId route for malformed ETag or Content-Type header values.
- Alert on unexpected Seerr container restarts followed by anomalous outbound network activity from the node process.
Monitoring Recommendations
- Enable file integrity monitoring on /app/dist/ and other Seerr application directories.
- Log all upstream response headers received by the ImageProxy module for post-incident analysis.
- Track process execution and child process creation originating from the Seerr Node.js runtime.
How to Mitigate CVE-2026-73291
Immediate Actions Required
- Upgrade Seerr to version 3.4.0 or later, which sanitizes ETag and extension values used in cache filename construction.
- Verify the integrity of /app/dist/index.js and other application files in existing Seerr containers before restart.
- Restrict Seerr-to-media-server communication to TLS-protected channels to eliminate the man-in-the-middle attack path.
Patch Information
The fix is available in Seerr 3.4.0. See the GitHub Release v3.4.0 and the GitHub Security Advisory GHSA-mc6w-69r3-62h8 for full remediation details.
Workarounds
- Place Seerr behind a reverse proxy that blocks or authenticates the /avatarproxy/:jellyfinUserId route until upgrade is possible.
- Ensure Jellyfin and Emby servers connected to Seerr are trusted, patched, and reachable only over HTTPS.
- Run the Seerr container with a read-only root filesystem, permitting writes only to the dedicated cache volume.
# Upgrade Seerr container to the patched release
docker pull ghcr.io/seerr-team/seerr:3.4.0
docker stop seerr && docker rm seerr
docker run -d --name seerr \
--read-only \
--tmpfs /tmp \
-v seerr-config:/app/config \
-v seerr-cache:/app/config/cache \
ghcr.io/seerr-team/seerr:3.4.0
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

