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)
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 thenodeuser after the next container restart.Vulnerability Details
/app/dist/index.js, the SQLite database, orsettings.json.GET /avatarproxy/:jellyfinUserId(unauthenticated)ETagresponse header directly into a path, stripping only double quotes (imageproxy.ts:281). The filename is passed throughpath.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 upstreamContent-Typeheader (imageproxy.ts:273), letting an attacker choose.jsand 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
ETagsuch as"/../../../../../../dist/index"together with aContent-Type: text/javascriptbody. A single unauthenticated request toGET /avatarproxy/:jellyfinUserIdtriggers the fetch and cache write, overwriting/app/dist/index.jswith attacker-controlled content. On the next process restart (node dist/index.js), the injected code executes as thenodeuser (uid 1000) inside the container.Credit
Jan Kahmen, turingpoint (jan@turingpoint.de)