Skip to content

Security: Systemic Missing Authorization - Students Can Perform Admin Actions #453

@lighthousekeeper1212

Description

@lighthousekeeper1212

Summary

During a security review, I identified systemic missing server-side authorization in Unifiedtransform. While the application defines 50+ Spatie permissions and assigns them to roles (admin, teacher, student), the vast majority of controllers do not enforce these permissions via middleware.

Findings

1. Missing Authorization Middleware (12 of 16 Controllers) — HIGH

Only 4 controllers use can: middleware:

  • UserControllercan:view users
  • SchoolClassControllercan:view classes
  • AcademicSettingControllercan:view academic settings
  • AttendanceControllercan:view attendances

The remaining 12 controllers have no authorization middleware: ExamController, MarkController, CourseController, SectionController, AssignmentController, EventController, RoutineController, SyllabusController, NoticeController, PromotionController, ExamRuleController, GradingSystemController, GradeRuleController, SchoolSessionController, SemesterController, AssignedTeacherController.

Since all routes are in the auth middleware group (routes/web.php:45), these endpoints only require authentication (login), not authorization (role/permission check). A student user can directly call admin-only routes like POST /school/session/create, POST /promotions/promote, or POST /exams/create.

2. IDOR on Student/Teacher Profile View/Edit/Update — HIGH

UserController::showStudentProfile($id), editStudent($student_id), showTeacherProfile($id), editTeacher($teacher_id), updateStudent(), updateTeacher() — all accept user-controlled IDs with no ownership verification. Any authenticated user can view/edit any student or teacher profile. The updateStudent() and updateTeacher() methods take student_id/teacher_id from the request body.

3. IDOR on Event Edit/Delete — MEDIUM

EventController::calendarEvents() uses Event::find($request->id) for edit and delete operations with no ownership check (lines 53, 61).

4. IDOR on Grade Rule Deletion — MEDIUM

GradeRuleController::destroy() calls GradeRule::destroy($request->id) with no ownership or session scoping.

5. Students Can View All Marks — MEDIUM

MarkController has no permission middleware. Students can view marks for any class/section/course/student via query parameters.

6. Cross-User Course Viewing — MEDIUM

CourseController::getStudentCourses($student_id) and AssignedTeacherController::getTeacherCourses() accept user-controlled IDs without ownership checks.

7. No Policies Defined — ARCHITECTURAL

The app/Policies/ directory does not exist. Zero Laravel policies are defined. $this->authorize() is never called in any controller.

Root Cause

The application relies on Blade @if(Auth::user()->role == "admin") checks to hide UI elements, but these are client-side controls that are trivially bypassed with direct HTTP requests.

Recommended Fix

Add can: middleware to all controller constructors matching the defined Spatie permissions:

// ExamController constructor
$this->middleware(['can:create exams'])->only(['store', 'create']);
$this->middleware(['can:view exams'])->only(['index']);

// PromotionController constructor
$this->middleware(['can:promote students']);

Also consider creating Laravel Policies for instance-level authorization (e.g., students should only view their own profile).

Disclosure

This report is submitted in good faith to help improve the security of Unifiedtransform. I am available to provide additional details or clarification.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions