← All posts
💀Security

Exploit Brokers Pay $300k for WordPress RCEs. I Found One with GPT-5.6 and $25.

Michael Sintim-Koree · July 2026

The going rate for a reliable, unauthenticated WordPress remote code execution on Zerodium's public acquisition page has been reported at $300,000. That number has been sitting there long enough that it doesn't shock anyone in security circles anymore. What should still be uncomfortable is how cheap the discovery side of that equation is getting.

The process described here involved using GPT-5.6 to assist with plugin code review, running up a $25 API bill, and arriving at a working RCE proof of concept in a plugin with over 400,000 active installs. This post is about the process, not the specific vulnerability details, which have been responsibly disclosed and are under coordinated disclosure as of this writing.


Why WordPress plugins are still the right target

WordPress itself is reasonably well-audited. The core team runs a structured security program, patches move fast, and the codebase gets serious scrutiny. The plugin ecosystem is a different story. Over 60,000 plugins live in the official repository, authored by everyone from enterprise software teams to solo developers who haven't touched the code since 2019. Quality variance is enormous, and the attack surface is enormous with it.

The combination that makes a plugin worth targeting: high install count, PHP code that touches file system operations or shell execution, and REST API endpoints or AJAX handlers registered without strict authentication checks. Those three things together appear more often than they should in plugins people are actively running on production sites.

The discovery asymmetry has always existed. A determined researcher with time and expertise could find these. What GPT-5.6 changes, at least in practice, is how much of the expertise requirement drops out of the equation. The workflow described here does not rely on deep PHP specialization; the model carries much of that weight.


What the workflow actually looked like

Automated triage: filtering 60,000 plugins to a shortlist

The first step was identifying candidate plugins. A short Python script pulls plugin metadata from the WordPress.org API, filtering for plugins with active install counts above 100,000 and last-updated dates more than 18 months ago. Stale, widely deployed code is where you look. The script costs nothing and takes twenty minutes to write.

From that list, narrowing by category makes sense: plugins that by nature handle file operations, specifically backup, import/export, media management, and code snippet managers. A plugin that never touches the file system can still have SQL injection or privilege escalation bugs, but for an RCE specifically, you want code that does file writes, runs shell commands, or handles serialized PHP objects. The categories narrow the list substantially.

Prompting GPT-5.6 for data-flow analysis, not general review

The model's job was reading PHP code and flagging patterns that warranted deeper manual investigation. Walking through 40,000 lines of plugin code manually looking for subtle authorization bypasses is slow, error-prone work. The model is not.

The prompting approach mattered. Asking the model to 'find vulnerabilities in this code' produces surface-level responses that flag obvious bad practices without much signal. What works is asking it to trace specific data flows: show me every path from a user-supplied parameter to a file write operation, with the full call chain. For each REST endpoint registered with register_rest_route, list the permission_callback, what parameters it accepts, and what those parameters eventually do. That kind of structured analysis is where the model earns its $25.

The context window capacity of GPT-5.6 is what makes this practical at all. Older models required chunking the codebase, losing cross-file visibility in the process. Loading the relevant plugin files as a single context and asking about data flow across files produces coherent analysis. The model tracked how a parameter moved from a REST handler through three helper functions into a file path construction that didn't sanitize traversal sequences.

The bug: subscriber-level write access with no path sanitization

The vulnerability was a file write reachable from an authenticated REST endpoint, with the authentication check set to a capability that subscriber-level users hold by default. In WordPress's capability model, subscribers are the lowest privileged registered users: someone who creates a free account on a site. The endpoint accepted a filename parameter that was passed into a file path without sanitization, and the file content was user-controlled. Path traversal plus arbitrary write equals arbitrary PHP file placement equals RCE.

The model flagged the permission_callback as 'current_user_can('read')' and noted that read is a capability held by subscribers, then traced the filename parameter through the stack. Verifying the capability mapping against WordPress's user role documentation and confirming the traversal wasn't sanitized with a quick test in a local environment produced a working proof of concept in about two hours of total work after the initial triage.


The economics, stated plainly

Zerodium's $300,000 acquisition price for a WordPress RCE is a market-clearing price. It shows what sophisticated buyers will pay for reliable, unpatched, weaponizable code execution against a platform running an estimated 43% of the public web. The supply side of that market has historically required either specialized PHP security expertise or significant time investment, which kept supply constrained.

GPT-5.6 doesn't have specialized PHP security expertise in the way a human researcher does, but it can read code, trace data flows, and identify patterns that match known vulnerability classes at a speed no human matches. The $25 figure is not a stunt. It covers a substantial volume of input and output tokens across a session spent reading plugin code and getting structured analysis back. At GPT-5.6's pricing tier, that's about right for a few hours of intensive code review.

The skills barrier to finding high-value security vulnerabilities has dropped. Manual verification, exploitation development, and the judgment to distinguish a real finding from a false positive still require human skill. But the reading and pattern-matching work that used to gate entry to this kind of research is now delegable to a language model.


What the model got wrong

About a third of the model's initial flagged issues were not real findings. Two were patterns that looked like unsigned integer operations in isolation but were bounded correctly by the surrounding code. One was a deserialization call the model flagged as dangerous, but the input was serialized internally by WordPress core and never touched user data. The model was correctly identifying patterns that warrant investigation, not correctly identifying exploitable vulnerabilities. That distinction matters a lot.

This is the accuracy ceiling to understand before treating AI-assisted code review as a reliable autonomous scanner. The model surfaces candidates for investigation. It does not replace the human step of verifying whether the flagged code is actually exploitable in the application's real execution context. Someone who treated every model-flagged issue as confirmed would generate a lot of noise and probably start discounting the output entirely, which is how you miss the real finding buried in the list.

The false negatives are harder to characterize. What the model missed cannot be known without a thorough manual audit of the same plugin for comparison. The finding confirmed was real, and the process was fast. What stayed undiscovered is something worth knowing before trusting this workflow on higher-stakes targets.


Responsible disclosure and why it matters more now

The finding was reported to the plugin vendor through their stated security contact and simultaneously to the WordPress Security Team. The vendor responded within 48 hours. A patch is in progress. The disclosure timeline follows the standard 90-day coordinated disclosure model, and no details that would allow exploitation are being published until the patch has been released and sites have had reasonable time to update.

This is worth being explicit about because the economics described above apply equally to people who don't intend to disclose responsibly. A motivated attacker with $25 and access to GPT-5.6 can run the same process. The skill differential between a security researcher who discloses and a threat actor who doesn't has narrowed to primarily intent. The barrier to finding a $300,000 bug is now mostly a decision, not a capability.

The argument for responsible disclosure is not new. What's new is that the barrier to entry for the other path has dropped far enough that the community norm matters more than it did when finding a high-value bug required substantial expertise. More researchers entering this space through AI-assisted workflows need to land on the right side of that decision, and the community that receives those disclosures needs to make the process worth the effort.


What plugin developers should take from this

The specific bug class here is not exotic. Path traversal into a file write is well-documented, has known mitigations, and should not be making it into code that gets 400,000 installs. The capability check being set to 'read' instead of something appropriate like 'manage_options' is either a mistake or a decision made without thinking through what subscriber-level access means on a public site.

  • Every REST endpoint and AJAX handler needs a deliberate capability check. 'read' is not a safe default for anything that modifies state or touches the file system.
  • Any user-supplied string that ends up in a file path needs sanitization for traversal sequences specifically. WordPress provides sanitize_file_name() and realpath() validation patterns. Use them.
  • File write operations should validate that the resolved path sits within an expected directory before writing. Check after path resolution, not before.
  • Plugins that have been in maintenance mode for 18 months with no security review are audit candidates. The cost of an audit is lower than the cost of being the plugin in a public vulnerability disclosure.

The WordPress Security Team has resources for plugin developers, including the Trac security reporting process and documentation on common vulnerability patterns. Both Automattic and the WordPress project run bug bounty programs through HackerOne. If you're a plugin developer who hasn't thought about this recently, now is a reasonable time to start.


Whether the disclosure infrastructure can handle what's coming

The coordinated disclosure model assumes a manageable number of researchers, reasonable vendor response times, and patch cycles that move faster than exploitation. All three of those assumptions start to strain if the supply of valid findings increases sharply. The infrastructure is unlikely to be ready for that.

The bug bounty ecosystem partially absorbs this: channeling findings through programs that have established triage capacity and defined payout structures. But not every plugin vendor has a bug bounty program. Many don't have a security contact at all. The WordPress Security Team fills some of that gap for the .org repository, but the capacity question is real. More findings per month means either faster patch cycles (good) or longer queues before disclosure timelines expire (bad, because the clock runs regardless of whether the vendor has responded). The 90-day timer starts the day of submission. The vendor's resource constraints don't pause it.

The offensive side of this doesn't wait for the defensive infrastructure to catch up. Exploit brokers aren't going to lower their acquisition prices because AI assistance made finding the bugs cheaper. The value is in the deployment, not the discovery. What changes is who can participate in the discovery, and that change is already underway.


If you're doing AI-assisted vulnerability research and have worked out how to handle disclosure timelines when vendors go quiet, specifically what you do when the 90-day clock is running and you've had one response in six weeks, I'd genuinely like to hear how you've structured it. That's the part of this workflow that remains unsolved.