fix: CSRF on ticket create form, DOM-safe duplicate list, audit-log param validation

- TicketController::create: validate csrf_token from POST before processing
- CreateTicketView: emit hidden csrf_token field; replace innerHTML duplicate
  list with DOM methods to prevent any XSS path; guard checkDuplicates() with
  lt.api availability check
- index.php audit-log: allowlist action_type; validate date_from/date_to as
  YYYY-MM-DD before passing to query

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-28 21:26:52 -04:00
parent b40c404828
commit 6b76496640
3 changed files with 44 additions and 12 deletions
+6 -4
View File
@@ -242,7 +242,9 @@ switch (true) {
$params = [];
$types = '';
if (!empty($_GET['action_type'])) {
$allowedActionTypes = ['create','update','delete','comment','assign','status_change','login','security',
'ticket_create','ticket_update','ticket_delete','attachment_delete','attachment_upload'];
if (!empty($_GET['action_type']) && in_array($_GET['action_type'], $allowedActionTypes, true)) {
$whereConditions[] = "al.action_type = ?";
$params[] = $_GET['action_type'];
$types .= 's';
@@ -252,15 +254,15 @@ switch (true) {
$whereConditions[] = "al.user_id = ?";
$params[] = (int)$_GET['user_id'];
$types .= 'i';
$filters['user_id'] = $_GET['user_id'];
$filters['user_id'] = (int)$_GET['user_id'];
}
if (!empty($_GET['date_from'])) {
if (!empty($_GET['date_from']) && preg_match('/^\d{4}-\d{2}-\d{2}$/', $_GET['date_from'])) {
$whereConditions[] = "DATE(al.created_at) >= ?";
$params[] = $_GET['date_from'];
$types .= 's';
$filters['date_from'] = $_GET['date_from'];
}
if (!empty($_GET['date_to'])) {
if (!empty($_GET['date_to']) && preg_match('/^\d{4}-\d{2}-\d{2}$/', $_GET['date_to'])) {
$whereConditions[] = "DATE(al.created_at) <= ?";
$params[] = $_GET['date_to'];
$types .= 's';