-
-
Notifications
You must be signed in to change notification settings - Fork 489
Description
Summary
The v1 API ticket endpoints lack group membership validation, allowing any authenticated user to read, update, delete, and comment on any ticket regardless of group membership. The v2 API correctly implements these checks.
Finding 1: V1 Single Ticket IDOR (CRITICAL)
File: src/controllers/api/v1/tickets.js:721-740
apiTickets.single fetches any ticket by UID with no group membership check. Route: GET /api/v1/tickets/:uid — only canUser('tickets:view').
V2 comparison (src/controllers/api/v2/tickets.js:116-152): Properly checks getDepartmentGroupsOfUser() for agents and getAllGroupsOfUser() for users, returning 403 if group doesn't match.
Finding 2: V1 Update Ticket IDOR (CRITICAL)
File: src/controllers/api/v1/tickets.js:767-883
apiTickets.update modifies any ticket by ID. Route: PUT /api/v1/tickets/:id — only canUser('tickets:update').
Finding 3: V1 Delete Ticket IDOR (CRITICAL)
File: src/controllers/api/v1/tickets.js:906-920
apiTickets.delete soft-deletes any ticket by ID. Route: DELETE /api/v1/tickets/:id — only canUser('tickets:delete').
Finding 4: Comment IDOR + Owner Spoofing (HIGH)
File: src/controllers/api/v1/tickets.js:954-979
postCommentadds comments to ANY ticket without group check- Line 957:
var owner = commentJson.ownerId || req.user._id— comment author is client-controlled, enabling impersonation
Impact
Any authenticated user can enumerate ticket UIDs (sequential integers from 1000) and access all tickets system-wide, breaking group-based isolation.
Suggested Fix
Port the v2 group membership check (getDepartmentGroupsOfUser() / getAllGroupsOfUser()) to v1 endpoints. For comments: always use req.user._id.
CWE
- CWE-639 (Authorization Bypass Through User-Controlled Key)
- CWE-862 (Missing Authorization)