From a82d9fba7ad818ea148a14a55f0da552e42ef123 Mon Sep 17 00:00:00 2001 From: Christian Hartmann Date: Sat, 21 Feb 2026 15:43:34 +0100 Subject: [PATCH] fix: Improve validation for submission answers with strict type checking Signed-off-by: Christian Hartmann --- lib/Service/SubmissionService.php | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/lib/Service/SubmissionService.php b/lib/Service/SubmissionService.php index 6f3d54162..c171219bc 100644 --- a/lib/Service/SubmissionService.php +++ b/lib/Service/SubmissionService.php @@ -517,6 +517,9 @@ public function validateSubmission(array $questions, array $answers, string $for // Check if all answers are within the possible options if (in_array($question['type'], Constants::ANSWER_TYPES_PREDEFINED) && empty($question['extraSettings']['allowOtherAnswer'])) { + // Normalize option IDs once for consistent comparison (DB may return ints, request may send strings) + $optionIds = array_map('intval', array_column($question['options'] ?? [], 'id')); + foreach ($answers[$questionId] as $answer) { // Handle linear scale questions if ($question['type'] === Constants::ANSWER_TYPE_LINEARSCALE) { @@ -527,8 +530,18 @@ public function validateSubmission(array $questions, array $answers, string $for } } // Search corresponding option, return false if non-existent - elseif (!in_array($answer, array_column($question['options'], 'id'))) { - throw new \InvalidArgumentException(sprintf('Answer "%s" for question "%s" is not a valid option.', $answer, $question['text'])); + else { + // Accept numeric strings like "46" from JSON payloads reliably (e.g. with hardening extensions enabled) + $answerId = is_int($answer) ? $answer : (is_string($answer) ? intval(trim($answer)) : null); + + // Reject non-numeric / malformed values early + if ($answerId === null || (string)$answerId !== (string)intval($answerId)) { + throw new \InvalidArgumentException(sprintf('Answer "%s" for question "%s" is not a valid option.', is_scalar($answer) ? (string)$answer : gettype($answer), $question['text'])); + } + + if (!in_array($answerId, $optionIds, true)) { + throw new \InvalidArgumentException(sprintf('Answer "%s" for question "%s" is not a valid option.', $answer, $question['text'])); + } } } }