-
-
Notifications
You must be signed in to change notification settings - Fork 337
Description
Summary
A security audit identified 12 authorization vulnerabilities (1 Critical, 6 High, 5 Medium) in the project management system.
Critical Finding
Kanban/Scrum Board — Cross-Project Ticket Status IDOR (CRITICAL)
app/Helpers/KanbanScrumHelper.php:157-166:
public function recordUpdated(int $record, int $newIndex, int $newStatus): void
{
$ticket = Ticket::find($record);
if ($ticket) {
$ticket->order = $newIndex;
$ticket->status_id = $newStatus;
$ticket->save();
}
}This Livewire listener accepts a ticket ID from the client with zero ownership or project membership verification. While the parent Kanban/Scrum page scopes to the user's project, this method can be called via the Livewire wire protocol with ANY ticket ID — enabling cross-project ticket status manipulation.
HIGH Findings — 1-of-N Policy Pattern
Delete Policies Missing Ownership Checks
Three policies (Ticket, Project, Sprint) all have the same pattern — view and update verify project membership/ownership, but delete only checks the Spatie permission:
TicketPolicy.php:84-87:
public function delete(User $user, Ticket $ticket) {
return $user->can('Delete ticket'); // NO ownership check
}Compare with update() which checks $ticket->owner_id === $user->id OR $ticket->responsible_id === $user->id OR project membership. Since the default role includes all permissions, any authenticated user can delete any ticket/project/sprint.
Comment Edit/Delete Missing Ownership (HIGH)
ViewTicket.php:170,229 — submitComment() and doDeleteComment() accept comment IDs without verifying the comment belongs to the current ticket or that the user is the author. Any user can edit/delete any comment system-wide.
Timesheet Resource — No Policy (HIGH)
TimesheetResource.php has NO associated policy. Any authenticated user can list ALL users' timesheets, edit any entry, and bulk-delete entries across all projects.
Epic CRUD Missing Project Auth (HIGH)
EpicForm.php — Livewire component performs no authorization checks on epic create/edit/delete.
MEDIUM — UI-Only Auth Pattern
ManageGeneralSettings, TimesheetDashboard, TimesheetExport, and JiraImport pages all use shouldRegisterNavigation() to hide nav links — but this does NOT prevent direct URL access. Any authenticated user can modify platform-wide settings.
Dashboard widgets (TicketTimeLogged, TicketsByPriority, TicketsByType, UserTimeLogged) query ALL tickets without project scoping — leaking cross-project aggregate data.
Recommended Fixes
- Add authorization to
recordUpdated()— verify user is a project member before modifying the ticket - Add ownership checks to delete policies to match view/update patterns
- Create a TicketHourPolicy for the Timesheet resource
- Add
mount()authorization to Filament pages instead of relying onshouldRegisterNavigation() - Scope dashboard widget queries to the current user's projects
Disclosure
Filed in good faith. No exploit code provided.