Skip to content

Path traversal to RCE via /avatarproxy image cache filename from upstream ETag

High
M0NsTeRRR published GHSA-mc6w-69r3-62h8 Jul 28, 2026

Package

seerr

Affected versions

< 3.4.0

Patched versions

3.4.0

Description

Summary

A Path Traversal leading to Remote Code Execution vulnerability (CWE-22 / CWE-94) has been identified in seerr's ImageProxy. It allows an attacker who controls the media server's HTTP response to overwrite arbitrary files on disk, including the application's entry point, leading to remote code execution as the node user after the next container restart.

Vulnerability Details

  • Type: Path Traversal (CWE-22), leading to Arbitrary File Write and Remote Code Execution (CWE-94)
  • Impact: An attacker controlling the media server response (malicious/compromised Jellyfin or Emby server, or a MITM position on the default plaintext seerr-to-media-server link) can overwrite arbitrary files in the seerr application, including /app/dist/index.js, the SQLite database, or settings.json.
  • Affected Routes:
    • GET /avatarproxy/:jellyfinUserId (unauthenticated)
  • Root Cause: The on-disk cache filename is built by interpolating the upstream ETag response header directly into a path, stripping only double quotes (imageproxy.ts:281). The filename is passed through path.join + fs.writeFile (imageproxy.ts:321,328), which normalizes embedded ../ sequences, allowing the write to escape the intended cache directory. The written file's extension is derived from the upstream Content-Type header (imageproxy.ts:273), letting an attacker choose .js and target the application's entry point.

Expected Behavior

The cache filename should be derived from a value that cannot contain traversal sequences. The resulting path should also be validated to remain within the intended cache directory before the write occurs.

Actual Behavior

Currently, any response from the configured media server can supply an ETag such as "/../../../../../../dist/index" together with a Content-Type: text/javascript body. A single unauthenticated request to GET /avatarproxy/:jellyfinUserId triggers the fetch and cache write, overwriting /app/dist/index.js with attacker-controlled content. On the next process restart (node dist/index.js), the injected code executes as the node user (uid 1000) inside the container.

Credit

Jan Kahmen, turingpoint (jan@turingpoint.de)

Severity

High

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Adjacent
Attack complexity
High
Privileges required
None
User interaction
None
Scope
Unchanged
Confidentiality
Low
Integrity
High
Availability
High

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:A/AC:H/PR:N/UI:N/S:U/C:L/I:H/A:H

CVE ID

CVE-2026-73291

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.

Credits