Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

FeedsContactPrivacy© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
moodle-grades-gradeitems — Moodle 5.2.3 - High - Remote - IDOR - core_grades_get_gradeitems lists hidden grade items | Kitploit
Tools/GitHubGitHub/abraxas/moodle-grades-gradeitems
Vulnerability AnalysisWeb Application ExploitationAPI Security TestingInformation GatheringWeb SecurityPenetration TestingLearning & EducationLabs & Practice
GitHubabraxas/moodle-grades-gradeitems

moodle-grades-gradeitems

Moodle 5.2.3 - High - Remote - IDOR - core_grades_get_gradeitems lists hidden grade items

102 days agoNot yet reviewed
View Repository

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

Abraxas Labs - moodle-grades-gradeitems

abraxaslabs.tech  ·  github.com/abraxas  ·  @abraxas_null  ·  [email protected]  ·  moodle-grades-gradeitems

moodle-grades-gradeitems

Moodle LMS 5.2.3 - Moodle

Class: IDOR Reach: Remote

core_grades_get_gradeitems is ajax plus the official mobile service, with no capabilities key in services.php. validate_context is the only gate. Then grade_item::fetch_all dumps every item in the course. The array_filter drops GRADE_TYPE_NONE, category items, and the course item. Hidden is not in that filter. Sibling core_grades_get_grade_tree already requires moodle/grade:viewall.

An enrolled student POSTs {courseid} and gets names of hidden grade items the student gradebook UI still hides.

IDno CVE yet
CWECWE-862 / CWE-200
CVSSMedium: 4.3 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N
ProductMoodle
Affected5.2.3 tag v5.2.3 (344232c15336c71b80f9aca8359ce0e0a9f3d116)
Authenrolled student (moodle/grade:view; lacks viewall / viewhidden)
LicenseGNU Affero GPL v3.0
Lab127.0.0.1 only

What an attacker can do

Writer: an enrolled student in the course. They POST the AJAX service with {courseid}. The response is names, IDs, and categories. The return schema has no scores. Not RCE. Not LPE. Not a score write.

PrivilegeMethod / sinkRecon / integrity / availabilityLab-proven or inferred
Read hidden grade-item name, id, and categoryPOST /lib/ajax/service.php?sesskey= core_grades_get_gradeitems {courseid}ReconLab-proven. HTTP 200, names include MOODLE-GRADES-GRADEITEMS-WITNESS
Read visible grade-item name, id, and categorySame responseRecon (intended for teachers)Lab-proven. names include Visible Lab Assignment
Same catalogue over the official mobile serviceSame class, services includes MOODLE_OFFICIAL_MOBILE_SERVICEReconInferred from services.php. Lab used AJAX.
Walk sequential courseid values for courses the student can enterSame method, guessed idsReconInferred. Lab used the seeded course id 2
See the hidden item in the student gradebook UIGET /grade/report/user/index.php?id=n/aLab-proven closed. hidden-in-ui=False, visible-in-ui=True
Call without a sessionAJAX with a dummy sesskeyn/aLab-proven closed. servicerequireslogin
Call as a logged-in user who is not enrolledoutsider AJAX, same courseidn/aLab-proven closed. requireloginerror
Read other students' scores or write gradesn/an/aClosed. Return keys are id, itemname, category
PHP RCE / OS LPEn/an/aClosed. This leftover is a catalogue read

A teacher or manager who already has moodle/grade:viewall already sees the catalogue. Guest / unauthenticated callers still need a course context.

Same pin leftovers: Blackboard img file read, enrol_database SQLi, grades feedback IDOR.

How I found it

I pinned moodle/moodle v5.2.3 after MSA-26-0042/0043. Grade web services were in that MSA window. get_gradeitems.php still has no require_capability. The student UI already hid the item. The AJAX catalogue did not.

Wrong turns already recorded: treating unauth AJAX 200 as the leak (body is servicerequireslogin); calling this a score IDOR because the method name has grade (schema is names only); expecting get_grade_tree to be the same leftover (it already requires viewall). A reverse shell. Theatre.

Lab

Live Moodle v5.2.3 on php:8.3-apache + MariaDB 11.4. Seed enrols labstudent, leaves laboutsider out of the course, and creates a visible manual item plus a hidden item whose name is the witness. run.sh copies a local pin or git clone --depth 1 --branch v5.2.3. The Moodle tree is not in this pack.

python3 moodle-grades-gradeitems-Abraxas-Labs.py

or

cd lab
./run.sh

Target only http://127.0.0.1:19590. Compose project moodle-grades-gradeitems. Stack tears down after the run.

SUCCESS moodle-grades-gradeitems student-ajax=200 hidden-in-ajax=yes hidden-in-ui=no visible-in-ajax=yes visible-in-ui=yes outsider-error=yes unauth-error=yes MOODLE-GRADES-GRADEITEMS-WITNESS

The fix

After validate_context, require the same cap as get_grade_tree: require_capability('moodle/grade:viewall', $context). Also drop hidden items unless the caller has moodle/grade:viewhidden. Add a Behat/PHPUnit case: enrolled student, hidden manual item, core_grades_get_gradeitems must omit that item (or 403). Student gradebook UI already hides it.

References

  • github.com/moodle/moodle tag v5.2.3
  • get_gradeitems.php
  • Sibling already requires the cap: get_grade_tree.php
  • Service registration: services.php (core_grades_get_gradeitems, no capabilities)
  • Same pin: moodle-blackboard-img · moodle-enrol-database-sqli · moodle-grades-feedback-idor
  • CWE-862

License

GNU Affero GPL v3.0. See LICENSE. Loopback lab only. No warranty.

Download Tool