TL;DR
I reported GHSA-8423-5658-789h in Chamilo LMS.
This was a broken object-level authorization issue in the assignment submission feedback API.
An authenticated user with a basic ROLE_USER account could target an arbitrary submissionId in a POST /api/c_student_publication_comments/upload request and inject feedback onto another student’s assignment.
Even worse, if the request included grading parameters, the backend would overwrite the submission’s score (qualification), record date, and stamp the attacker’s user ID as the evaluator (qualificator_id).
All without checking whether the attacker was enrolled in the target course or had teacher/grader permissions.
The bug
The vulnerable endpoint sat at:
POST /api/c_student_publication_comments/uploadThe flow of the API logic looked like this:
POST payload with submissionId-> Backend loads target CStudentPublication by ID-> Creates CStudentPublicationComment on the loaded submission-> If qualification is present: -> updates $submission->setQualification(...) -> updates $submission->setQualificatorId(...) -> updates $submission->setDateOfQualification(...)-> Saves record to databaseNotice what is missing between loading CStudentPublication and modifying it:
is the requesting user enrolled in the submission's course/session?is the requesting user a teacher or grader for that course?Because those checks were missing, any valid session with ROLE_USER could interact with submissions belonging to completely unrelated courses and sessions.
What an attacker could do
An attacker registered as a regular student in Course A could issue a request targeting a submission in Course B:
POST /api/c_student_publication_comments/upload HTTP/1.1Host: chamilo.localAuthorization: Bearer <attacker_token>Content-Type: application/json
{ "submissionId": 42, "comment": "Tampered feedback via API", "qualification": "100", "file": null}When Chamilo processed this request:
- A new feedback comment was appended to submission
42. - The score on submission
42was changed to100. qualificator_idwas updated to the attacker’s user ID.date_of_qualificationwas updated to the current timestamp.
This gave a low-privileged user both a feedback injection vector and arbitrary grade manipulation across the entire LMS platform.
Why it happened
The endpoint loaded the CStudentPublication object directly from the database using the user-supplied submissionId.
While authentication was verified (the user needed a valid JWT token), authorization was treated as binary (“is the user logged in?”) rather than contextual (“is the user authorized to grade this specific submission in this specific course?”).
In an LMS architecture, authorization must always be evaluated against the resource’s parent scope (Course / Session / Group), not just global login status.
The fix
The fix requires enforcing object-level authorization on the loaded CStudentPublication record before performing any state changes or comment creations.
The backend must verify:
- The user has teacher/grader role within the specific course/session associated with the target submission.
- Or if only adding comments, the user owns the submission or is an assigned instructor.
Requests failing this check must be rejected immediately with 430 / 403 Forbidden.
Versions and details
- Advisory:
GHSA-8423-5658-789h - Package:
chamilo/chamilo-lms - Affected:
<= 2.0.2 - Severity:
High - Weakness:
CWE-862 (Missing Authorization) - Credit: baradika