---
title: "Plex Media Server CVE-2026-96656 (CISA KEV): Check, Investigate and Patch"
source: "https://support.tools/plex-media-server-cve-2026-96656-check-and-patch/"
published: 2026-10-27
categories: ["Security","Network Security","Self-Hosting","Linux"]
tags: ["Security","CVE","Vulnerability Management","Self-Hosting","Ubuntu","Linux"]
---

## Quick fix

Upgrade Plex Media Server to 1.43.3.10861 or later (the current release is 1.43.5.11079), then confirm with `curl -s http://127.0.0.1:32400/identity`. If apt reports NO_PUBKEY 0A05F1E6E7AFD573, install the PlexSign.v2 key and re-add the repo as shown below.



On 2026-10-20, CISA added four Plex Media Server vulnerabilities to its [Known Exploited Vulnerabilities (KEV) catalog](https://www.cisa.gov/known-exploited-vulnerabilities-catalog): CVE-2026-96656, CVE-2026-96654, CVE-2026-96655 and CVE-2026-96652. A fifth bug from the same advisory, CVE-2026-96651, is not in KEV, but it is the piece that turns an "admin only" code execution bug into something a regular session holder can reach. All five are fixed in Plex Media Server 1.43.3.10861. If your home media server is older than that, it needs attention today.

This guide is for self-hosters running Plex on Debian or Ubuntu (with a short section for Docker). It covers three questions in order: am I vulnerable, was I compromised, and how do I patch. It also covers the apt signing key gotcha that leaves many servers silently stuck on old builds after an Ubuntu release upgrade.

## What Was Fixed and Why the Chain Matters

All five CVEs were published in NVD on 2026-09-23, alongside the CISA CSAF advisory va-26-266-01 titled "Plex Media Server" and Plex's [release notes](https://forums.plex.tv/t/plex-media-server/30447/711). Every NVD record says the same thing about affected versions: "before 1.43.3.10861". Plex also posted [Important security update for Plex Media Server v1.43.2 and earlier](https://forums.plex.tv/t/important-security-update-for-plex-media-server-v1-43-2-and-earlier/942319), which the KEV entries link to. The researcher write-up, titled [plex2shell](https://zmain.info/blog/plex2shell), describes the chain to code execution.

| CVE | Issue | CVSS 4.0 | CVSS 3.1 | Auth required | CISA KEV |
|---|---|---|---|---|---|
| [CVE-2026-96656](https://nvd.nist.gov/vuln/detail/CVE-2026-96656) | Admin can write files that are executed on load (x264 options and startup `.so` loading) | 8.6 HIGH | 7.2 HIGH | Admin | Added 2026-10-20, due 2026-10-23 |
| [CVE-2026-96651](https://nvd.nist.gov/vuln/detail/CVE-2026-96651) | Path traversal in `/system/agents/media/get` reads any file the PMS user can read, including `PlexOnlineToken` | 7.1 HIGH | 6.5 MEDIUM | Session token | Not listed |
| [CVE-2026-96652](https://nvd.nist.gov/vuln/detail/CVE-2026-96652) | SSRF via `/player/timeline` (`protocol` parameter) | 5.3 MEDIUM | 4.3 MEDIUM | Low | Added 2026-10-20, due 2026-11-03 |
| [CVE-2026-96654](https://nvd.nist.gov/vuln/detail/CVE-2026-96654) | `searchOne` does not neutralize URL values, so callers can invoke other plugins' functions with their own parameters | 6.9 MEDIUM | 6.5 MEDIUM | None | Added 2026-10-20, due 2026-10-23 |
| [CVE-2026-96655](https://nvd.nist.gov/vuln/detail/CVE-2026-96655) | SSRF via the `/video/:/transcode/universal` path parameter | 5.3 MEDIUM | 4.3 MEDIUM | Low | Added 2026-10-20, due 2026-11-03 |

Scores are the CNA scores shown in NVD. Note that there is no Plex CVE-2026-96653; that ID belongs to an unrelated WordPress plugin, so do not treat this as a contiguous range. CISA lists known ransomware use as "Unknown" for all four KEV entries.

### How the pieces fit together

CVE-2026-96656 is the code execution primitive. According to NVD, the `TranscoderH264Options` preference is appended verbatim to the x264 option string on every transcode. Separately, at startup Plex loads every `.so` file it finds without checking signatures, execute bits or symbols. An attacker who can set preferences can therefore get a file written to disk during a transcode and have it loaded as native code the next time the server starts. On its own this requires admin rights, which is why the CVSS 4.0 vector says PR:H.

The other bugs remove that requirement:

- **CVE-2026-96651** lets anyone with a valid session token (a shared user, a friend you gave library access to, or a stolen client token) read arbitrary files. `Preferences.xml` holds the server's `PlexOnlineToken`, and NVD notes that this token gives control of both the account and the server. NVD also notes that a LAN-adjacent attacker supplying their own `X-Forwarded-For` header can do the same.
- **CVE-2026-96654** needs no authentication at all and lets a caller drive other plugins' functions.
- **CVE-2026-96652** and **CVE-2026-96655** are server-side request forgery bugs that let the server be used to reach internal or external addresses.

So the realistic path is: get a session (or abuse the unauthenticated surface), read the owner token, act as admin, and then use the preference and library loading behavior to run code as the `plex` user. That combination is what CISA is responding to.

Exposure is not hypothetical. SC World, citing Shadowserver, [reported more than 36,000 Plex Media Servers still unpatched](https://www.scworld.com/brief/over-36000-plex-media-servers-remain-unpatched-against-security-vulnerabilities) against these issues. That figure is theirs, not ours, but it matches what you would expect from a product that self-hosters install once and forget.

## Am I Vulnerable?

You are vulnerable if your Plex Media Server version is lower than **1.43.3.10861**. The current release on the Plex repo and downloads API is **1.43.5.11079-b3b13e506**.

### Check the installed version

On Debian or Ubuntu, ask dpkg:

```bash
dpkg -l plexmediaserver | awk '/^ii/ {print $2, $3}'
```

```text
plexmediaserver 1.42.2.10156-<build-hash>
```

The `/identity` endpoint reports the running version without a token, which is handy because it reflects what is actually executing rather than what is on disk:

```bash
curl -s http://127.0.0.1:32400/identity | grep -o 'version="[^"]*"'
```

```text
version="1.42.2.10156-<build-hash>"
```

In the Web UI, the version is shown under **Settings > General** for the server.

To get a clear pass or fail, let dpkg compare versions for you:

```bash
#!/usr/bin/env bash
set -euo pipefail
fixed="1.43.3.10861"
running=$(curl -s http://127.0.0.1:32400/identity | sed -n 's/.*version="\([^"]*\)".*/\1/p')
if [ -z "$running" ]; then
  echo "Could not read version from /identity" >&2
  exit 2
fi
if dpkg --compare-versions "$running" lt "$fixed"; then
  echo "VULNERABLE: running $running (fixed in $fixed)"
  exit 1
fi
echo "OK: running $running"
```

### Check exposure

Version tells you whether the bugs exist. Exposure tells you who can reach them.

1. **Remote Access.** In the Web UI, open **Settings > Remote Access**. If it shows "Fully accessible outside your network", the server is reachable from the internet on a public port.
2. **Router port forwards.** Look for a manual forward to TCP 32400 (or whatever public port you configured).
3. **UPnP and NAT-PMP.** If UPnP is enabled on the router, Plex may have opened a port by itself. From any Linux host on the LAN, `miniupnpc` can list current mappings:

```bash
sudo apt install -y miniupnpc
upnpc -l | grep -i -E 'plex|32400'
```

4. **Who has session tokens.** Every shared user and every signed-in device holds a token. CVE-2026-96651 means each of those is a potential path to your owner token, so even a server that is "only shared with family" is in scope.

## Was I Compromised?

The checks below are read-only. Run them before you upgrade, because upgrading and restarting changes file times and rotates logs. The default data directory on Debian and Ubuntu is used throughout:

```bash
PMS_DATA="/var/lib/plexmediaserver/Library/Application Support/Plex Media Server"
```

> [!WARNING]
> `Preferences.xml` contains your `PlexOnlineToken`. Never `cat` it, paste it into a ticket, or attach it to a forum post. The commands below print attribute names only.

### 1. Inspect Preferences.xml keys without printing values

List the attribute names and nothing else:

```bash
sudo grep -o ' [A-Za-z0-9]*=' "$PMS_DATA/Preferences.xml" | tr -d ' =' | sort -u
```

Or with Python, which parses the XML properly:

```bash
sudo python3 -I -c 'import sys, xml.etree.ElementTree as E; print("\n".join(sorted(E.parse(sys.argv[1]).getroot().attrib)))' "$PMS_DATA/Preferences.xml"
```

Then filter for transcoder settings:

```bash
sudo python3 -I -c 'import sys, xml.etree.ElementTree as E; print("\n".join(k for k in sorted(E.parse(sys.argv[1]).getroot().attrib) if k.startswith("Transcoder")))' "$PMS_DATA/Preferences.xml"
```

The key you care about most is **`TranscoderH264Options`**. Most installs never set it. If it is present and you did not add it yourself, treat that as a strong indicator. Any other `Transcoder*` key you do not recognize deserves a closer look in the Web UI (Settings > Transcoder) rather than by dumping the file.

### 2. Verify package files

`dpkg -V` compares installed files against the package's checksums. No output means nothing in the package has changed:

```bash
sudo dpkg -V plexmediaserver
```

A line such as `??5?????? /usr/lib/plexmediaserver/...` means a binary or library shipped by the package has been modified. Configuration files may legitimately differ, but binaries should not.

### 3. Look for shared objects the package does not own

The data directory is not owned by the package, so `dpkg -V` cannot see it. List every shared object under it with its modification time:

```bash
sudo find "$PMS_DATA" -type f -name '*.so*' -printf '%TY-%Tm-%Td %TH:%TM  %u  %p\n' | sort
```

Files under `Codecs/<hash>/` are normal. Plex downloads codec libraries there, and their timestamps typically line up with an upgrade or first transcode. Compare against your package history:

```bash
grep -E ' (install|upgrade) plexmediaserver' /var/log/dpkg.log* 2>/dev/null
```

What to flag:

- `.so` files outside `Codecs/`, for example in `Cache/`, `Logs/`, `Plug-in Support/` or the top of the data directory.
- `.so` files inside `Codecs/` whose time does not match an upgrade or codec download.
- Files written after a known-good reference point:

```bash
sudo find "$PMS_DATA" -type f -name '*.so*' -newer /usr/lib/plexmediaserver/Plex\ Media\ Server -printf '%TY-%Tm-%Td %TH:%TM  %p\n'
```

### 4. Processes, cron and /tmp for the plex user

Code that runs through PMS runs as the `plex` user. Look at what that account is doing:

```bash
ps -u plex -o pid,ppid,lstart,cmd --forest
sudo crontab -l -u plex 2>&1
sudo find /tmp /var/tmp /dev/shm -user plex -printf '%TY-%Tm-%Td %TH:%TM  %p\n' 2>/dev/null
sudo ss -tnp | grep -i plex
```

Expected children of `Plex Media Server` include the transcoder, the plug-in host and tuner or scanner helpers. A shell, `curl`, `wget`, `nc`, or a binary running out of `/tmp` is not expected. A crontab for `plex` is also unusual on a package install.

### 5. Logs

PMS logs live in `$PMS_DATA/Logs/`. Search for preference writes and `searchOne` calls, and strip query strings so you do not print tokens:

```bash
sudo grep -h -E 'PUT /:/prefs|searchOne' "$PMS_DATA"/Logs/Plex\ Media\ Server*.log \
  | sed -E 's/\?[^ ]*//g' | sort | uniq -c | sort -rn | head -50
```

A preference write you did not make, especially around a time you were not using the UI, is worth chasing. Be realistic about what this proves: PMS rotates its logs quickly, often keeping only a few days, so finding nothing is weak evidence. Finding something is strong evidence.

### If anything turns up

Treat the host as compromised. Code execution as `plex` means the attacker had whatever that user can reach, including your media, the database and the owner token.

1. Disconnect the server from the network or stop `plexmediaserver`.
2. From a clean machine, change your plex.tv password and sign out all devices (see Hardening below).
3. Rebuild the host from a known-good image. Do not try to clean it in place.
4. Restore media from storage you trust, and restore the Plex database only if you are confident it was not modified. Do not restore `Preferences.xml`; let the new install claim the server fresh.

## Patch Plex Media Server

On a host with a working Plex repo, patching is one command:

```bash
sudo apt update
sudo apt install --only-upgrade plexmediaserver
curl -s http://127.0.0.1:32400/identity | grep -o 'version="[^"]*"'
```

If the version did not move, you have probably hit the gotcha below.

### The Ubuntu release upgrade gotcha

`do-release-upgrade` disables third-party apt sources as part of the upgrade. Plex's repo is one of them, so after moving to a new Ubuntu release the server keeps running happily on whatever build it had, and `apt upgrade` reports nothing to do. That is exactly how a home media server can fall many months behind without anyone noticing.

The natural fix is to re-enable the old source. That then fails with:

```text
W: GPG error: https://repo.plex.tv/deb public InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 0A05F1E6E7AFD573
E: The repository 'https://repo.plex.tv/deb public InRelease' is not signed.
```

The reason is that Plex no longer signs the repo with its 2015 key (`PlexSign.key`, rsa4096 `97203C7B3ADCA79D`). The `Release` file is now signed by `0A05F1E6E7AFD573`, an ed25519 signing subkey of **PlexSign.v2**. The old keyring simply cannot verify it.

### Install the PlexSign.v2 key

Fetch the key into its own keyring:

```bash
curl -fsSL https://downloads.plex.tv/plex-keys/PlexSign.v2.key \
  | gpg --dearmor \
  | sudo tee /usr/share/keyrings/plexmediaserver.v2.gpg >/dev/null
sudo chmod 0644 /usr/share/keyrings/plexmediaserver.v2.gpg
```

Verify the fingerprint before you trust it:

```bash
gpg --show-keys --with-subkey-fingerprints /usr/share/keyrings/plexmediaserver.v2.gpg
```

You should see a primary key with fingerprint **6EFF EB47 8A65 59D7 5C7C 4FE7 06C5 2179 0B9C FFDE** and the uid `Plex Inc. (SHA-512)`, plus an ed25519 signing subkey ending in `0A05 F1E6 E7AF D573` (full fingerprint `B406 F089 7A39 A570 8042 6054 0A05 F1E6 E7AF D573`, created 2024-02-20, expiring 2029-02-18). If the primary fingerprint does not match, stop and do not install the repo.

### Add the repo as a deb822 source

Remove any stale or disabled Plex entries first (file names vary; check before deleting):

```bash
ls /etc/apt/sources.list.d/ | grep -i plex
grep -rn 'repo.plex.tv\|downloads.plex.tv' /etc/apt/sources.list /etc/apt/sources.list.d/ 2>/dev/null
```

Then create a single deb822 source that pins the new keyring:

```bash
sudo tee /etc/apt/sources.list.d/plexmediaserver.sources >/dev/null <<'EOF'
Types: deb
URIs: https://repo.plex.tv/deb
Suites: public
Components: main
Signed-By: /usr/share/keyrings/plexmediaserver.v2.gpg
EOF
```

`Signed-By` scopes the key to this one repo, which is better practice than dropping it into `/etc/apt/trusted.gpg.d/`, where it would be trusted for every source.

Update, install and confirm:

```bash
sudo apt update
sudo apt install plexmediaserver
systemctl status plexmediaserver --no-pager
curl -s http://127.0.0.1:32400/identity | grep -o 'version="[^"]*"'
```

```text
version="1.43.5.11079-b3b13e506"
```

Anything at or above 1.43.3.10861 is fixed.

### Docker users

If you run the official `plexinc/pms-docker` image, pull a current image and recreate the container rather than relying on an old pinned tag:

```bash
docker pull plexinc/pms-docker:latest
docker compose up -d --force-recreate plex
curl -s http://127.0.0.1:32400/identity | grep -o 'version="[^"]*"'
```

Always confirm the running version through `/identity` after the restart. The image tag is not proof of the PMS version inside the container. The investigation steps above apply too; the data directory is whatever host path you mounted at `/config`.

## Hardening After the Patch

Patching closes the bugs. It does not undo a token that already leaked.

- **Rotate tokens.** Change your plex.tv password and use the option to sign out all connected devices. That invalidates existing device tokens, including any `PlexOnlineToken` read through CVE-2026-96651. Expect to sign clients back in and, if prompted, re-claim the server.
- **Do not forward 32400 raw.** Prefer a VPN (WireGuard or Tailscale) or a reverse proxy that you patch and log. If you must expose PMS directly, limit the source addresses where you can.
- **Disable UPnP** on the router so Plex, or anything else on the LAN, cannot open ports without you knowing.
- **Review shared users.** Remove accounts that no longer need access. Each one holds a session token.
- **Alert on version drift.** The underlying failure in most of these cases is not the bug, it is a server that stopped updating months ago.

### Version drift alerting

The simplest check compares the running version against the public downloads API:

```bash
#!/usr/bin/env bash
# /usr/local/bin/plex-version-check
set -euo pipefail
running=$(curl -fsS http://127.0.0.1:32400/identity | sed -n 's/.*version="\([^"]*\)".*/\1/p')
latest=$(curl -fsS https://plex.tv/api/downloads/5.json | python3 -I -c 'import json,sys; print(json.load(sys.stdin)["computer"]["Linux"]["version"])')
behind=0
dpkg --compare-versions "$running" lt "$latest" && behind=1
out=/var/lib/node_exporter/textfile_collector/plex.prom
cat > "$out.$$" <<EOF
# HELP plex_version_behind 1 if the running Plex Media Server is older than the latest public release
# TYPE plex_version_behind gauge
plex_version_behind{running="$running",latest="$latest"} $behind
EOF
mv "$out.$$" "$out"
```

Run it from a systemd timer or cron every few hours, point node_exporter's `--collector.textfile.directory` at that path, and alert when `plex_version_behind == 1` for more than a few days. If node_exporter already exposes apt metrics on the host, an alert on pending upgrades catches the same problem, with one caveat: a disabled source reports zero pending upgrades, which is exactly the failure described above. The `/identity` comparison does not have that blind spot.

## Related Plex and Overseerr Vulnerabilities

These are not part of the KEV listing, but they belong on the same checklist.

- **[CVE-2025-69414](https://nvd.nist.gov/vuln/detail/CVE-2025-69414)**: a permanent access token can be retrieved via `/myplex/account` using a transient token. NVD 7.1 HIGH (CNA score 8.5). Affects PMS through 1.42.2.10156.
- **[CVE-2025-69415](https://nvd.nist.gov/vuln/detail/CVE-2025-69415)**: device-token access to `/myplex/account` is not aligned with the current device to account association. NVD 7.1 HIGH. Affects PMS through 1.42.2.10156.
- **[CVE-2026-65696](https://nvd.nist.gov/vuln/detail/CVE-2026-65696)** (Overseerr): NVD describes an authorization bypass in the push subscription API in Overseerr through 1.35.0 that lets a user list, read and delete other users' push subscriptions by `userId`, leaking email addresses and plexId values. The record is marked Deferred in NVD, with CNA scores from VulnCheck of 5.3 (CVSS 4.0) and 5.4 (CVSS 3.1). Check the project's own advisory for the fixed release that applies to your deployment.

CISA's catalog also still carries an older Plex entry, CVE-2020-5741 (remote code execution), added on 2023-03-10. Plex has been a KEV target before.

## FAQ

**Is my server safe if Remote Access is off?**
Safer, not safe. CVE-2026-96654 requires no authentication, and NVD notes the CVE-2026-96651 traversal is reachable by a LAN-adjacent attacker. A compromised device on your home network counts. Patch regardless.

**Which version fixes CVE-2026-96656 and the related Plex CVEs?**
Plex Media Server 1.43.3.10861 fixes all five. The current release as of this writing is 1.43.5.11079.

**Why does apt say NO_PUBKEY 0A05F1E6E7AFD573?**
You only have Plex's 2015 key installed. The repo is signed by a subkey of PlexSign.v2. Install that key with the fingerprint check above and reference it with `Signed-By`.

**Do I need to rebuild if I find nothing?**
No. Patch, rotate your plex.tv password and devices, and close direct exposure. Keep in mind that Plex logs rotate quickly, so a clean log check on a long-exposed server is reassuring but not conclusive. If the server sat unpatched and internet-facing for months, rotating tokens is not optional.

## Conclusion

The individual Plex bugs look modest on paper: one needs admin, a couple are medium-severity SSRFs. Together they give an attacker the owner token and native code execution, which is why four of them landed in CISA KEV on 2026-10-20. For most self-hosters the fix is a version bump to 1.43.3.10861 or later. The harder part is noticing that the server stopped updating in the first place. Check `/identity`, run the read-only compromise checks before you upgrade, move the repo to the PlexSign.v2 key, rotate your tokens, and add a drift alert so the next advisory finds you already patched.

