One bug, three plugins
WPScan published a CVE of mine today. It covers three plugins.
| CVE | Plugins | Class | Fixed in |
|---|---|---|---|
| CVE-2026-85081 | WP File Manager, FileOrganizer, Filester | DOM-based cross-site scripting via postMessage origin bypass. CVSS 7.5 | 8.0.5, 1.2.1, 2.1.3 |
Three rows in the fixed-in column, because it's one defect in one piece of code that three different plugins each carry a copy of.
The coordinating body withholds proof-of-concept detail on this one until the twenty-fourth of October, so that sites have time to update. I don't publish proofs of concept for anything, ever, so that date changes nothing about what I'd have written. But it does mean this post stays at the altitude the advisory itself uses, and I'm not going to go further into the mechanism than the published page does.
The same code, three times
None of these three plugins wrote the vulnerable code. They all bundle the same open-source file manager component, the way plugins routinely bundle a library rather than depend on one, because WordPress has no mechanism for shared dependencies between plugins. Each plugin ships its own copy, inside its own directory, on its own release schedule.
So a defect in that component isn't one plugin's problem. It's a defect in every plugin that vendored a copy before the fix existed, and nothing in the WordPress ecosystem tracks that they're related. There's no shared manifest, no version to pin, no update channel that reaches all of them at once. From the outside they're unrelated plugins by unrelated authors that happen to do similar things. Where the relationship gets recorded at all, it's after the fact, in an advisory written by somebody who noticed — which is what this one is.
I found it in one of them and then checked the others I could account for, which is why this record covers three and not one.
The part that surprised me is that containing the component and being exposed by it are different questions, and only the second one matters. Another plugin carried the same component with the same weakness sitting in the file, and it wasn't reachable there — the vendor's own code replaced the relevant behaviour before anything could reach it. That took considerably longer to establish than finding the copy did, and the answer was that there was nothing to report. Three is what survived that second question, not a count of who ships the library.
I want to be careful about the install numbers here, because this is exactly where a post like this overreaches. WordPress.org reports the three at over a million active installs between them, most of that in one of the three. That number is the size of the population carrying the component. It is not the number of sites that were exploitable, which I don't know and can't measure, and the advisory makes no claim about either. I'm quoting it because the multiplication is the point of this post, not because it's an impact figure.
Fifteen days between the first fix and the last
Here's the part I didn't expect, and it's the reason I wanted to write this up.
The three vendors shipped on their own schedules:
| Plugin | Fixed in | Released |
|---|---|---|
| Filester | 2.1.3 | 7 September |
| FileOrganizer | 1.2.1 | 8 September |
| WP File Manager | 8.0.5 | 22 September |
Two of them within a day of each other, on the 7th and the 8th. The third on the 22nd.
One CVE covers all three, and it didn't publish until the last of them shipped. For those fifteen days the identifier existed but was reserved. Nothing in MITRE, nothing in the national vulnerability database. I checked both directly on the afternoon of the day it published and both still returned nothing. The advisory page itself I had only through a cached listing less than a day old, which corroborates that and does not settle it.
So the cost of the spread wasn't a public record saying the wrong thing. It was fifteen days in which the record said nothing at all, while two of the three plugins were already patched and those fixes were sitting in public vendor releases for anyone who went looking. I sent the venue updated version information once during that window — nine days after the first fix shipped, not the day of it — and a final correction once the last vendor moved.
I don't know whether the two things were linked. I watched a sequence: first vendor patches, second patches, third patches fifteen days later, the record moves to scheduled disclosure the next day, and the advisory publishes the day after that. A sequence is not a mechanism. Nobody told me the disclosure was being held for the last vendor, and I'm not going to claim it was because the shape fits.
What it changed for me is smaller than a fix. I now send the fixed-in column as a correction each time a vendor ships, rather than once at the end. On a single-plugin record that's pedantry. On a record carrying three independent release schedules it's the only way that field is ever right.
The version number said it was still vulnerable
The last vendor's fix had a wrinkle worth recording, and it's about verifying a patch rather than exploiting a bug.
The fix is in the copy they ship, and the copy is otherwise where it was. The file that stamps the component's version is byte-for-byte identical across the two releases and still reports the number it reported before the fix.
So checking the bundled component's own version string, rather than the plugin's, returns the wrong answer here. It reports a patched plugin as vulnerable. Any scanner keying on that string gets it wrong, in the direction that generates a false alarm rather than a missed one, which is the less damaging direction but still wrong.
I only know this because I read the two releases against each other rather than trusting the version string, and I'd like to claim that was foresight. It wasn't. I had a habit of checking the fixed-in version in code before telling a venue it was fixed, and the habit caught something the habit wasn't designed for.
The general form is one I keep relearning. A version number is a claim a vendor makes about their code. It's evidence, and it's weaker evidence than the code, and when the two disagree the code wins.
What this one paid
Nothing, and that's not a complaint.
This went to a venue that assigns identifiers and pays nothing at all. The bug needed a precondition that made it out of scope for the programme that does pay, and I'd rather state that plainly than imply a payout I didn't get. This defect is closed in all three releases, the record is public, and the fixed-in versions on it are right for all three. That's the whole return, and it was worth having.
What I'd tell anyone running one of these three: this defect is closed in the versions in the table above, and I read all three releases to confirm it. That is a claim about one bug in one bundled component, not a clean bill of health for the plugin. I didn't audit the rest of any of them, and I'm not going to let a fixed CVE stand in for a review I didn't do.
And if you maintain a plugin that bundles somebody else's component, the useful question isn't whether your code has a bug in it. It's whether you'd find out when the thing you copied does.
This work uses large language models throughout the toolchain, including in drafting this post. Every finding is checked by hand against the source before anything is submitted. The finding was reported through WPScan, who coordinated disclosure and assigned the identifier. The three fix releases were read directly from each vendor's published source.