From 126a49185229f248eae8c485b3e16e029ebcb353 Mon Sep 17 00:00:00 2001 From: polo Date: Fri, 23 Oct 2026 23:29:59 +0200 Subject: =?UTF-8?q?audit=20claude=20code=201,=20validation=20formulaire=20?= =?UTF-8?q?toujours=20ok,=20=C3=A9chappement=20dans=20URL,=20quelques=20ht?= =?UTF-8?q?mlspecialchars=20manquants,=20fonction=20Security::validateURL?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Controller/HeadFootController.php | 9 +++++++-- src/Controller/MenuAndPathsController.php | 22 ++++++++++++---------- src/Controller/ViewController.php | 3 ++- 3 files changed, 21 insertions(+), 13 deletions(-) (limited to 'src/Controller') diff --git a/src/Controller/HeadFootController.php b/src/Controller/HeadFootController.php index e39c07b..2bf210e 100644 --- a/src/Controller/HeadFootController.php +++ b/src/Controller/HeadFootController.php @@ -28,14 +28,19 @@ class HeadFootController $node_data = $model->getNode()->getNodeData(); // liens réseaux sociaux + $link = trim($json['new_text'] ?? ''); // trim n'aime pas recevoir un NULL if(in_array($params_array[1], NodeData::$social_networks)){ + if($link !== '' && !Security::validateURL($link)){ + return new JsonResponse(['success' => false, 'error' => 'invalid_url']); + } + $social = $node_data->getData()['social'] ?? []; - $social[$params_array[1]] = $json['new_text']; + $social[$params_array[1]] = $link; $node_data->updateData('social', $social); } // autres textes else{ - $node_data->updateData($params_array[1], $json['new_text']); // $params_array[1] n'est pas contrôlé + $node_data->updateData($params_array[1], $link); // $params_array[1] n'est pas contrôlé } $entityManager->flush(); diff --git a/src/Controller/MenuAndPathsController.php b/src/Controller/MenuAndPathsController.php index 1916f06..aa283b6 100644 --- a/src/Controller/MenuAndPathsController.php +++ b/src/Controller/MenuAndPathsController.php @@ -6,31 +6,33 @@ declare(strict_types=1); namespace App\Controller; use Doctrine\ORM\EntityManager; +use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\RedirectResponse; use App\Entity\Page; use App\Model\Menu; use App\Model\Model; use App\Service\URL; +use App\Service\Security; use App\View\NavBuilder; use App\View\MenuBuilder; class MenuAndPathsController { - static public function newUrlMenuEntry(EntityManager $entityManager): RedirectResponse + static public function newUrlMenuEntry(EntityManager $entityManager, Request $request): RedirectResponse { Model::$menu = new Menu($entityManager); $previous_page = Model::$menu->findPageById((int)$_POST["location"]); // (int) à cause de declare(strict_types=1); $parent = $previous_page->getParent(); - $url_input = trim($_POST["url_input"]); // faire htmlspecialchars à l'affichage - if(!filter_var($url_input, FILTER_VALIDATE_URL) || !str_starts_with($url_input, 'http')){ + $url_input = trim($request->request->get("url_input")); // faire htmlspecialchars à l'affichage + if(!Security::validateURL($url_input)){ // utiliser une flash error - return new RedirectResponse((string)new URL(['page' => $_GET['from'], 'error' => 'invalide_url'])); + return new RedirectResponse((string)new URL(['page' => $request->query->get('from'), 'error' => 'invalide_url'])); } $page = new Page( - trim(htmlspecialchars($_POST["label_input"])), + trim(htmlspecialchars($request->request->get("label_input"))), $url_input, '', true, true, false, $previous_page->getPosition(), @@ -47,7 +49,7 @@ class MenuAndPathsController $entityManager->persist($page); $entityManager->flush(); - return new RedirectResponse((string)new URL(['page' => $_GET['from']])); + return new RedirectResponse((string)new URL(['page' => $request->query->get('from')])); } // on pourrait utiliser FormValidation ici @@ -62,7 +64,7 @@ class MenuAndPathsController elseif(!in_array($json['field'], ['url_name', 'url_content'])){ return new JsonResponse(['success' => false, 'message' => "champ invalide"]); } - elseif($json['field'] === 'url_content' && (!filter_var($url_data, FILTER_VALIDATE_URL) || !str_starts_with($url_data, 'http'))){ + elseif($json['field'] === 'url_content' && !Security::validateURL($url_data)){ return new JsonResponse(['success' => false, 'message' => "la chaîne envoyée n'est pas une URL valide"]); } else{ @@ -77,10 +79,10 @@ class MenuAndPathsController } } - static public function deleteUrlMenuEntry(EntityManager $entityManager): RedirectResponse + static public function deleteUrlMenuEntry(EntityManager $entityManager, Request $request): RedirectResponse { Model::$menu = new Menu($entityManager); - $page = Model::$menu->findPageById((int)$_POST["delete"]); + $page = Model::$menu->findPageById((int)$request->request->get("delete")); $parent = $page->getParent(); if($parent == null){ $parent = Model::$menu; @@ -91,7 +93,7 @@ class MenuAndPathsController $entityManager->remove($page); // suppression en BDD $entityManager->flush(); - return new RedirectResponse((string)new URL(['page' => $_GET['from']])); + return new RedirectResponse((string)new URL(['page' => $request->query->get('from')])); } static public function MoveOneLevelUp(EntityManager $entityManager, array $json): JsonResponse diff --git a/src/Controller/ViewController.php b/src/Controller/ViewController.php index 1f13861..5be4ffd 100644 --- a/src/Controller/ViewController.php +++ b/src/Controller/ViewController.php @@ -38,7 +38,8 @@ class ViewController{ else{ // mode création d'article // l'id du bloc et 'from=' sont vérifiés dans ArticleController::editorSubmit - if($request->query->get('id')[0] === 'n' && $request->query->has('from') && !empty($request->query->get('from'))){ + if(preg_match('/^n\d+\z/', $request->query->get('id')) // débute par 'n' puis des chiffres, \z au lieu de $ pour éviter un saut de ligne à la fin + && $request->query->has('from') && !empty($request->query->get('from'))){ NewBuilder::$new_article_mode = true; } } -- cgit v1.2.3