Skip to content

Security: Systemic Ticket IDOR, Owner Spoofing, and Settings Pages Missing Admin Check #750

@lighthousekeeper1212

Description

@lighthousekeeper1212

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

  1. 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.

  2. Owner Spoofing (Findings 4, 6): Never trust owner/ownerId from the request body. Always derive the owner from req.user._id server-side.

  3. Settings Admin Check (Finding 5): Apply isAdmin middleware to all /settings/* routes, not just /settings/server.

  4. Message IDOR (Finding 7): Validate that req.user._id is a participant in the conversation before returning messages.

  5. User Preferences IDOR (Finding 8): Validate that req.user.username matches the :username parameter.

  6. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions