diff --git a/api/delete_attachment.php b/api/delete_attachment.php index 789cc50..5e7f8fc 100644 --- a/api/delete_attachment.php +++ b/api/delete_attachment.php @@ -80,12 +80,17 @@ try { ResponseHelper::forbidden('You do not have permission to delete this attachment'); } - // Delete the file - $uploadDir = $GLOBALS['config']['UPLOAD_DIR'] ?? dirname(__DIR__) . '/uploads'; - $filePath = $uploadDir . '/' . $attachment['ticket_id'] . '/' . $attachment['filename']; + // Delete the file — use realpath() to prevent path traversal + $uploadDir = realpath($GLOBALS['config']['UPLOAD_DIR'] ?? dirname(__DIR__) . '/uploads'); + $filePath = $uploadDir . '/' . (int)$attachment['ticket_id'] . '/' . $attachment['filename']; + $realPath = realpath($filePath); - if (file_exists($filePath)) { - if (!unlink($filePath)) { + if ($realPath !== false) { + // Ensure the resolved path is still inside the upload directory + if (strncmp($realPath, $uploadDir . DIRECTORY_SEPARATOR, strlen($uploadDir) + 1) !== 0) { + ResponseHelper::forbidden('Access denied'); + } + if (!unlink($realPath)) { ResponseHelper::serverError('Failed to delete file'); } } diff --git a/api/manage_templates.php b/api/manage_templates.php index 0218f48..23003f9 100644 --- a/api/manage_templates.php +++ b/api/manage_templates.php @@ -73,17 +73,36 @@ try { case 'POST': $data = json_decode(file_get_contents('php://input'), true); + // Validate required fields and lengths + $templateName = trim($data['template_name'] ?? ''); + $titleTemplate = trim($data['title_template'] ?? ''); + if (!$templateName || mb_strlen($templateName) > 100) { + echo json_encode(['success' => false, 'error' => 'Template name is required (max 100 chars)']); + exit; + } + if (!$titleTemplate || mb_strlen($titleTemplate) > 255) { + echo json_encode(['success' => false, 'error' => 'Title template is required (max 255 chars)']); + exit; + } + $allowedCategories = ['General','Hardware','Software','Network','Security']; + $allowedTypes = ['Issue','Maintenance','Install','Task','Upgrade','Problem']; + $category = in_array($data['category'] ?? '', $allowedCategories) ? $data['category'] : 'General'; + $type = in_array($data['type'] ?? '', $allowedTypes) ? $data['type'] : 'Issue'; + $priority = max(1, min(5, (int)($data['default_priority'] ?? 4))); + $isActive = $data['is_active'] ? 1 : 0; + $description = mb_substr($data['description_template'] ?? '', 0, 65535); + $stmt = $conn->prepare("INSERT INTO ticket_templates (template_name, title_template, description_template, category, type, default_priority, is_active) VALUES (?, ?, ?, ?, ?, ?, ?)"); $stmt->bind_param('sssssii', - $data['template_name'], - $data['title_template'], - $data['description_template'], - $data['category'], - $data['type'], - $data['default_priority'] ?? 4, - $data['is_active'] ?? 1 + $templateName, + $titleTemplate, + $description, + $category, + $type, + $priority, + $isActive ); if ($stmt->execute()) { @@ -103,18 +122,37 @@ try { $data = json_decode(file_get_contents('php://input'), true); + // Validate required fields and lengths + $templateName = trim($data['template_name'] ?? ''); + $titleTemplate = trim($data['title_template'] ?? ''); + if (!$templateName || mb_strlen($templateName) > 100) { + echo json_encode(['success' => false, 'error' => 'Template name is required (max 100 chars)']); + exit; + } + if (!$titleTemplate || mb_strlen($titleTemplate) > 255) { + echo json_encode(['success' => false, 'error' => 'Title template is required (max 255 chars)']); + exit; + } + $allowedCategories = ['General','Hardware','Software','Network','Security']; + $allowedTypes = ['Issue','Maintenance','Install','Task','Upgrade','Problem']; + $category = in_array($data['category'] ?? '', $allowedCategories) ? $data['category'] : 'General'; + $type = in_array($data['type'] ?? '', $allowedTypes) ? $data['type'] : 'Issue'; + $priority = max(1, min(5, (int)($data['default_priority'] ?? 4))); + $isActive = $data['is_active'] ? 1 : 0; + $description = mb_substr($data['description_template'] ?? '', 0, 65535); + $stmt = $conn->prepare("UPDATE ticket_templates SET template_name = ?, title_template = ?, description_template = ?, category = ?, type = ?, default_priority = ?, is_active = ? WHERE template_id = ?"); $stmt->bind_param('sssssiii', - $data['template_name'], - $data['title_template'], - $data['description_template'], - $data['category'], - $data['type'], - $data['default_priority'] ?? 4, - $data['is_active'] ?? 1, + $templateName, + $titleTemplate, + $description, + $category, + $type, + $priority, + $isActive, $id );