-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Description
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:
UserController—can:view usersSchoolClassController—can:view classesAcademicSettingController—can:view academic settingsAttendanceController—can: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.