CVE-2025-69361
Executive Summary
CVE-2025-69361 is a Missing Authorization vulnerability in the PublishPress Post Expirator WordPress plugin, affecting versions from n/a through 4.9.3. This flaw allows an authenticated attacker with low privileges to exploit incorrectly configured access control security levels, potentially leading to unauthorized access to scheduled post expiration settings or actions. The vulnerability has a CVSS score of 4.3 (Medium) and an EPSS score of 0.0%, indicating low exploitation likelihood in the wild. No public proof-of-concept or exploit code is available at this time.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
WordPress Ecosystem Context
This vulnerability is specific to the WordPress plugin ecosystem, not the underlying web server (Apache/Nginx). The issue lies in the plugin's failure to properly enforce authorization checks on certain administrative actions, allowing users with minimal permissions to interact with expiration-related functionality.
CVSS Breakdown & Threat Level
- CVSS Score: 4.3 (Medium)
- Vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N
- Attack Vector: Network
- Attack Complexity: Low
- Privileges Required: Low (authenticated user)
- User Interaction: None
- Scope: Unchanged
- Confidentiality Impact: Low
- Integrity Impact: None
- Availability Impact: None
Threat Level: Medium. While the impact is limited to low confidentiality breach, the low attack complexity and lack of user interaction make it exploitable by any authenticated user.
Deep Dive & Mechanics
The vulnerability resides in the Post Expirator plugin's AJAX handlers and admin pages. The plugin fails to perform proper capability checks (e.g., manage_options or edit_posts) before allowing modifications to expiration schedules. An attacker with subscriber-level or contributor-level access can:
- Enumerate expiration settings for posts/pages.
- Modify expiration dates or disable expiration for content they do not own.
- Potentially view metadata about scheduled expirations.
The core issue is a Missing Authorization (CWE-862) in functions like expirationdate_save_meta or expirationdate_ajax_handler, which do not verify the user's role before processing requests.
Vulnerable vs. Patched Code
Vulnerable Code (<= 4.9.3):
// In post-expirator.php or similar
add_action('wp_ajax_expirationdate_save_meta', 'expirationdate_save_meta_callback');
function expirationdate_save_meta_callback() {
// No capability check
$post_id = intval($_POST['post_id']);
$expire = sanitize_text_field($_POST['expiration']);
update_post_meta($post_id, '_expiration-date', $expire);
wp_die();
}
Patched Code (Hypothetical Fix):
add_action('wp_ajax_expirationdate_save_meta', 'expirationdate_save_meta_callback');
function expirationdate_save_meta_callback() {
// Check if user can edit the specific post
if (!current_user_can('edit_post', intval($_POST['post_id']))) {
wp_die('Unauthorized', 403);
}
$post_id = intval($_POST['post_id']);
$expire = sanitize_text_field($_POST['expiration']);
update_post_meta($post_id, '_expiration-date', $expire);
wp_die();
}
Exploitation & Lab Setup
Red Team
Prerequisites:
- WordPress instance with Post Expirator <= 4.9.3 installed.
- Low-privilege account (e.g., subscriber).
Exploitation Steps:
- Log in as a subscriber.
- Craft a POST request to
/wp-admin/admin-ajax.phpwith actionexpirationdate_save_metaand a target post ID. - Modify expiration date without proper authorization.
Example cURL:
curl -X POST http://target/wp-admin/admin-ajax.php \
-d "action=expirationdate_save_meta&post_id=123&expiration=2025-12-31 23:59:59" \
--cookie "wordpress_logged_in_xxx=..."
Blue Team
Detection:
- Monitor AJAX requests to
admin-ajax.phpwith actionexpirationdate_save_metafrom low-privilege users. - Alert on unauthorized modification of
_expiration-datepost meta.
Hunting:
- Query database for posts where
_expiration-datewas modified by non-admin users. - Review WordPress audit logs (if available) for suspicious AJAX calls.
Indicators of Compromise (IOCs)
- Network: POST requests to
/wp-admin/admin-ajax.phpwithaction=expirationdate_save_metafrom non-admin IPs. - Host: Modified
_expiration-datemeta values inwp_postmetatable. - Logs: WordPress debug logs showing
wp_ajax_expirationdate_save_metacalls from unexpected user roles.
Detection Engineering
YARA Rule
rule CVE_2025_69361_WordPress_Plugin {
meta:
description = "Detects Post Expirator plugin files with missing authorization"
author = "Valters IT"
date = "2025-04-01"
cve = "CVE-2025-69361"
strings:
$ajax_handler = "expirationdate_save_meta" nocase
$missing_check = "current_user_can" nocase
condition:
$ajax_handler and not $missing_check
}
Sigma Rule
title: CVE-2025-69361 - Post Expirator Missing Authorization
id: 8a4b3c2d-1e5f-4a7b-9c8d-0e1f2a3b4c5d
status: experimental
description: Detects unauthorized AJAX requests to Post Expirator endpoints
logsource:
category: webserver
product: apache
detection:
selection:
cs-method: 'POST'
cs-uri-query|contains: 'action=expirationdate_save_meta'
condition: selection
falsepositives:
- Legitimate admin actions
level: medium
Suricata Rule
alert http any any -> any any (msg:"CVE-2025-69361 - Post Expirator Missing Authorization"; flow:to_server,established; content:"POST"; http_method; content:"/wp-admin/admin-ajax.php"; http_uri; content:"action=expirationdate_save_meta"; http_client_body; classtype:attempted-recon; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Disable the plugin if not critical to operations.
- Restrict access to
/wp-admin/admin-ajax.phpvia.htaccessor WAF rules for low-privilege users. - Apply virtual patching using a Web Application Firewall (WAF) to block requests containing
action=expirationdate_save_metafrom non-admin roles.
Long-Term Fix:
- Upgrade to a patched version once released by PublishPress.
- Implement custom code fix as shown in the patched code section above.
- Enforce capability checks using
current_user_can()for all AJAX handlers.
Workaround:
- Use a security plugin like Wordfence to add role-based restrictions on AJAX actions.
Valters IT
Senior DevSecOps & Cyber Threat Intelligence Expert
What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.