Two vulnerabilities published on April 2, 2026 — CVE-2026-34980 and CVE-2026-34990 — chain into a complete unauthenticated remote-to-root exploit against any Linux server running CUPS with a shared PostScript queue reachable on the network. Active exploitation has been confirmed. The fix is a one-liner if you do not print, and a single package upgrade if you do. Run the check below right now before reading the rest.
systemctl is-active cups 2>/dev/null || echo "CUPS not running"
If this returns active, your server is exposed until you take action. If it returns inactive, unknown, or CUPS not running, you are not immediately at risk from the network vector — but check whether the package itself is installed, because CVE-2026-34990 has a local privilege escalation path that matters even if the service is down.
Why VPS Servers Are the Primary Target
CUPS was not designed for server environments. It is a desktop printing subsystem. The problem is that many base OS images shipped by distributions — and pulled into VPS templates — install CUPS as a recommended dependency of other packages, often without any explicit request from the operator. A Rocky Linux or Ubuntu Server system provisioned from a standard image can have cupsd running on port 631, listening for connections, despite the VPS never having seen a printer in its existence.
This is the attack surface that makes CVE-2026-34980 disproportionately dangerous for cloud infrastructure compared to desktop systems. On a desktop, CUPS is expected to be present and a local firewall typically blocks port 631 from external access. On a VPS, the same port is often open to the internet because nobody thought to audit a print daemon on a web server. According to the researcher who discovered the chain, the prerequisites — a network-exposed cupsd with a shared PostScript queue — are satisfied in practice across a large portion of Linux servers scanned during responsible disclosure.
How the Two-CVE Chain Works
Understanding the mechanism matters because it determines which mitigation applies to your situation. The two vulnerabilities are independent at the code level but sequential in the attack path.
CVE-2026-34980 — Unauthenticated RCE as lp
CUPS accepts anonymous Print-Job requests to shared queues by default — the authentication check only blocks remote jobs to non-shared queues. The vulnerability is a parsing flaw in how cupsd handles the page-border option value submitted as textWithoutLanguage in a crafted IPP request. An attacker embeds a newline character inside the option value. CUPS preserves the newline through its option escaping and reparse stage, then reparses the resulting second line as a trusted PPD scheduler control record rather than as user-supplied data.
A follow-up raw print job exploits the injected control record to instruct the scheduler to execute an existing binary on the server — the researcher used /usr/bin/vim as a proof-of-concept, but any binary reachable by the lp account works. The attacker now has code execution as the lp service account. This by itself is serious but not game over — lp is a low-privilege account and cannot directly read sensitive files or write to system paths. That is where the second CVE enters.
CVE-2026-34990 — lp to Root via Localhost IPP Token Abuse
The second flaw exists in the default CUPS authorization policy for localhost connections. CUPS issues reusable Authorization: Local tokens for local connections and — critically — the CUPS-Create-Local-Printer IPP operation is not gated behind admin authentication when the request originates from localhost in the default policy.
With code execution as lp, the attacker coerces cupsd to authenticate to an attacker-controlled IPP service on a chosen localhost port. CUPS hands over a local token. The attacker reuses that token to issue /admin/ requests directly against the live cupsd instance. Using CUPS-Create-Local-Printer with printer-is-shared=true and a file:/// URI, the attacker registers a fake printer pointing to any file path on the system. The normal FileDevice policy rejects file:// URIs — but this bypass sidesteps it via the Create-Local-Printer path. Triggering a print job to that fake printer gives an arbitrary root file overwrite. The published proof-of-concept drops a sudoers fragment granting the attacker full root command execution.
The full chain: unauthenticated network attacker → IPP print job → RCE as lp → localhost token capture → admin API access → file overwrite as root → sudoers entry → root shell. No credentials required at any stage for the initial entry.
Affected Versions and Patch Status
Both CVEs affect CUPS versions 2.4.16 and earlier. OpenPrinting released CUPS 2.4.17 on April 16, 2026, which fixes CVE-2026-34980 (control character filtering in option values) and CVE-2026-34990 (local certificate handling over the loopback interface), along with four additional CVEs patched in the same release.
Distribution-level patch availability as of April 20, 2026:
| Distribution | CVE-2026-34980 status | CVE-2026-34990 status | Action |
|---|---|---|---|
| Ubuntu 22.04 / 24.04 | Patch in progress | Patch in progress | Disable or block port 631 immediately |
| Debian 11 Bullseye | Vulnerable (2.3.3op2) | Vulnerable | Disable or block port 631 immediately |
| Debian 12 Bookworm | Vulnerable (2.4.2) | Vulnerable | Disable or block port 631 immediately |
| Rocky Linux 8 / 9 | Red Hat advisory active | Red Hat advisory active | Disable or apply available advisory update |
| AlmaLinux 8 / 9 | Red Hat advisory active | Red Hat advisory active | Disable or apply available advisory update |
| openSUSE / SLES | SUSE advisory active | SUSE advisory active | Apply zypper security update |
| Arch Linux | cups 2.4.17 in repos | cups 2.4.17 in repos | pacman -Syu |
| Alpine Linux | Check aports tracker | Check aports tracker | Disable or apk upgrade cups |
For distributions where the patched package is not yet available in the official repositories, disabling the service entirely is the correct mitigation — not waiting. A VPS that does not use a printer has no reason to run cupsd at all.
Step 1 — Full Exposure Check
Run this block in your VPS console or over SSH. It checks whether the service is running, which version is installed, and whether port 631 is reachable externally:
# Check if cupsd is running
systemctl is-active cups 2>/dev/null && echo "EXPOSED: cupsd is active" || echo "cupsd not running"
# Check installed version
cups-config --version 2>/dev/null || dpkg -l cups 2>/dev/null | grep ^ii || rpm -q cups 2>/dev/null
# Check if port 631 is listening and on which interface
ss -tlnp | grep 631
The third command is the most important. If port 631 shows 0.0.0.0:631 or :::631, the daemon is listening on all interfaces and is reachable from the internet. If it shows 127.0.0.1:631, the network-attack vector of CVE-2026-34980 is blocked — but CVE-2026-34990's local privilege escalation path still applies if any local user accounts exist on the machine.
Step 2a — If Your VPS Does Not Print (Most VPS Workloads)
Stop and permanently disable CUPS. Also disable cups-browsed if present, as it is a separate service that participates in the 2024 CUPS vulnerability chain and has no purpose on a server:
# Stop and disable the main CUPS scheduler
systemctl stop cups
systemctl disable cups
systemctl mask cups
# Stop and disable cups-browsed if installed
systemctl stop cups-browsed 2>/dev/null
systemctl disable cups-browsed 2>/dev/null
systemctl mask cups-browsed 2>/dev/null
# Verify both are gone
systemctl is-active cups cups-browsed 2>/dev/null
The mask command goes beyond disable — it symlinks the service unit to /dev/null, which prevents any other package or process from starting it back up as a dependency. On Alpine Linux (OpenRC), the equivalent is:
rc-service sshd stop # stop if running
rc-update del cups # remove from runlevel
rc-update del cups-browsed 2>/dev/null
On FreeBSD, prevent it from starting at boot:
sysrc cupsd_enable="NO"
service cupsd stop 2>/dev/null
After masking, run the exposure check block again and confirm port 631 no longer appears in the ss output.
Step 2b — If Your VPS Runs a Print Server (Patch Required)
If you are running CUPS deliberately — for example, a shared office print server or a workstation-style VPS with a GUI — disabling the service is not an option. The correct action is to upgrade to CUPS 2.4.17, the only release that patches both CVEs.
On Arch Linux, where 2.4.17 is already in the repos:
pacman -Syu cups
On distributions where 2.4.17 is not yet available through the system package manager, apply the available security advisory update as a partial mitigation and add a firewall rule immediately to restrict port 631 to trusted source IPs only:
# Ubuntu / Debian — block external access to CUPS port
ufw deny 631/tcp
ufw deny 631/udp
ufw reload
# Rocky Linux / AlmaLinux / RHEL
firewall-cmd --permanent --remove-service=mdns
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" port port="631" protocol="tcp" reject'
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" port port="631" protocol="udp" reject'
firewall-cmd --reload
The firewall rule neutralizes the network vector of CVE-2026-34980 without disabling printing functionality for local users. CVE-2026-34990 remains a risk as long as the service is running and unprivileged accounts have local access, so the CUPS 2.4.17 upgrade is still required as soon as the patched package reaches your distribution's repository.
Step 3 — Verify the Fix
After applying either mitigation, confirm the state with a final check:
# Confirm service is not running (disable path)
systemctl is-active cups && echo "WARNING: still active" || echo "OK: not running"
# Confirm port 631 is no longer exposed (both paths)
ss -tlnp | grep 631 && echo "WARNING: port still open" || echo "OK: port 631 not listening"
# Confirm mask is in place (disable path)
systemctl is-enabled cups
The last command should return masked, not disabled. A masked unit cannot be started by any trigger, including package updates. A merely disabled unit can be started manually or as a dependency — masking is the correct state for a service you intentionally removed from a server.
Broader Hardening Context
The CUPS situation is a specific instance of a general problem: services that belong to workstation environments end up on servers because base OS images are built for breadth, not for minimal attack surface. A freshly installed Ubuntu Server or Rocky Linux VPS can be running a print daemon, an Avahi mDNS responder, a Bluetooth stack stub, and an SNMP agent — none of which belong on a cloud server, all of which have historical CVE track records.
The correct long-term practice is an explicit audit of running services immediately after provisioning a new VPS:
systemctl list-units --type=service --state=running
Any service that you cannot explain a specific reason for should be stopped and masked. This brings the VPS to a minimal running state where the attack surface matches the actual workload, not the default assumptions of a desktop package manifest.
If you need help auditing and hardening a VPS — including identifying unexpected running services, configuring firewall rules, and applying pending security advisories — the ServerSpan managed Linux administration service covers this class of work directly. For newly provisioned servers that need a clean starting point, all ServerSpan VPS plans include full root access and console availability so you can apply these steps immediately after provisioning.
Summary of required actions as of April 20, 2026: If your VPS is running CUPS and you do not need it — stop, disable, and mask the service right now. If you need CUPS and are on Arch Linux, upgrade to 2.4.17 via pacman -Syu. If you need CUPS on any other distribution where 2.4.17 is not yet in the repos, add a firewall rule blocking port 631 externally and watch for the patched package. No patch, no exception — CVE-2026-34990 gives root to any local user on a default CUPS configuration.
Source & Attribution
This article is based on original data belonging to serverspan.com blog. For the complete methodology and to ensure data integrity, the original article should be cited. The canonical source is available at: CUPS RCE on Linux VPS: CVE-2026-34980 Chains to Root — Check If You Are Exposed Right Now.