War Room: CVE-2026-4480, when a Samba print job name is a shell command
A deep dive into CVE-2026-4480, a critical pre-auth command injection vulnerability in Samba's printing path. Find affected versions and mitigations.
Table of Contents
Heartbleed taught everyone that the scariest bugs hide in code nobody looks at anymore. CVE-2026-4480 is that lesson again, this time in Samba's printing path. An unauthenticated attacker who can reach a guest printer share runs commands on the host by sending a print job with the right name. No credentials, no chain, no memory corruption. Samba rated it CVSS 10.0, and for once the score is not marketing.
The bug lived in print command, a line most admins copied out of a HOWTO years ago and never touched again.
What is CVE-2026-4480?
When a print job finishes spooling, Samba does not talk to a printer. It runs whatever you set as print command in smb.conf and lets that deal with the spool file. The string takes macros; %s is the spool path and %J is the job name, which the client controls.
Samba builds that string and hands it to system(). Before the patch, %J went in with exactly one transformation: a single quote became an underscore. Every other shell metacharacter survived. A job named |sh is not a job name. It is a pipeline.
Which Samba versions are affected?
Everything before the May 2026 release. The fix shipped in 4.22.10, 4.23.8, and 4.24.3, which escape shell-unsafe characters and wrap %J in quotes.
Three things have to be true for a host to be exploitable:
-
It uses an external
print command(the classicprinting = sysvsetup). Servers onprinting = cupsoriprintgo through the CUPS API and are not affected. -
That command references
%J. -
A client can submit a job, which on a guest-enabled printer share means anyone.
The release was a bundle: reparse-point checks, vfs_worm, GPO certificate handling, WINS, and this. So "we are below the patched version" tells you nothing about which hole you actually have. On a plain file-and-print box with a guest printer and no AD role, the print injection is usually the only one a pre-auth attacker can reach.
What makes it dangerous
Two details turn a config line into pre-auth RCE.
The first is how little sanitization there was. The substitution happens in generic_job_submit() in print_generic.c, and the only cleanup on the job name was that single-quote-to-underscore swap. It looks like it was meant to stop a quote breakout inside a quoted argument, except the default print command does not quote %J at all. It guarded a door nobody used and left the windows open.
The second is that the obvious exploit fails, which is why this survived so long. Queue a malicious job name with smbclient and you get nothing: the legacy RAP print path scrubs metacharacters to _ before they ever reach %J, so |sh becomes _sh. The vulnerable substitution lives on the other road into the spooler, the spoolss RPC interface, where the job name rides in as the document name and lands in %J untouched. The bug is real, the convenient tooling sanitizes it by accident, and the working exploit needs you to speak spooler RPC. That gap is where most people stop reading and assume the advisory is wrong.
How attackers weaponize it
A print job over spoolss is a fixed handful of RPC calls: open the printer, start the document (the name becomes %J), write the spool body, end the document (Samba runs the command), close. Drop |sh in the document name and the finished print command becomes a pipe that feeds the spool body to a shell. The attacker writes their commands as the "file" they are printing, and EndDocPrinter pulls the trigger.
The precondition is a single open printer share, so this is mass-scan bait. A guest-writable printer on 445 is a one-line check, and the result is deterministic once one answers. Treat any internet-facing Samba print service on an unpatched build as already found.
Detection and threat hunting
Nothing shows up in the print logs, because as far as Samba is concerned the job printed fine. Watch process lineage instead.
-
smbdspawning shells. The print helper is a known binary. Ansmbdchild ofsh,bash,nc,python, orcurlis the signal. -
Document names with metacharacters. Job names containing
|,;,&, backticks, or$(are not print jobs. Real ones look like filenames. -
Outbound from the print host. Print servers rarely dial out. A reverse shell from one is loud if you watch egress.
-
Filesystem changes around a print event. Correlate a suspicious job with new files under
/tmpor drop-ins in/etc/systemd. Post-exploitation here pivots into local privesc fast.
Recommended mitigations
Patch. Move to 4.22.10, 4.23.8, or 4.24.3 (or later) and the input is escaped for you.
If you genuinely cannot patch today, quote the macro yourself so the job name cannot break out:
[global]
print command = /usr/local/bin/print-helper %s '%J'
Better still, drop %J if your helper does not need it, or switch to printing = cups and leave the vulnerable path behind. And while you are in smb.conf, ask the question nobody asks: does this host need to share a printer to the network, and does that share need to accept guests? Most of these are leftovers. Keeping 139 and 445 off the open internet is still the cheapest control you have.
Credit for the fix goes to Ron Ben Yizhak (SafeBreach), John Walker (ZeroPath), and Arjun Basnet (Securin Labs).
Want to try it yourself?
We built this one into a box. Abducted (Medium Linux, Hack The Box) is a small firm's file-and-print server: you land the unauthenticated foothold through the guest printer over spoolss, recover a reused credential, abuse a share misconfiguration to move sideways, and take root through a polkit-delegated systemd service. It is the fastest way to feel why a "harmless" printer share is anything but.
Final thoughts
The dangerous surface is rarely the one you are watching. Teams harden authentication and patch the web stack while a CVSS 10.0 sits behind a print command copied from a 2014 tutorial. CVE-2026-4480 was pre-auth, deterministic, and invisible, saved only by an accidental sanitizer on a code path most people never use.
Patch the version, quote the macro, and go find the printer your network forgot it was sharing.