
There's a sentence I've written in reports and I've started to distrust it: "authorisation is enforced on the request". I've typed that after watching a check fire, seeing a 403 come back, and moving on to the next thing. PaperCut's zero-day this week is a fairly expensive argument against that habit. The check was there. It ran. It passed. It was just reading the permissions of the page the server was about to draw, not the page that owned the code it was about to run.
So here's my claim, and I'll spend the rest of the post trying to earn it: the two CVEs in this chain are the same mistake in two different places. PaperCut trusted a name and never checked the thing the name pointed at. Once you see it that way, the bit where the first emergency patch got bypassed the same day stops being surprising.
If you run PaperCut NG or MF and the Application Server answers on anything the internet can reach, this one is pointed at you, and it's pointed at this weekend rather than next sprint.
What shipped this week, in order
PaperCut NG and PaperCut MF are print management servers, made by an Australian company of the same name. They sit in universities, councils, hospitals and a lot of mid-sized offices, they hold user directories and sometimes the documents themselves, and their web interface has a habit of being published so people can release a print job from a laptop at home. I've got a print server in my own lab that I have genuinely never once thought about as an attack surface, which is the whole problem in miniature.
Huntress sees exploitation in two customer environments. One incident lasts under two minutes.
PaperCut publishes an urgent advisory. Active exploitation, confirmed customer incidents, no CVE, no CVSS, no technical detail.
Emergency patch for v25 and v26. Patches for v24 follow later the same day.
CVE-2026-81578 and CVE-2026-82078 assigned. Rapid7 publishes the exploit path. Emergency Patch Release 2 ships after work with Huntress and watchTowr.
The two identifiers matter because of how differently they score on their own. CVE-2026-81578 is improper access control in the web management interface, CVSS 4.0 8.8, and Rapid7 map it to CWE-306, missing authentication for a critical function. PaperCut's own wording is that "unauthenticated remote requests targeting administrative functions can trigger backend actions prior to the completion of access validation checks". CVE-2026-82078 is unsafe dynamic class loading in the database connection utilities, CVSS 4.0 9.4, CWE-470, and its vector carries PR:H. On paper it needs an administrator.
Read those two rows in a vulnerability report on a Monday morning and you get a high that lets a stranger change a setting, and a critical that needs an admin session you assume nobody has. Neither of those is a fire on its own. Together they are unauthenticated code execution as the service account, and the chain is the whole story. That's the same lesson as the SharePoint chain a few weeks back, where treating each CVE as its own ticket was exactly how people stayed exploitable.
Why "we check on every request" feels like enough
I want to state the other side properly, because it isn't stupid and I've held it. If a framework runs an access check on every inbound request, before any handler executes, then you've got a single choke point. One place to audit, one place to fix, no chance of a developer forgetting a decorator on a new endpoint. That design is genuinely better than sprinkling permission checks through five hundred controllers and hoping. Most secure-by-default advice points at exactly that pattern.
PaperCut had that. The check was central, it ran early, and on a normal request it did the right thing. What nobody had asked, apparently for years, was a much more boring question: when the check looks up "what permissions does this request need", which object is it asking about.
The first name: a page in a URL
PaperCut is built on Apache Tapestry, a Java web framework. Tapestry has a request format called complex direct, and its job is to let a link on one page trigger a component that lives on a different page, then render a result. That is a completely reasonable thing for a web framework to support. It also means a single request carries two page identities: the one that gets drawn, and the one that owns the code being run.
Rapid7's analysis is the clearest published account of what went wrong, and it comes down to one sentence: PaperCut validated access to the page being displayed. Not the page that owned the component. So an attacker names a page that anybody is allowed to see, the Error page or the Exception page, and names an administrative component behind it. The access check looks at "Error", says yes, and then the framework runs the thing attached to ConfigEditor.
POST /app?service=direct/1/Error/ConfigEditor/quickFindForm
POST /app?service=direct/1/Error/ConfigEditor/$Form
POST /app?service=direct/1/Error/UserList/$QuickFind.$Form
Request paths as published by Rapid7 in their emergent threat response. The 1 can be any value, and Error can also be Exception. Nothing here was captured from a run of my own.
Two of those hand an unauthenticated caller the configuration editor. The third triggers a user or card search, which is what makes the next stage go off. Huntress described the same behaviour independently and reproduced the full chain against a stock PaperCut NG 25.0.11.75758, ending with charmap.exe running as SYSTEM under the pc-app.exe process. They picked charmap because it's harmless and obvious, which is a nice touch.
The check wasn't missing and it wasn't weak. It was asking about the wrong object, and a check that names the wrong object is not a control at all.
This is the part I'd want on a review checklist tomorrow. "Is authorisation enforced" is nearly worthless as a question. "Which object does the authorisation decision name, and is that the same object that ends up executing" is the one that would have caught this.
The second name: a JDBC driver class
Now you can write configuration. That on its own sounds like a defacement risk, not a code execution risk, and this is where PaperCut's second bug does the heavy lifting. Four settings are the target:
user-lookup.db-driver
user-lookup.db-url
user-lookup.id-to-username-sql
user-lookup.enabled
The external user lookup settings named by Rapid7. Normally these point PaperCut at a card database an administrator owns.
These exist so an administrator can point PaperCut at an external database of ID cards. Perfectly ordinary feature. The bug, in PaperCut's own words, is that the application "loads database driver classes based on configurable driver names without validating them against an approved allowlist". So the driver name is a class name, the class name comes from configuration, and the configuration is now attacker-controlled. Same shape as the first bug: a name is trusted, and the thing behind the name is never checked.
What Rapid7 documented next is the bit I found genuinely clever, in the way that makes you slightly annoyed. PaperCut ships Apache Derby. Derby has a feature called foreignViews, reachable through a CALL statement, which makes Derby open a second JDBC URL. Point that at H2, and H2 honours an inline INIT clause in its connection string. That INIT creates a database trigger backed by JavaScript. PaperCut also bundles Nashorn, the JavaScript engine that used to ship with the JDK, and from there the trigger starts an operating system process.
Error, Exception or Home in the complex direct URL. The access check reads this one and approves it.
ConfigEditor executes anyway, because nobody checked the component's owner page.
Four settings, a hostile JDBC URL and a hostile SQL statement, written without a login.
A quick find on UserList makes PaperCut connect, and Derby to H2 to Nashorn ends in a process.
Nothing in that chain is a memory corruption trick or a race. It is four features, each behaving as designed, wired together by an attacker who was allowed to choose two strings. I keep coming back to the fact that the "exploit" is a configuration change, and configuration is the category most reviews wave through because you have to be an admin to touch it.
The first emergency patch was bypassed the same day
This is the evidence I'd point at if someone told me I was overreading two unrelated bugs. Patch one blocked the trick as it had been seen: Error and Exception as the displayed page. Rapid7 then reported that the same attack worked with the Home page instead. One name swapped for another name.
That's what fixing the exploit rather than the bug looks like, and I don't say it to sneer at PaperCut, who shipped something within hours of a live incident and then shipped again. Emergency Patch Release 2 landed on 28 August after work with Huntress and watchTowr, covers versions 24, 25 and 26 on Windows, Linux and macOS, and Rapid7 say it correctly remediates the Home page bypass. If you applied Release 1 you are not protected. That surprised me when I read it, and it's the kind of detail that gets lost when a patch lands twice in a day.
Then the honest caveat, which I'd rather put here than bury. watchTowr told The Hacker News that they had found multiple bypasses of the original patches, an additional authentication bypass on top of the two CVEs, and that further patch bypasses affecting the latest fully patched version had been identified. Huntress separately reported a bypass of the first patch set. So the current state is "patched, probably, for now", and the control that doesn't depend on a build number is the network one.
The best argument against me
The strongest counter is that I'm generalising from a framework quirk. Tapestry's complex direct format is unusual, most stacks don't let a request nominate two pages at once, and if you're writing Django or Rails or Spring you can't make this mistake in this exact form. Fair. If the argument is "PaperCut hit a sharp edge specific to their framework", I'd half agree.
But only half, because the shape turns up constantly once you go looking. Authorisation on the route while the handler is reached another way. Authorisation on the controller while a service is callable directly. Authorisation on the URL while the object ID is a parameter, which is just IDOR wearing a hat. Even the Metabase injection was a version of it, where the thing that reached the query builder was not the thing anyone had validated. The second PaperCut CVE has no framework excuse at all, either. Loading a class because someone typed its name into a settings field is a plain missing allowlist, and it lives in the same codebase as the first one.
Where my claim runs out
Two things I want to be straight about. First, I have not run any of this. I've no PaperCut licence and no lab for it, so everything technical above is me reading Rapid7, Huntress, watchTowr and PaperCut's own bulletin carefully and trying not to overstate them. If you've reproduced it and I've got a step in the wrong order, tell me and I'll correct the post.
Second, I might be forcing the pattern. "Trusting a name" is a comfortable frame and comfortable frames make unrelated things look connected. It's possible these are just two separate mistakes that happened to land in the same advisory, and my tidy story is doing more work than the evidence supports. I don't think so, mainly because of how the first patch failed, but I'd hold it loosely.
What to actually do
Patch to Emergency Patch Release 2, even if you applied the first one. Version 23 and older gets no patch at all, and Huntress reported that 47% of the roughly 2,500 PaperCut installations they track are on v23 or older, so for a lot of people this is an upgrade project rather than a patch. Site Servers and secondary print servers need the update too. Print Deploy and Mobility Print don't.
Then take the Application Server off the public internet, firewall it to known ranges or put it behind a VPN, and treat that as the real fix while the patch bypass question stays open. That's the control I'd argue for first, because it survives the next bypass.
For hunting, PaperCut and Huntress have published enough to work with:
Alongside those, look for a server.log that is missing or has been truncated, since the payload Huntress recovered deleted it on the way out. Look for unexpected .class files under server/lib, matching .cmd or .out files under server/data/content, changes to the external user lookup settings, and pc-app.exe spawning shells or discovery tools. Huntress saw base64 blobs in the log that decoded to whoami & ver in one incident and whoami & ver & tasklist in another. The filenames they recovered, Udydn.class and Moo97.class, were five random characters, so match on the shape rather than the string.
server/logs before you restart anything. Then hunt the four signals above, and remember a clean log file is itself a finding.MITRE ATT&CK mapping
- T1190 Exploit Public-Facing Application, the initial access, since the Application Server is the entry point.
- T1059 Command and Scripting Interpreter, the Nashorn trigger starting an operating system process.
- T1082 System Information Discovery and T1057 Process Discovery, matching the
whoami & ver & tasklistHuntress recovered. - T1070.004 Indicator Removal: File Deletion, the payload deleting its own output and
server.log.
References
- Rapid7, PaperCut NG/MF Critical Zero-Day Exploited in the Wild (the technical overview of the chain and the patch bypass)
- Huntress, PaperCut Actively Exploited: A Pre-Auth RCE Chain (John Hammond and Andrew Brandt, incident detail and indicators)
- BleepingComputer, PaperCut releases second emergency patch for exploited flaws
- The Hacker News, Attackers Chain Two PaperCut Flaws to Execute Code Without Authentication (watchTowr on the remaining bypasses)
- Help Net Security, PaperCut NG/MF vulnerabilities exploited in zero-day attacks
FAQ
What are CVE-2026-81578 and CVE-2026-82078?
Two flaws in PaperCut NG and PaperCut MF, disclosed by the vendor on 28 August 2026. CVE-2026-81578 is an improper access control bug in the web management interface, scored CVSS 4.0 8.8. CVE-2026-82078 is unsafe dynamic class loading in the database connection utilities, scored CVSS 4.0 9.4. Chained, they give unauthenticated remote code execution.
Is the PaperCut zero-day being exploited in the wild?
Yes. PaperCut's advisory of 27 August 2026 said it was investigating active exploitation and had confirmed customer incidents. Huntress observed exploitation in two customer environments on 26 and 27 August, where the activity was short and looked like reconnaissance rather than malware deployment or persistence.
Which PaperCut versions are patched?
PaperCut published Emergency Patch Release 2 on 28 August 2026 for PaperCut NG and MF versions 24, 25 and 26 on Windows, Linux and macOS. Release 1 is not enough on its own. Version 23 and older gets no patch at all, so those installations have to be upgraded rather than fixed in place.
Does Emergency Patch Release 2 fully fix the PaperCut chain?
Apply it, but don't treat it as the end. watchTowr told The Hacker News it had found multiple bypasses of the first patch plus an extra authentication bypass, and that further patch bypasses affecting the latest fully patched build had been identified. Restricting network access to the Application Server is the control that doesn't depend on a build number.
How do I check whether my PaperCut server was already hit?
Look for a missing or truncated server.log, the strings "No suitable driver found for jdbc:no:x" and "Database error looking up cardID: VALUES CAST" in server.log, unexpected .class files under server/lib, matching .cmd or .out files under server/data/content, and pc-app.exe spawning command shells.
Related reading
- SharePoint's RCE Chain Just Grew a Fourth CVE (two CVEs that only matter together, same triage trap)
- A JSON Key Metabase Never Asked For Became a CVSS 10 SQL Injection (something reaching the database layer that nobody had validated)
- vCenter Wrote a Log Line Into /etc/cron.d, and Cron Ran It as Root (a feature behaving as designed, used as the exploit)
- Injection attacks explained (the wider family this chain sits in)
- Browse the whole Threats & Exploits track