From 3980d03bad7fc0bd8f28e4b2b0bd484d9c8d6c2c Mon Sep 17 00:00:00 2001 From: Marijn Doeve Date: Sat, 23 May 2026 14:51:45 +0200 Subject: [PATCH] Add CSRF token validation across backoffice forms - Added CSRF validations to candidate correction, penalty, answer saving, and elimination forms. - Updated corresponding Twig templates to include CSRF token inputs. - Adjusted column count in `tab_result` template to maintain layout consistency. --- .../Backoffice/PrepareEliminationController.php | 4 ++++ src/Controller/Backoffice/QuizController.php | 12 ++++++++++++ src/Controller/QuizController.php | 4 ++++ .../backoffice/prepare_elimination/index.html.twig | 1 + templates/backoffice/quiz/tab_result.html.twig | 5 +++-- 5 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/Controller/Backoffice/PrepareEliminationController.php b/src/Controller/Backoffice/PrepareEliminationController.php index 7b5284a..eda337b 100644 --- a/src/Controller/Backoffice/PrepareEliminationController.php +++ b/src/Controller/Backoffice/PrepareEliminationController.php @@ -40,6 +40,10 @@ final class PrepareEliminationController extends AbstractController public function viewElimination(Elimination $elimination, Request $request): Response { if ('POST' === $request->getMethod()) { + if (!$this->isCsrfTokenValid('prepare_elimination', $request->request->get('_token'))) { + throw $this->createAccessDeniedException(); + } + $elimination->updateFromInputBag($request->request); $this->em->flush(); diff --git a/src/Controller/Backoffice/QuizController.php b/src/Controller/Backoffice/QuizController.php index 2094411..293e836 100644 --- a/src/Controller/Backoffice/QuizController.php +++ b/src/Controller/Backoffice/QuizController.php @@ -193,6 +193,10 @@ class QuizController extends AbstractController )] public function saveCandidateAnswers(Season $season, Quiz $quiz, Question $question, Request $request): RedirectResponse { + if (!$this->isCsrfTokenValid('candidate_answer', $request->request->get('_token'))) { + throw $this->createAccessDeniedException(); + } + if (false === $season->quizzes->contains($quiz) || false === $quiz->questions->contains($question)) { throw new BadRequestHttpException('Invalid quiz or question'); @@ -304,6 +308,10 @@ class QuizController extends AbstractController throw new MethodNotAllowedHttpException(['POST']); } + if (!$this->isCsrfTokenValid('candidate_correction', $request->request->get('_token'))) { + throw $this->createAccessDeniedException(); + } + $corrections = (float) $request->request->get('corrections'); $this->quizCandidateRepository->setCorrectionsForCandidate($quiz, $candidate, $corrections); @@ -323,6 +331,10 @@ class QuizController extends AbstractController throw new MethodNotAllowedHttpException(['POST']); } + if (!$this->isCsrfTokenValid('candidate_penalty', $request->request->get('_token'))) { + throw $this->createAccessDeniedException(); + } + $penalty = (int) $request->request->get('penalty'); $this->quizCandidateRepository->setPenaltyForCandidate($quiz, $candidate, $penalty); diff --git a/src/Controller/QuizController.php b/src/Controller/QuizController.php index 9951e9d..26f53d5 100644 --- a/src/Controller/QuizController.php +++ b/src/Controller/QuizController.php @@ -97,6 +97,10 @@ final class QuizController extends AbstractController } if ('POST' === $request->getMethod()) { + if (!$this->isCsrfTokenValid('question', $request->request->get('token'))) { + throw $this->createAccessDeniedException(); + } + // TODO: Extract saving answer logic to a service // Check if candidate is inactive for this quiz $quizCandidate = $this->quizCandidateRepository->findOneBy(['quiz' => $quiz, 'candidate' => $candidate]); diff --git a/templates/backoffice/prepare_elimination/index.html.twig b/templates/backoffice/prepare_elimination/index.html.twig index 1c50933..bf16ede 100644 --- a/templates/backoffice/prepare_elimination/index.html.twig +++ b/templates/backoffice/prepare_elimination/index.html.twig @@ -15,6 +15,7 @@
+ {%~ for candidate, colour in elimination.data %}
diff --git a/templates/backoffice/quiz/tab_result.html.twig b/templates/backoffice/quiz/tab_result.html.twig index 5aa5db5..d450c76 100644 --- a/templates/backoffice/quiz/tab_result.html.twig +++ b/templates/backoffice/quiz/tab_result.html.twig @@ -37,6 +37,7 @@ +
- +
{% else %} - {{ 'No results'|trans }} + {{ 'No results'|trans }} {% endfor %}