A media server is the most forgivable thing to expose to the internet. It is also, this month, the most expensive.

On 20 October 2026 CISA added four Plex Media Server vulnerabilities to its Known Exploited Vulnerabilities catalogue at once. Chained, they let an attacker with no credentials obtain an admin token and execute code as the Plex process. The researcher who found them scores the chain 9.8.

The patched build, 1.43.3.10861, was released on 4 August. Everything that has happened since is about the gap between a fix existing and a fix being installed, and that gap is the only part of this story you control.

The timeline, because it is the argument

DateEvent
27 July 2026Researcher Zach Main reports the chain to Plex
3-4 August 2026Plex Media Server 1.43.3.10861 ships with the fix
Early September 2026Shadowserver counts over 36,000 internet-exposed servers still unpatched
16 October 2026Full technical write-up published
17 October 2026First in-the-wild exploitation observed, against honeypots, dropping a cryptominer
19 October 2026Public proof-of-concept exploit on GitHub
20 October 2026CISA adds all four CVEs to the KEV catalogue
23 October 2026Federal remediation deadline for the two worst of them

Eleven weeks of warning. Thirty-six thousand servers that did not use them.

What the chain actually is

Four issues, each unremarkable alone, which is exactly why they sat unnoticed:

  • CVE-2026-96652 (CVSS 5.3), server-side request forgery: Plex can be made to send POST requests to arbitrary destinations, including its own internal APIs.
  • CVE-2026-96654 (CVSS 6.9), URL injection: attacker-controlled parameters reach other plugins’ functions.
  • CVE-2026-96655 (CVSS 5.3), another SSRF, this one in the transcoder endpoint.
  • CVE-2026-96656 (CVSS 8.6), arbitrary file write in the transcoder settings: a shared library can be planted where Plex will load it.

Read the last one again, because it is the pattern worth carrying to every other service you run: a process that writes files, and later loads code from the directory it writes to, is one file-write bug away from code execution. Codecs, plugins, themes, extensions, uploads with an include path. The individual scores are medium. The chain is 9.8.

Exploitation needs network access to TCP port 32400. Plex’s Remote Access feature, or a manual port forward, is what turns a living-room service into an internet-facing one.

Do these three things first

1. Check the full build number, not the marketing version.

# Debian or Ubuntu package install
dpkg -s plexmediaserver | grep '^Version'
# official Docker image
docker exec plex dpkg -s plexmediaserver | grep '^Version'
# any install, from the box itself: the identity endpoint answers without a token
curl -s http://127.0.0.1:32400/identity

Anything below 1.43.3.10861 is affected. An early 1.43.3 build is still affected: the last five digits are the ones that matter.

2. Update, then confirm the running process is the new one. A container that was never re-pulled, or a package held back by a pin, will happily report a new version in the UI while the old binary is still serving.

docker compose pull plex && docker compose up -d plex
docker exec plex dpkg -s plexmediaserver | grep '^Version'

3. If the server was internet-reachable on an old build, assume it was reached. Plex’s own advisory says to treat such servers as potentially compromised, and gives indicators: unfamiliar .so or .dll files in the Codecs directory, and outbound connections to proxystream.st. Check both before you call it done:

# unexpected shared libraries in the codec directory
find ~/Library/Application\ Support/Plex\ Media\ Server/Codecs \
     /var/lib/plexmediaserver/Library/Application\ Support/Plex\ Media\ Server/Codecs \
     -name '*.so' -o -name '*.dll' 2>/dev/null | sort

# anything the box is talking to that you cannot name
ss -tn state established | awk 'NR>1{print $4}' | sort | uniq -c | sort -rn | head -20

A cryptominer announces itself in CPU. Proxyware does not: it sells your address as residential bandwidth and stays quiet. Absence of load is not absence of compromise.

The checklist that would have saved you anyway

None of the following requires knowing about a CVE in advance. That is the entire point: these controls pay off during the weeks when you have not patched yet, which is every service you run, always.

Do not port-forward a service to the internet to use it yourself. Remote Access and a forwarded port exist to serve people who are not on your network. If the only remote user is you, a WireGuard tunnel or a mesh VPN removes the attack surface completely rather than defending it. Exposure is a decision, and most of the time nobody ever makes it deliberately.

Default-deny inbound, with the open ports written down. On a box that runs several things, the firewall is the only place where “what is reachable” is answerable in one screen:

ufw default deny incoming
ufw allow 443/tcp
ufw status numbered

Read the output top to bottom and ask what matches first. On a legacy box we audited this month, a careful three-subnet allowlist sat four lines below a blanket ACCEPT for the same port from 0.0.0.0/0, which meant it had never restricted anything. The full audit is here.

Put HTTP services behind one reverse proxy, never directly on the internet. One TLS configuration, one access log, one place to add authentication. The pattern we run on this very site, in full, is in Caddy and Docker in production. The short version for a service that needs no public access at all:

media.example.com {
    @notlocal not remote_ip 10.0.0.0/8 100.64.0.0/10 192.168.0.0/16
    respond @notlocal 403
    reverse_proxy 127.0.0.1:32400
}

Bind the service to localhost and let the proxy be the only door. A container published as -p 32400:32400 is on every interface the host owns, including the public one; -p 127.0.0.1:32400:32400 is not. This single character difference is the most common accidental exposure we find.

Treat outbound traffic as something you are allowed to care about. Both observed payloads here, the miner and the proxyware, are useless without egress. A home or small-office box has no business opening arbitrary outbound connections, and a baseline you can diff is worth more than any IOC list published after the fact.

Know how you would rebuild, and have tested it. After this class of compromise the honest advice is a clean install, which is only survivable if your data is somewhere else and restoring is something you have done before, not something you plan to learn under pressure. Where that somewhere else should be, with real prices on real data, is in our backup storage comparison.

Subscribe to the release notes of anything you expose. Eleven weeks is not an unlucky interval, it is an unread mailing list. For a self-hosted service the vendor has no way to reach you, and no obligation to try.

What we do not know

We have not seen the inside of a compromised host ourselves, and we are not going to pretend otherwise. The indicators above are Plex’s, the exposure counts are Shadowserver’s, the CVSS numbers are the researcher’s, and the exploitation dates come from the vendors and CISA. Our contribution is the part we can stand behind: what the pattern means for the rest of your stack, and the configuration we actually run.

FAQ

Which Plex version fixes Plex2Shell? 1.43.3.10861 and later, released on 4 August 2026. Builds before that are affected, including earlier 1.43.3 builds.

Is my Plex server at risk if it is not exposed to the internet? The chain needs network access to TCP port 32400. A server reachable only from your LAN is still exploitable from that LAN, so a compromised laptop or an untrusted guest device is enough. It is a smaller risk, not a theoretical one.

How do I know if my Plex server was already compromised? Plex’s advisory points at two indicators: unfamiliar .so or .dll files in the Codecs directory, and outbound connections to proxystream.st. Observed payloads have been cryptominers and proxy malware. If the server was internet-facing on an old build, the safe assumption is compromise.

Does updating remove an existing compromise? No. Patching closes the door; it does not remove anything already inside. After a confirmed compromise the only clean path is a rebuild from known-good media plus a restore of data you can verify.

Should I just turn off Plex Remote Access? If the only person streaming from outside your home is you, yes, and reach it over a VPN instead. Remote Access is the feature that puts port 32400 on the internet, and the 36,000 exposed servers counted in September were mostly not deliberate decisions.

What’s next

If this prompted a look at the rest of your stack, the one-hour audit for a server you inherited is the checklist we use on an unknown box, and the VPS comparison covers where to put a service you would rather not run at home at all.