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
single handler 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
owner from the request body without validating it against req.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
redirectToLogin middleware but do NOT apply isAdmin. Only /settings/server includes the isAdmin check — 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
ownerId or owner from the request body without validating against req.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:
POST create has no isAgentOrAdmin middleware, 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 single handler. Ensure batch operations validate each ticket ID individually.
-
Owner Spoofing (Findings 4, 6): Never trust owner/ownerId from the request body. Always derive the owner from req.user._id server-side.
-
Settings Admin Check (Finding 5): Apply isAdmin middleware to all /settings/* routes, not just /settings/server.
-
Message IDOR (Finding 7): Validate that req.user._id is a participant in the conversation before returning messages.
-
User Preferences IDOR (Finding 8): Validate that req.user.username matches the :username parameter.
-
Tag Role Check (Finding 10): Add isAgentOrAdmin middleware 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.
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
GET /api/v1/tickets/:uidsrc/controllers/api/v1/tickets.js:721singlehandler which properly checks group membership — a classic 1-of-N inconsistency between API versions.2. v1 Ticket Update IDOR
PUT /api/v1/tickets/:idsrc/controllers/api/v1/tickets.js:7673. v2 Batch Ticket Update IDOR
PUT /api/v2/tickets/batchsrc/controllers/api/v2/tickets.js:1674. Message Send — Owner Spoofing + No Participant Check
POST /api/v1/messages/sendsrc/controllers/api/v1/messages.js:183ownerfrom 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.5. Settings Pages Missing Admin Role Check
/settings/*routes (general, mailer, permissions, backup, elasticsearch, etc.)src/routes/index.js:284-342redirectToLoginmiddleware but do NOT applyisAdmin. Only/settings/serverincludes theisAdmincheck — a 1-of-N inconsistency.HIGH (6)
6. Comment/Note/Ticket Owner Spoofing
addcomment,addnote,create(ticket creation)src/controllers/api/v1/tickets.js:954, 1035, 447ownerIdorownerfrom the request body without validating againstreq.user._id. Attackers can create tickets, comments, and internal notes that appear to come from other users.7. Message Read IDOR
GET /api/v1/messages/conversation/:idsrc/controllers/api/v1/messages.js:2558. User Preferences IDOR
PUT /api/v1/users/:username/updatepreferencessrc/controllers/api/v1/users.js:6969. Ticket Delete Missing Ownership Check
DELETE /api/v1/tickets/:idsrc/controllers/api/v1/tickets.js:90610. Tag Create Missing Role Check
POSTcreate has noisAgentOrAdminmiddleware, while update and delete operations do. This is a 1-of-N inconsistency where write operations are partially protected.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
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.