SECURITY ADVISORY / 01

CVE-2025-9318 Exploit & Vulnerability Analysis

Complete CVE-2025-9318 security advisory with proof of concept (PoC), exploit details, and patch analysis.

cve_patchdiff:quiz-master-next NVD ↗
Exploit PoC Vulnerability Patch Analysis

1. Vulnerability Background

What is this vulnerability?

  • CVE-2025-9318 is a time-based SQL injection vulnerability in the WordPress Quiz and Survey Master (QSM) plugin.
  • The vulnerable code was in php/rest-api.php, where the request parameter is_linking was used to build a SQL IN (...) clause without sufficient validation or escaping.
  • The plugin also exposed REST endpoints with permission_callback => '__return_true', creating an authorization bypass for those routes.

Why is it critical/important?

  • SQL injection allows attackers to manipulate database queries, which can lead to data exfiltration, authentication bypass, or even full site compromise.
  • Time-based SQLi is particularly dangerous because it can be exploited in blind conditions, where the attacker cannot directly see query results but can infer them through response timing.
  • Combined with insufficient REST API permissions, this vulnerability enlarges the attacker surface and can be exploited by low-privileged users.

What systems/versions are affected?

  • QSM – Easy Quiz and Survey Maker plugin for WordPress
  • All versions up to and including 10.3.1
  • Any WordPress site running the vulnerable plugin with REST API access enabled is at risk

2. Technical Details

Root cause analysis

  • The root cause is unsafe SQL query construction in php/rest-api.php.
  • is_linking was read directly from the request and later concatenated into a dynamic SQL clause: WHERE question_id IN (" . $comma_separated_ids . ")
  • The code also built a linked question list from user-controlled data without strict validation.
  • Separately, endpoint registration used 'permission_callback' => '__return_true', which bypasses all authorization checks and allows unauthorized access.

Attack vector and exploitation conditions

  • The attacker needs to reach a vulnerable QSM REST API endpoint that processes is_linking.
  • The payload can be supplied through the is_linking parameter in a REST request.
  • Because the value is inserted directly into an IN (...) list, a crafted value like 1, IF(SUBSTRING(@@version,1,1)=5, SLEEP(5), 0) can induce a measurable delay.
  • Exploitation is feasible with subscriber-level or low-privileged access if the REST endpoint is accessible, and even more so when permission callbacks are incorrectly configured.

Security implications

  • Unauthorized database access and data disclosure
  • Blind SQL injection via timing attacks
  • Possible extraction of sensitive site and database information
  • Expanded attack surface due to broken REST API authorization

3. Patch Analysis

What code changes were made?

  • Permission callbacks on multiple REST routes were changed: from 'permission_callback' => '__return_true' to a closure that calls current_user_can('edit_qsm_quizzes')
  • is_linking input now sanitized using intval()
  • Existing linked question IDs are normalized by:
    • splitting on commas
    • trimming values
    • filtering empty strings
    • converting each value to integer via array_map('intval')
  • Linked IDs are deduplicated and filtered before query construction
  • The SQL query now uses a sanitized list of integer IDs

How do these changes fix the vulnerability?

  • The permission callback restricts endpoint access to users with the edit_qsm_quizzes capability, closing the authorization bypass.
  • intval() prevents arbitrary SQL fragments from being injected through is_linking.
  • Normalizing the linked question list ensures only numeric IDs are incorporated into the query.
  • Deducing and filtering the ID list prevents non-numeric input from reaching the SQL statement.

Security improvements introduced

  • Enforced capability-based access control on REST endpoints
  • Input validation and sanitization of query parameters
  • Safer SQL query composition by limiting injected content to integer values
  • Reduced attack surface by removing public exposure of sensitive endpoints

4. Proof of Concept (PoC) Guide

Prerequisites for exploitation

  • WordPress site with QSM plugin version 10.3.1 or earlier installed
  • Access to a vulnerable QSM REST API endpoint that accepts is_linking
  • Ability to send authenticated REST requests (subscriber-level or accessible endpoint)

Step-by-step exploitation approach

  1. Identify the QSM REST endpoint implementing is_linking handling.
  2. Send a crafted request with the is_linking parameter containing an injected SQL expression, for example: is_linking=1, IF(SUBSTRING(@@version,1,1)='5', SLEEP(5), 0)
  3. Observe response timing:
    • normal input should return quickly
    • injected input should delay the response by the sleep interval if SQL injection succeeds
  4. Use a time-based payload to infer database contents such as version, table names, or other sensitive values.

Expected behavior vs exploited behavior

  • Expected behavior:
    • is_linking is treated as an integer ID
    • query returns the expected linked quiz question records
  • Exploited behavior:
    • is_linking injects SQL syntax into the query
    • query executes attacker-controlled expressions
    • response timing or results leak database information

How to verify the vulnerability exists

  • Confirm QSM version is 10.3.1 or older
  • Locate the REST endpoint in php/rest-api.php
  • Send a test payload with an injected sleep expression
  • If the endpoint response is delayed consistently, the vulnerability is present
  • Alternatively, monitor database logs for malformed IN (...) queries containing injected payload content

5. Recommendations

Mitigation strategies

  • Update QSM to a patched version above 10.3.1
  • If patching is not immediately possible, disable the plugin or restrict REST access to trusted users only
  • Apply input validation and sanitization for all user-controlled REST parameters

Detection methods

  • Inspect REST API endpoint registration for permission_callback => '__return_true'
  • Monitor access to QSM REST routes in web logs
  • Detect unusual is_linking parameter values or repeated timing-based requests
  • Use database query logging to find unexpected IN (...) payloads

Best practices to prevent similar issues

  • Never use __return_true for REST API permission callbacks
  • Always enforce capability checks with current_user_can() for plugin endpoints
  • Sanitize all request inputs before using them in SQL queries
  • Prefer parameterized queries and prepared statements over direct string concatenation
  • Normalize and validate list input values before building query clauses
  • Apply least privilege to REST endpoints and limit access to necessary roles only

Frequently asked questions about CVE-2025-9318

What is CVE-2025-9318?

CVE-2025-9318 is a security vulnerability. This security advisory provides detailed technical analysis of the vulnerability, exploit methodology, affected versions, and complete remediation guidance.

Is there a PoC (proof of concept) for CVE-2025-9318?

Yes. This writeup includes proof-of-concept details and a technical exploit breakdown for CVE-2025-9318. Review the analysis sections above for the PoC walkthrough and code examples.

How does CVE-2025-9318 get exploited?

The technical analysis section explains the vulnerability mechanics, attack vectors, and exploitation methodology. PatchLeaks publishes this information for defensive and educational purposes.

What products and versions are affected by CVE-2025-9318?

CVE-2025-9318 — check the affected-versions section of this advisory for specific version ranges, vulnerable configurations, and compatibility information.

How do I fix or patch CVE-2025-9318?

The patch analysis section provides guidance on updating to patched versions, applying workarounds, and implementing compensating controls.

What is the CVSS score for CVE-2025-9318?

The severity rating and CVSS scoring for CVE-2025-9318 is documented in the vulnerability details section. Refer to the NVD entry for the current authoritative score.