From fca0b42726e937f64a7a2b809591b33d7e3ebdbb Mon Sep 17 00:00:00 2001 From: Jared Vititoe Date: Fri, 11 Sep 2026 13:31:33 -0400 Subject: [PATCH] Validate field_type against the allowed enum in custom field definitions (#50) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The setValue()/is_required/select-options half of this issue was already fixed incidentally by #47's new api/ticket_custom_fields.php endpoint. The remaining gap: createDefinition()/updateDefinition() never validated field_type against the six values the schema's enum() actually allows (text/textarea/select/checkbox/date/number), so a malformed type could be stored via the admin API and break whatever UI renders it later. Added an ALLOWED_FIELD_TYPES allowlist check at the top of both methods, returning the same ['success' => false, 'error' => ...] shape they already use for a DB failure — api/custom_fields.php already propagates that shape correctly with no changes needed there. Verified against real MariaDB: an invalid field_type is rejected on both create and update, while a valid one still succeeds. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01Lhz7pGMaoTfL5sdYS5XiKv --- models/CustomFieldModel.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/models/CustomFieldModel.php b/models/CustomFieldModel.php index 4ebb3c0..cc80aa2 100644 --- a/models/CustomFieldModel.php +++ b/models/CustomFieldModel.php @@ -8,6 +8,9 @@ class CustomFieldModel { private $conn; + // Must match custom_field_definitions.field_type's enum() in the schema. + private const ALLOWED_FIELD_TYPES = ['text', 'textarea', 'select', 'checkbox', 'date', 'number']; + public function __construct($conn) { $this->conn = $conn; @@ -87,6 +90,10 @@ class CustomFieldModel */ public function createDefinition($data) { + if (!in_array($data['field_type'] ?? '', self::ALLOWED_FIELD_TYPES, true)) { + return ['success' => false, 'error' => 'Invalid field_type']; + } + $options = null; if (isset($data['field_options']) && !empty($data['field_options'])) { $options = json_encode($data['field_options']); @@ -129,6 +136,10 @@ class CustomFieldModel */ public function updateDefinition($fieldId, $data) { + if (!in_array($data['field_type'] ?? '', self::ALLOWED_FIELD_TYPES, true)) { + return ['success' => false, 'error' => 'Invalid field_type']; + } + $options = null; if (isset($data['field_options']) && !empty($data['field_options'])) { $options = json_encode($data['field_options']);