-
-
Notifications
You must be signed in to change notification settings - Fork 489
Description
Security Audit Report — Responsible Disclosure
This report documents 14 security findings (5 CRITICAL, 6 HIGH, 1 MEDIUM) discovered during an authorized security audit of trudesk. The findings center on three systemic patterns: missing ownership/group-membership checks on ticket operations, owner spoofing via unvalidated request body fields, and settings pages lacking admin role enforcement.
These are reported together because they share common root causes and a coordinated fix would be most effective.
Summary of Findings
CRITICAL (5)
1. v1 Ticket Read IDOR
- Endpoint:
GET /api/v1/tickets/:uid - File:
src/controllers/api/v1/tickets.js:721 - Description: Fetches any ticket without group membership check. Ticket UIDs are sequential integers, making enumeration trivial. Compare with the v2
singlehandler which properly checks group membership — a classic 1-of-N inconsistency between API versions. - Impact: Any authenticated user can read every ticket in the system, including those belonging to other groups/teams.
2. v1 Ticket Update IDOR
- Endpoint:
PUT /api/v1/tickets/:id - File:
src/controllers/api/v1/tickets.js:767 - Description: Modifies any ticket (status, subject, group, priority, assignee) without ownership or group membership check. Only authentication is required.
- Impact: Any authenticated user can alter any ticket's status, reassign it, change its priority, or move it to a different group.
3. v2 Batch Ticket Update IDOR
- Endpoint:
PUT /api/v2/tickets/batch - File:
src/controllers/api/v2/tickets.js:167 - Description: Accepts an array of ticket IDs and updates their status without any ownership or group validation. Batch operations amplify the impact significantly.
- Impact: Any authenticated user can mass-update ticket statuses across the entire system in a single request.
4. Message Send — Owner Spoofing + No Participant Check
- Endpoint:
POST /api/v1/messages/send - File:
src/controllers/api/v1/messages.js:183 - Description: Accepts
ownerfrom the request body without validating it againstreq.user._id, and performs no participant validation on the target conversation. Any user can send messages to any conversation while impersonating any other user. - Impact: Full conversation impersonation — messages appear to come from arbitrary users in conversations the attacker has no access to.
5. Settings Pages Missing Admin Role Check
- Endpoint: All
/settings/*routes (general, mailer, permissions, backup, elasticsearch, etc.) - File:
src/routes/index.js:284-342 - Description: Settings routes only apply
redirectToLoginmiddleware but do NOT applyisAdmin. Only/settings/serverincludes theisAdmincheck — a 1-of-N inconsistency. - Impact: Any authenticated user (including customers/end-users) can access and modify system-wide settings including mail configuration, permissions, backup, and Elasticsearch settings.
HIGH (6)
6. Comment/Note/Ticket Owner Spoofing
- Endpoints:
addcomment,addnote,create(ticket creation) - Files:
src/controllers/api/v1/tickets.js:954, 1035, 447 - Description: These endpoints accept
ownerIdorownerfrom the request body without validating againstreq.user._id. Attackers can create tickets, comments, and internal notes that appear to come from other users. - Impact: Identity spoofing on ticket operations — comments and notes attributed to arbitrary users.
7. Message Read IDOR
- Endpoint:
GET /api/v1/messages/conversation/:id - File:
src/controllers/api/v1/messages.js:255 - Description: Returns all messages in a conversation without checking whether the requesting user is a participant.
- Impact: Any authenticated user can read any private conversation by enumerating conversation IDs.
8. User Preferences IDOR
- Endpoint:
PUT /api/v1/users/:username/updatepreferences - File:
src/controllers/api/v1/users.js:696 - Description: Modifies any user's preferences without verifying that the requesting user matches the target username.
- Impact: Any authenticated user can alter another user's preference settings.
9. Ticket Delete Missing Ownership Check
- Endpoint:
DELETE /api/v1/tickets/:id - File:
src/controllers/api/v1/tickets.js:906 - Description: Soft-deletes any ticket without ownership or group membership validation.
- Impact: Any authenticated user can delete any ticket in the system.
10. Tag Create Missing Role Check
- Endpoint: Tag creation endpoint
- Description:
POSTcreate has noisAgentOrAdminmiddleware, while update and delete operations do. This is a 1-of-N inconsistency where write operations are partially protected. - Impact: Unauthorized users can create tags, potentially polluting the tag namespace.
Recommended Fixes
-
Ticket IDOR (Findings 1-3, 9): Add group membership validation to all v1 ticket endpoints, matching the pattern already implemented in v2's
singlehandler. Ensure batch operations validate each ticket ID individually. -
Owner Spoofing (Findings 4, 6): Never trust
owner/ownerIdfrom the request body. Always derive the owner fromreq.user._idserver-side. -
Settings Admin Check (Finding 5): Apply
isAdminmiddleware to all/settings/*routes, not just/settings/server. -
Message IDOR (Finding 7): Validate that
req.user._idis a participant in the conversation before returning messages. -
User Preferences IDOR (Finding 8): Validate that
req.user.usernamematches the:usernameparameter. -
Tag Role Check (Finding 10): Add
isAgentOrAdminmiddleware to the tag create endpoint to match update/delete.
Disclosure Timeline
- 2026-03-04: Report filed via GitHub Issue
This report is part of a volunteer security research effort focused on improving the security of open-source software. No exploit code is provided. Please feel free to reach out if you need additional details or clarification on any finding.