CVE-2026-7654: Admin Columns WordPress Plugin Vulnerability
| Field | Value |
|---|---|
| CVE ID | CVE-2026-7654 |
| CVSS score | 8.8 (High) |
| Attack vector | Unknown from retrieved NVD data |
| Auth required | Yes, Contributor-level access or higher |
| Patch status | Patch likely available in 7.0.19; explicit vendor security confirmation was not retrieved |
TL;DR - High-severity authenticated RCE in Admin Columns for WordPress. - Affects versions up to and including 7.0.18; upgrade to 7.0.19 or later. - No CISA-confirmed in-the-wild exploitation and no verified public PoC from collected evidence.
What This Vulnerability Is and Why It Matters
CVE-2026-7654 is a high-severity vulnerability in the Admin Columns WordPress plugin from Codepress. According to the NVD description, the issue is a PHP Object Injection bug that can lead to remote code execution when an authenticated attacker abuses unsafe deserialization in the plugin. The vulnerable code path reportedly uses unserialize() without an allowed_classes restriction inside IdsToCollection::get_ids_from_string(), and it processes attacker-controlled post meta values without proper validation.
For defenders, the important part is not just that this is deserialization, but that the impact is RCE as the web server user. In practical terms, that can allow code execution in the WordPress application context, which may lead to full site compromise, credential theft, web shell deployment, data manipulation, or pivoting into adjacent systems depending on hosting architecture. This is not an internet-wide unauthenticated wormable issue, but it is still serious for any WordPress environment where lower-privileged content authors, contractors, or compromised user accounts exist.
The attack precondition also matters. NVD states exploitation requires authenticated access with Contributor-level privileges or above. That means the risk is especially relevant for sites that allow many non-admin logins, multi-author publishing, community publishing workflows, or environments where role assignment is loosely governed. If you run a small brochure site with only one tightly controlled admin account, your exposure is lower than a news, education, or membership site with many contributors, but the severity remains high because the end state is code execution.
The affected versions are stated as “up to and including 7.0.18.” Based on WordPress.org version metadata, 7.0.19 exists and is the likely fixed version, but the fetched source set did not include an explicit vendor bulletin stating “7.0.19 fixes CVE-2026-7654.” Defenders should still treat 7.0.19 or later as the remediation target because it is the first version observed after the vulnerable range ended.
Affected Versions and Exposure Assessment
The affected product is the Admin Columns plugin for WordPress, plugin slug codepress-admin-columns. The vulnerable range, based on the NVD description, is all versions up to and including 7.0.18. That means if your environment is running 7.0.18, 7.0.17, or any earlier release in the branch, you should treat it as exposed until you validate otherwise.
The fixed version is likely 7.0.19. That wording is deliberate. The evidence confirms that version 7.0.19 is published on WordPress.org and that the vulnerable range ends at 7.0.18, but the retrieved vendor content did not explicitly say “security fix for CVE-2026-7654.” In security operations, that is enough to justify patching, but not enough to overstate vendor confirmation. If you need strict change-control documentation, record the caveat in your ticket: “7.0.19 appears to be the first non-vulnerable version based on available metadata; direct vendor security advisory not retrieved.”
A quick way to assess exposure is to inventory the plugin across all WordPress instances, including forgotten staging systems, low-traffic microsites, and customer-managed subdomains. WordPress plugin risk is often not concentrated on primary production sites alone. Old admin utilities, cloned environments, and abandoned content sites tend to lag patching and are commonly overlooked. If Contributor accounts exist on any of those instances, this vulnerability becomes operationally relevant.
Where version discovery is incomplete, assume the worst until verified. If your asset inventory cannot reliably tell you whether Admin Columns is installed, you should check directly on disk or through WP-CLI. In the absence of central data, defenders should assume that any WordPress site with the plugin present and version <= 7.0.18 is vulnerable.
Technical Notes
Use WP-CLI to identify the installed version:
wp plugin list --format=table | grep codepress-admin-columns
Check the plugin version from its header on disk:
grep -E "Version:" /var/www/html/wp-content/plugins/codepress-admin-columns/codepress-admin-columns.php
Find WordPress installs that have the plugin deployed:
find /var/www -type d -path "*/wp-content/plugins/codepress-admin-columns" 2>/dev/null
Exploitation Status, PoC Status, and Threat Reality
At the time of writing, exploitation in the wild is not confirmed from the provided primary-source evidence. Specifically, CVE-2026-7654 is not listed in CISA’s Known Exploited Vulnerabilities catalog, so there is no CISA-backed confirmation of active exploitation. That does not mean exploitation is impossible or absent; it means defenders should avoid claiming confirmed in-the-wild abuse without stronger evidence.
Likewise, a public PoC was not verified from the collected research set. Search-derived references surfaced aggregation pages, but no authoritative GitHub PoC or primary exploit publication for this exact CVE was confirmed. So the correct statement is: no verified public PoC is known from the collected evidence. Do not translate that into “safe to defer.” Authenticated WordPress RCEs often become reproducible quickly once root cause details are public, especially when the issue involves a straightforward unserialize() misuse and referenced code locations are known.
The absence of a KEV entry and the absence of a verified public PoC should affect prioritization only slightly, not fundamentally. Because this flaw yields RCE and only requires Contributor-level privileges, it is still a strong candidate for expedited patching. In environments where contributor accounts are internet-accessible, where account takeover risk is non-trivial, or where multiple users manage content, the practical exploitability can still be high even without broad public weaponization.
If you need a conservative planning assumption, use this: treat the vulnerability as exploit-ready by any attacker who can obtain or create a Contributor-level account, or who can compromise one through credential reuse, phishing, or another WordPress weakness. That assumption is operationally safer than waiting for public exploit telemetry.
Technical Root Cause
The root cause described by NVD is unsafe PHP deserialization. The plugin reportedly uses unserialize() without the allowed_classes restriction in IdsToCollection::get_ids_from_string(), while handling attacker-controlled post meta values. In PHP applications, this is dangerous because deserializing untrusted data can instantiate attacker-chosen objects and trigger magic methods during object lifecycle events. If a usable gadget chain is present, the result can be code execution, file writes, or other dangerous side effects.
In this case, the available references also point to bundled Laravel Serializable Closure components, which suggests a POP gadget chain is involved in reaching code execution. That is consistent with the NVD statement that the issue can be exploited via a bundled POP gadget chain. Direct retrieval of the referenced WordPress Trac source URLs was not possible in this environment due to HTTP 403 responses, so defenders should rely on the NVD description and linked file paths rather than claiming direct source review here.
The practical lesson for defenders and developers is broader than this single CVE. Any plugin or PHP application that deserializes user-controlled data without strict constraints should be treated as a high-risk code pattern. Even when the initial input seems limited to “metadata” or “custom fields,” deserialization vulnerabilities often become severe because the application or its dependencies already contain the classes needed to form a gadget chain.
Technical Notes
Referenced code locations from the CVE research set include:
classes/Formatter/IdsToCollection.php
classes/Formatter/Meta.php
vendor/laravel/serializable-closure/src/Serializers/Native.php
vendor/laravel/serializable-closure/src/Support/ClosureStream.php
Safer PHP deserialization pattern, where unavoidable:
$data = unserialize($input, ['allowed_classes' => false]);
Best practice is to avoid unserialize() on untrusted input entirely and prefer formats like JSON with strict schema validation.
What Defenders Should Do Next
If you run WordPress at scale, the immediate task is straightforward: find every instance of Admin Columns, identify versions, and upgrade any installation at 7.0.18 or earlier. Prioritize systems with many authors, guest contributors, external content teams, or weak identity controls. Those environments align most closely with the stated privilege requirement.
Next, decide whether you need threat hunting. If the plugin was exposed and Contributor-level accounts existed, check logs, recent post meta activity, and file integrity. If you find suspicious indicators or cannot rule out compromise, move into formal incident response and preserve evidence before cleaning up. For SMB operators without deep telemetry, at minimum review user accounts, new admin creation, plugin/theme file changes, unexpected scheduled tasks, and outbound connections from the web server.
Finally, document the uncertainty correctly. There is no confirmed CISA KEV exploitation, no verified public PoC from the collected evidence, and the fix version is strongly indicated as 7.0.19 but not explicitly vendor-confirmed in the fetched content. That does not weaken the remediation case. It just keeps the advisory accurate, which matters when security teams are making patch decisions under scrutiny.
Detection and Incident Response Guidance
Detection is tricky because the core abuse path involves malicious post meta content rather than a clean, single HTTP signature with a stable URI. The NVD description says the vulnerable function processes attacker-controlled post meta values, so defenders should focus on a combination of indicators: unusual requests to post editing endpoints by Contributor-level users, suspicious serialized PHP object strings in form submissions, plugin file changes, unexpected PHP execution artifacts, and downstream actions such as dropped files or new admin users.
A useful first step is to review who has Contributor or higher access in affected sites and correlate that with recent content edits, custom field updates, and login anomalies. On many WordPress deployments, Contributors normally create drafts and limited edits, not complex custom meta updates with long serialized payloads. That makes serialized object markers in POST bodies or application logs worth triaging. You should also inspect web root and upload directories for new PHP files, unauthorized cron entries, modified .htaccess rules, and suspicious outbound network connections from the web server after plugin-related activity.
Because direct exploit telemetry is limited, defenders should broaden the response scope beyond just the vulnerable plugin. If you suspect exploitation, assume possible post-exploitation as the web server user. That means reviewing persistence, web shells, plugin/theme modifications, database changes, and new privileged WordPress accounts. If the server is shared, examine whether the compromise could have reached other vhosts or credentials stored in configuration files.
Technical Notes
Look for suspicious serialized object patterns in web logs or reverse proxy captures. PHP serialized objects often begin with O: and may appear in POST bodies tied to content editing workflows.
Example grep against request captures or WAF logs:
grep -R -E 'O:[0-9]+:"[A-Za-z0-9_\]+' /var/log/nginx /var/log/apache2 /var/log/modsec 2>/dev/null
Example generic log pattern to investigate:
POST /wp-admin/post.php
POST /wp-admin/admin-ajax.php
POST /wp-json/
request body contains: O: or C: followed by quoted class name
user role involved: contributor
Example Sigma-style idea for web logs:
title: WordPress Serialized Object Pattern in Admin Request
logsource:
category: webserver
detection:
selection_uri:
cs-uri-stem|contains:
- "/wp-admin/post.php"
- "/wp-admin/admin-ajax.php"
selection_body:
request_body|re: '(^|[&=])[^=]*(O|C):[0-9]+:"[^"]+"'
condition: selection_uri and selection_body
level: high
If you have database access and want to hunt for suspicious meta values:
SELECT post_id, meta_key, LEFT(meta_value, 200) AS sample
FROM wp_postmeta
WHERE meta_value REGEXP '(^|;)O:[0-9]+:"'
LIMIT 50;
This query is only a hunt aid. Serialized data may be legitimate in some plugins, so treat results as triage leads, not proof of exploitation.
Mitigation and Patching
The primary mitigation is to upgrade Admin Columns to 7.0.19 or later. Since the vulnerable range is explicitly up to and including 7.0.18, and 7.0.19 is the next observed release, that is the practical remediation target. Even though an explicit vendor advisory was not retrieved in the source set, upgrading beyond the known vulnerable range is the most defensible action.
If you cannot patch immediately, reduce exposure by tightening access to WordPress roles that meet the stated precondition. Specifically, review and temporarily minimize Contributor and higher accounts, disable unused users, enforce MFA if your environment supports it, restrict access to admin endpoints by IP where feasible, and watch for suspicious post editing or custom-field activity. This is a compensating control, not a substitute for upgrade, because the vulnerability remains reachable to any authenticated attacker who retains the required role.
You should also consider short-term hardening around custom fields and plugin usage. If Admin Columns is not business-critical, temporarily disabling the plugin may be justified until patch validation is complete. In regulated or high-sensitivity environments, the safest path is usually: snapshot, upgrade, validate content workflows, then audit for signs of prior abuse. If compromise is suspected, patching alone is not enough; perform incident response before declaring the host clean.
Technical Notes
Upgrade with WP-CLI:
wp plugin update codepress-admin-columns --version=7.0.19
Or update to the latest available version:
wp plugin update codepress-admin-columns
Verify the result:
wp plugin get codepress-admin-columns --field=version
Temporary workaround by deactivating the plugin:
wp plugin deactivate codepress-admin-columns
If WP-CLI is unavailable, remove Contributor exposure as a temporary control by auditing roles and disabling unneeded accounts through WordPress admin or SQL-backed admin processes. If you must use a database query for emergency review, first back up the database and validate table prefixing:
SELECT ID, user_login
FROM wp_users
WHERE ID IN (
SELECT user_id
FROM wp_usermeta
WHERE meta_key = 'wp_capabilities'
AND meta_value LIKE '%contributor%'
);
References
| Source | URL |
|---|---|
| WordPress.org plugin page | https://wordpress.org/plugins/codepress-admin-columns/ |
| WordPress.org markdown view | https://wordpress.org/plugins/codepress-admin-columns/?output_format=md |
| Vendor changelog | https://www.admincolumns.com/changelog/ |
| Wordfence advisory page | https://www.wordfence.com/threat-intel/vulnerabilities/wordpress-plugins/codepress-admin-columns/admin-columns-7018-authenticated-contributor-php-object-injection-to-remote-code-execution-via-custom-field-meta-value |
| NVD-linked code reference | https://plugins.trac.wordpress.org/browser/codepress-admin-columns/tags/7.0.16/classes/Formatter/IdsToCollection.php#L42 |
| NVD-linked code reference | https://plugins.trac.wordpress.org/browser/codepress-admin-columns/tags/7.0.16/classes/Formatter/Meta.php#L34 |
| GitHub repository | https://github.com/codepress/admin-columns |
| GitHub releases | https://github.com/codepress/admin-columns/releases |
For enhanced security while using WordPress, consider using a VPN service like NordVPN or Surfshark to protect your data. Additionally, using security tools like Malwarebytes can help safeguard your site from vulnerabilities.
This article may contain affiliate links. We earn a commission on qualifying purchases at no extra cost to you.