Security/correctness: visibility filtering, Content-Type headers, group validation

- TicketModel::getAllTickets() now accepts optional $user param and applies
  getVisibilityFilter() so non-admin users cannot see internal/confidential
  tickets they lack access to from the dashboard listing
- DashboardController passes $GLOBALS['currentUser'] to getAllTickets()
- clone_ticket.php: move Content-Type header to top so all error paths send
  correct JSON content type
- AuthMiddleware: filter group names from HTTP header to [a-z0-9_-] only,
  preventing header injection via malformed group names
- add_comment.php: return HTTP 201 on success, 500 in catch block
- update_comment.php, delete_comment.php: return 500 in catch blocks

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-29 18:23:16 -04:00
parent f983269f93
commit e6b6a2a88c
7 changed files with 26 additions and 5 deletions
+5 -1
View File
@@ -155,7 +155,11 @@ class AuthMiddleware {
}
// Check for admin or employee group membership
$userGroups = array_map('trim', explode(',', strtolower($groups)));
// Filter to safe characters only to prevent header injection attacks
$userGroups = array_filter(
array_map('trim', explode(',', strtolower($groups))),
function($g) { return preg_match('/^[a-z0-9_\-]+$/', $g); }
);
$requiredGroups = ['admin', 'employee'];
return !empty(array_intersect($userGroups, $requiredGroups));