In June 2024, a security flaw was found and registered as CVE-2024-48898 in Moodle, the well-known open-source learning management system. This vulnerability, discovered by security researchers, revealed that users with permissions to delete report audiences could also delete audiences from reports they didn't actually control. This post will break down What happened, How it works, code snippets, exploit steps, and how to mitigate the problem.

What is an 'Audience' in Moodle Reports?

In Moodle, an audience is a group of users who have access to a particular report. For example, teachers might make a report on student grades and set an audience of "all students in course X." The permissions system is supposed to make sure you can only edit or delete audiences from your own reports.

The Vulnerability: What Went Wrong?

The core issue in CVE-2024-48898 is a permissions bypass. Moodle's code did not *properly* check that a user deleting an audience from a report actually had the *right* to manage that specific report’s audience. If someone could delete audiences from a report they owned, they could also—by clever requests—delete from other reports as well.

This was due to improper checks in the backend logic. The delete function didn't confirm ownership or right permissions before proceeding, trusting just the incoming report and audience IDs.

Let's imagine a simplified PHP example similar to Moodle internals

// function to delete an audience
function delete_audience($audienceid, $userid) {
    $audience = get_audience_by_id($audienceid);

    // BAD: Only checks if user can delete audiences in general, not ownership
    if (user_has_capability('report/audience:delete', $userid)) {
        // Proceed to delete
        db_delete('report_audiences', ['id' => $audienceid]);
        return true;
    } else {
        return false;
    }
}

Because there was no check that $userid actually owned or managed the report linked to $audienceid, users with basic deletion permission could delete audiences in any report.

Exploit Details: Step-by-Step

Anyone who already had the ability to delete audiences from *their* reports could exploit this in these steps:

1. Find Victim-Audience IDs: The attacker finds the ID (number) of an audience attached to a report they *should not* manage.

This can be done by guessing, enumeration, or viewing report URLs.

2. Send a Delete Request: Using a crafted HTTP request, they ask the Moodle backend to delete the audience with that ID.

Tools like Burp Suite, browser DevTools, or curl can help.

3. Audience is Deleted: Because the backend never checks ownership, it deletes the audience—even from reports the attacker shouldn’t touch.

Example HTTP Request

POST /moodle/local/report/delete_audience.php
Content-Type: application/x-www-form-urlencoded

audienceid=4321

As long as 4321 is a valid audience ID, and the user has base delete permissions, it works.

Unauthorized users can remove whole sets of users from viewing specific reports.

- This could mess up visibility, reporting, and even be used for denial-of-service attacks on report access.

Mitigation & Fix

The fix, merged into Moodle’s core repo (see Moodle vulnerabilities page), is to check report permissions before allowing audience deletion.

Fixed logic

function delete_audience($audienceid, $userid) {
    $audience = get_audience_by_id($audienceid);
    $report = get_report_by_id($audience['reportid']);

    // NOW: Also checks if user can manage THIS report
    if (user_owns_report($userid, $report['id']) 
        && user_has_capability('report/audience:delete', $userid)) {
        db_delete('report_audiences', ['id' => $audienceid]);
        return true;
    } else {
        return false;
    }
}

References

- Moodle Security Advisory for CVE-2024-48898 *(official, see Security Notices)*
- NVD Entry for CVE-2024-48898
- Moodle GitHub — see commits after June 2024

Summary

CVE-2024-48898 shows how even small backend permission mistakes can have big impacts. In this case, a missing ownership check meant power users could delete stuff outside their area. The fix is straightforward: Always check *full* user permissions, not just the action, but the context too.

If you use Moodle, doublecheck your version, review report permissions, and patch as soon as possible!


*Stay safe. For bug bounty, research, or responsible disclosure, always report issues directly to the Moodle security team.*

Timeline

Published on: 11/18/2024 12:15:18 UTC
Last modified on: 11/20/2024 14:46:16 UTC