Fix bind_param type mismatches and integer validation

- TemplateModel.php: fix bind_param "ssssiii" -> "sssssii" (5 strings not 4)
- manage_workflows.php: fix bind_param 'ssiiii' -> 'ssiiiii' (4 int columns)
- download_attachment.php, delete_attachment.php, get_template.php: replace is_numeric()
  with strict int cast+equality check to reject floats and scientific notation
- manage_recurring.php: validate JSON input before accessing schedule_type key

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-28 22:33:48 -04:00
parent 5242d42fa7
commit cfbef029cb
6 changed files with 16 additions and 15 deletions
+2 -4
View File
@@ -51,13 +51,11 @@ if (!CsrfMiddleware::validateToken($csrfToken)) {
} }
// Get attachment ID // Get attachment ID
$attachmentId = $input['attachment_id'] ?? null; $attachmentId = isset($input['attachment_id']) ? (int)$input['attachment_id'] : 0;
if (!$attachmentId || !is_numeric($attachmentId)) { if ($attachmentId <= 0 || (string)$attachmentId !== (string)($input['attachment_id'] ?? '')) {
ResponseHelper::error('Valid attachment ID is required'); ResponseHelper::error('Valid attachment ID is required');
} }
$attachmentId = (int)$attachmentId;
try { try {
$attachmentModel = new AttachmentModel(Database::getConnection()); $attachmentModel = new AttachmentModel(Database::getConnection());
+2 -4
View File
@@ -22,16 +22,14 @@ if (!isset($_SESSION['user']) || !isset($_SESSION['user']['user_id'])) {
} }
// Get attachment ID // Get attachment ID
$attachmentId = $_GET['id'] ?? null; $attachmentId = isset($_GET['id']) ? (int)$_GET['id'] : 0;
if (!$attachmentId || !is_numeric($attachmentId)) { if ($attachmentId <= 0 || (string)$attachmentId !== (string)($_GET['id'] ?? '')) {
http_response_code(400); http_response_code(400);
header('Content-Type: application/json'); header('Content-Type: application/json');
echo json_encode(['success' => false, 'error' => 'Valid attachment ID is required']); echo json_encode(['success' => false, 'error' => 'Valid attachment ID is required']);
exit; exit;
} }
$attachmentId = (int)$attachmentId;
try { try {
$attachmentModel = new AttachmentModel(Database::getConnection()); $attachmentModel = new AttachmentModel(Database::getConnection());
+2 -5
View File
@@ -24,18 +24,15 @@ try {
} }
// Get template ID from query parameter // Get template ID from query parameter
$templateId = $_GET['template_id'] ?? null; $templateId = isset($_GET['template_id']) ? (int)$_GET['template_id'] : 0;
if (!$templateId || !is_numeric($templateId)) { if ($templateId <= 0 || (string)$templateId !== (string)($_GET['template_id'] ?? '')) {
ErrorHandler::sendValidationError( ErrorHandler::sendValidationError(
['template_id' => 'Valid template ID required'], ['template_id' => 'Valid template ID required'],
'Invalid request' 'Invalid request'
); );
} }
// Cast to integer for safety
$templateId = (int)$templateId;
// Get template // Get template
$conn = Database::getConnection(); $conn = Database::getConnection();
$templateModel = new TemplateModel($conn); $templateModel = new TemplateModel($conn);
+8
View File
@@ -70,6 +70,10 @@ try {
echo json_encode($result); echo json_encode($result);
} else { } else {
$data = json_decode(file_get_contents('php://input'), true); $data = json_decode(file_get_contents('php://input'), true);
if (!is_array($data) || empty($data['schedule_type']) || empty($data['title_template'])) {
echo json_encode(['success' => false, 'error' => 'schedule_type and title_template are required']);
exit;
}
// Calculate next run time // Calculate next run time
$nextRun = calculateNextRun( $nextRun = calculateNextRun(
@@ -94,6 +98,10 @@ try {
} }
$data = json_decode(file_get_contents('php://input'), true); $data = json_decode(file_get_contents('php://input'), true);
if (!is_array($data) || empty($data['schedule_type'])) {
echo json_encode(['success' => false, 'error' => 'Invalid request data']);
exit;
}
// Recalculate next run time if schedule changed // Recalculate next run time if schedule changed
$nextRun = calculateNextRun( $nextRun = calculateNextRun(
+1 -1
View File
@@ -120,7 +120,7 @@ try {
$stmt = $conn->prepare("UPDATE status_transitions SET $stmt = $conn->prepare("UPDATE status_transitions SET
from_status = ?, to_status = ?, requires_comment = ?, requires_admin = ?, is_active = ? from_status = ?, to_status = ?, requires_comment = ?, requires_admin = ?, is_active = ?
WHERE transition_id = ?"); WHERE transition_id = ?");
$stmt->bind_param('ssiiii', $stmt->bind_param('ssiiiii',
$data['from_status'], $data['from_status'],
$data['to_status'], $data['to_status'],
$data['requires_comment'] ?? 0, $data['requires_comment'] ?? 0,
+1 -1
View File
@@ -87,7 +87,7 @@ class TemplateModel {
default_priority = ? default_priority = ?
WHERE template_id = ?"; WHERE template_id = ?";
$stmt = $this->conn->prepare($sql); $stmt = $this->conn->prepare($sql);
$stmt->bind_param("ssssiii", $stmt->bind_param("sssssii",
$data['template_name'], $data['template_name'],
$data['title_template'], $data['title_template'],
$data['description_template'], $data['description_template'],