Back to Blog

Proxmox VE 7: the patch had been out for three years and nobody knew it was a patch

Two old rack servers lying flat on a metal shelf in a storage room, still powered and cabled, among cardboard boxes and a mop

Picture a doorman who asks for your ID and then, when you say "don't worry, I have the second document too", stops asking for the first one. He never checks the second one either. Merely mentioning it makes him forget the other. That is, literally, what the Proxmox VE 7 login did: sending a tfa-challenge parameter with any value at all was enough to log in as root@pam with no password. The code that fixes it shipped on 20 July 2023. The advisory arrived on 1 September 2026, three years and six weeks later, when somebody found their node encrypted.

What the flaw does, plainly

Proxmox VE authentication goes through a single call: POST /api2/json/access/ticket. That is where the username, the password and, where applicable, the second factor travel, the latter in the tfa-challenge parameter. In the affected versions, for accounts without a second factor configured that parameter was never validated — there was nothing to compare it against — and, on top of that, its mere presence caused the password check to be skipped. It is not that the password was validated badly: it was never looked at.

The result is unauthenticated access that turns an attacker into any existing, enabled user with no second factor, root@pam included. The vulnerable package is libpve-access-control from version 7.0-7 up to but not including 8.0.4; the advisory translates that to Proxmox VE 7.0 to 7.4, and the CVE record extends the range to the initial 8.0. The CVE is CVE-2023-54391 and the same assigner gives it 9.8 on CVSS 3.1 and 9.3 on CVSS 4.0, with the full network vector, no prior privileges and no user interaction.

The only requirement to exploit it is reaching the API. By default, port 8006. Anyone who has it published on the internet has an open door with a sign on it.

A second factor saved you, and not for the reason you think

Here is the detail that inverts the intuition. The parameter that opened the door was the second-factor one, but the advisory is categorical: "users with any second factor configured for login are not affected". On those accounts the tfa-challenge is a ticket signed by the server itself and its signature was genuinely verified — exactly the check that the Proxmox patch reinstates. The vulnerability lived precisely in the gap left by accounts that had none.

With one caveat worth keeping in view: it protected each account that had it, not the node. A single enabled user without a second factor — a service account, a monitoring account, the one you created for an integration and never deleted — was enough to keep the door open.

We like this case because it settles an argument we have every few months, when someone asks whether it is worth putting a second factor on root@pam of a hypervisor "that is only touched from inside". The usual argument is password theft, and it is the weakest one. The good one is this: a second factor is one more condition the code has to evaluate, and every extra condition is one fewer branch to slip through. Here it ended up protecting against a logic flaw nobody had spotted. By accident, which counts too.

Three years between the fix and the advisory

What makes this more than just another CVE is the chronology, and it is not us telling it: it is in the advisory. The vulnerable code ceased to exist on 20 July 2023, in libpve-access-control 8.0.4, as a side effect of a rework of the second-factor configuration handling. Nobody labelled it a security fix because nobody realised it was one, and so — quoting the advisory directly — "it was therefore not recognized as a candidate for a backport to the PVE 7 branch", which at that point was still supported. The two commits from those days talk about reading tfa.cfg and about the x marker in user.cfg. Neither mentions passwords.

That breaks the mental model most of us manage patches by: a serious flaw gets discovered, assigned a CVE, fixed, and the fix flows down to every live branch. Here the order was reversed. And in between, the 7 branch reached end of life in July 2024 — per the project's own lifecycle table, aligned with Debian 11 "Bullseye" — so by the time the advisory came out there was nobody left under any obligation to fix it.

We already wrote about the other side of this when it was the 8 branch's turn: Debian keeps patching you, the hypervisor does not. That post was about a date that passes without anything breaking. This one is about the day, months or years later, when the absence of a maintainer collects the whole bill at once.

How everyone found out: through a forum thread

The sequence says something too. On 31 August a user opened the thread that put the problem on the map: their VE 7 installation had turned up encrypted, with a ransom demand and the logs wiped. He himself pointed to an earlier complaint, in Chinese, from the day before. Within hours others came forward with the same picture. On 1 September Proxmox published advisory PSA-2026-00043-1, "Authentication bypass in EOL Proxmox VE 7 release", explaining that it had learned of the problem through "many independent reports within the last two days" which also reported exploitation in the wild. Shortly afterwards a proof of concept appeared publicly.

The discovery, then, came from the victims. When the first detection channel for a vulnerability is the support forum, the window between "somebody is using this" and "you find out" has already been open for a stretch of time nobody can measure.

What can be claimed and what cannot

It is worth separating three levels of certainty, because right now they are getting mixed up:

  • The flaw and the affected versions are vendor-confirmed. That is not up for debate: the advisory says so.
  • Active exploitation is asserted by Proxmox based on the reports it received. CISA, on the other hand, has not added it to its KEV catalogue: we checked the source file, version 2026.09.02, and neither CVE-2023-54391 nor any other Proxmox entry appears there. That is not a contradiction: they are two different evidence thresholds, and CISA's is the slower one. Absence from KEV does not mean it is not happening.
  • The indicators of compromise going around come from the community, not from the advisory: a /var/lib/systemd/PVE-1 file that turned out to be the miner, the system logs (auth.log, wtmp, btmp, lastlog, secure) replaced with symlinks to /dev/null, and outbound connections to a Monero mining pool. We find them plausible and worth hunting for, but they should be treated as what they are: reports from affected users, not an official list.

What to check today, in this order

  1. Look at the package version. dpkg -l libpve-access-control. If the number falls between 7.0-7 and 8.0.3, that node is exploitable. Watch out for the "lower than 8.0.4" shortcut: a PVE 6 box on 6.4-x gives a lower number and sits outside the affected range. pveversion gives you the branch, which helps, but the deciding figure is in the package.
  2. Who can reach 8006. ss -tlnp | grep 8006 tells you it is listening; what matters is where it is reachable from. Test it from outside your network, not from the office. If it answers from the internet, cutting that off comes first, before anything else on this list.
  3. The log, with a caveat. In /var/log/pveproxy/access.log you will see the POST /api2/json/access/ticket requests and their source IP, but not the parameter: it travels in the body, and pveproxy records the request line Apache-style, not request bodies. Look there for access from addresses you do not recognise. And also run ls -l /var/log/: in the reported cases auth.log, wtmp, btmp, lastlog and secure had been replaced with symlinks to /dev/null. If any of them is, that is already an answer.
  4. Users and tokens you did not create. pveum user list and, for each account, pveum user token list <user>@<realm> — for example, pveum user token list root@pam. An API token created by the attacker survives a password change and an upgrade. It is the leftover most often missed.
  5. The backups, before touching anything. If the node is compromised and has to be rebuilt, the first thing you need to know is whether the backups are reachable from that same node. If they are, assume the attacker reached them too.

That last point is not rhetorical. In the 2026 ransomware report we picked apart why restoring is not the same as recovering, and the order of operations matters: preserve logs and disks before reinstalling, because once it is wiped there is no way left to know what was taken.

The emergency patch, and why we would handle it with tongs

Proxmox publishes a stopgap in the advisory itself: a sed against /usr/share/perl5/PVE/AccessControl.pm that reinstates the second-factor ticket check, followed by a restart of pvedaemon and pveproxy. It is the vendor's, not a forum hack, and on a node you cannot upgrade today it does its job. But anyone applying it should be clear on three things: it is a local modification to a packaged file, one that does not live under /etc, so any reinstall or branch jump overwrites it without asking; and it does nothing about the other fixes the 7 branch has gone without since July 2024.

Our order would be this: first close 8006 to the internet, which takes minutes and removes the vector; then verify whether the node is already compromised; and only then plan the branch upgrade. The sed fits in the gap between the second step and the third, not in place of either. And if you land on 9, the next step is making it decent: we wrote that up in full in hardening Proxmox 9.2 in production.

What this case says about your inventory

We build and maintain this kind of infrastructure, so let us say the uncomfortable part. Nobody leaves a hypervisor untouched for five years out of laziness. They leave it because it works, because inside it there are three virtual machines that cannot be stopped, because the person who built it has left, or because every time the subject comes up someone asks what it costs and the conversation ends there. That node is in nobody's plan precisely because it gives no trouble.

It is the same pattern we described in exposed BMCs and IPMIs, the computer nobody maintains: the component that never shows up in the inventory because it never raises a ticket. And it is where we keep hammering on an idea we repeat to the point of tedium: failure is inevitable, an outage is a design decision. You did not decide that a login written in 2021 had a logic flaw. That the flaw reached production three years after being fixed, with the interface published on the internet and no second factor on root@pam, is a chain of decisions. Every one of them reasonable in isolation. None of them ever reviewed together.

The short version

Log into each node and run dpkg -l libpve-access-control. If a number between 7.0-7 and 8.0.3 comes back, that is work for this morning. Then check from outside whether 8006 answers. With those two answers you already know whether this is a maintenance task or an incident.

And if the number comes back fine, use the scare to ask the question that actually matters, which is not about this CVE: how many machines do you have running whose version you could not state without logging in to look? Those are the ones that will show up in the next advisory.

Sources (consulted on 4 September 2026): the primary source is advisory PSA-2026-00043-1, "Authentication bypass in EOL Proxmox VE 7 release", dated 1 September 2026, published in the Proxmox VE security advisories thread. From it come, verbatim: the libpve-access-control range (7.0-7 to before 8.0.4) and its translation to "Proxmox VE 7.0 through 7.4"; that the parameter's presence "caused the verification of the submitted password to be skipped entirely"; that "users with any second factor configured for login are not affected"; that the flaw was "closed in libpve-access-control 8.0.4 (released 2023-07-20)" as "a side effect of a rework of the TFA configuration handling" and that "it was therefore not recognized as a candidate for a backport to the PVE 7 branch"; the "many independent reports within the last two days" with exploitation in the wild; and the stopgap sed against AccessControl.pm plus the restart of pvedaemon and pveproxy. The user thread from 31 August is Proxmox VE 7 is vulnerable to some type of 0day/RCE non auth. The public proof of concept and the exploitation summary — securityonline.info. The indicators of compromise (/var/lib/systemd/PVE-1, system logs symlinked to /dev/null and the mining pool) come only from the prepaid-host analysis of reported cases. CVSS 3.1 score of 9.8 and CVSS 4.0 score of 9.3, both from the same assigner, and the vector AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H — the CVE record and IONIX Threat Center. That CVE-2023-54391 does not appear in CISA's KEV catalogue we checked ourselves by downloading known_exploited_vulnerabilities.json from cisa.gov, catalogue version 2026.09.02: neither that entry nor any other Proxmox entry is in it; BlackTree notes the same. Proxmox VE 7 end of life in July 2024, aligned with Debian 11 "Bullseye" — Proxmox VE support lifecycle table. Important qualifier: the indicators of compromise are not in the official advisory; use them as leads, not as a verdict.

Do you know what version every one of your nodes is on?

We run Proxmox VE with Ceph storage in production across several datacentres, and we have worked with Proxmox since the 3.x branches. What this trade has taught us is that the node worth worrying about is rarely the one giving trouble. Reviewing what you have exposed, what version it runs and what would happen if someone got in is cybersecurity; making sure that review does not depend on somebody remembering is IT maintenance. And if what sits underneath calls for a new branch, that is infrastructure and cloud.

Let's talk

Tags:

Share:

Subscribe to our newsletter

To receive IT stories, everyWAN news and exclusive subscriber offers, sign up to our mailing list

Minorisa de Sistemas Informaticos y Gestión S.L. © 2026
everyWAN
everyWAN