Le Component FormProtection fournit une protection contre l’altération des données de formulaire.
Comme tous les components, il dispose de plusieurs paramèters de configuration.
Chacune de ces propriétés peut être définie directement ou par des setters du
même nom, dans les méthodes initialize()
ou beforeFilter()
de votre
controller.
Si vous utilisez d’auutres components qui traitent des données de formulaire
dans leurs callbacks startup()
, veillez à placer le Component FormProtection
avant ceux-ci dans votre méthode initialize()
.
Note
Quand vous utilisez le Component FormProtection vous devez utiliser le
FormHelper pour créer vos formulaires. De plus, vous ne devez pas
réécrire les attributs « name » des champs. Le Component FormProtection
observe certains indicateurs créés et gérés par le FormHelper (en
particulier ceux qui sont créés dans
create()
et
end()
). L’altération dynamique
des champs soumis dans une requête POST (par exemple désactiver, supprimer
ou créer de nouveaux champs via JavaScript) est susceptible d’entraîner
l’échec de validation du jeton de formulaire.
Par défaut, le FormProtectionComponent
empêche certaines altérations de
formulaire par les utilisateurs. Il les empêche:
de modifier l’action du formulaire (URL)
d’ajouter des champs inconnus
de supprimer des champs du formulaire
de modifier des valeurs dans des inputs cachés.
La prévention de ces altérations fonctionne en collaboration avec le
FormHelper
, et consiste à tracer les champs du formulaire. Les valeurs des
champs cachés sont également tracées. Toutes ces données sont hachées, et des
jetons cachés sont insérés automatiquement dans le formulaire. Quand le
formulaire est transmis, le FormProtectionComponent
utilise les données POST
pour reconstruire la même structure et comparer le hash.
Note
Le FormProtectionComponent n’empêchera pas l’ajout et la modification d’options dans les select. Il n’empêchera pas non plus l’ajout ou la modification d’options radio.
La configuration du component security se fait générallement dans les callbacks
initialize()
ou beforeFilter()
du controller.
Les options possibles sont:
Définir à false
pour passer complètement la validation des requêtes
POST, désactivant de fait l’essentiel de la validation de formulaires.
Défini comme une liste de champs à exclure de la validation POST. Les champs
peuvent être déverrouillés (unlocked) soit dans le Component, soit avec
FormHelper::unlockField()
. Les champs déverrouillés peuvent être
absents du POST et les valeurs des champs cachés déverrouillés ne sont pas
vérifiées.
Actions à exclure des vérifications de validation de POST.
Callback à appeler en cas d’échec de validation. Doit être une Closure valide. Non défini par défaut, auquel cas une exception est lancée en cas d’échec de validation.
namespace App\Controller;
use App\Controller\AppController;
use Cake\Event\EventInterface;
class WidgetsController extends AppController
{
public function initialize(): void
{
parent::initialize();
$this->loadComponent('FormProtection');
}
public function beforeFilter(EventInterface $event)
{
parent::beforeFilter($event);
if ($this->request->getParam('prefix') === 'Admin') {
$this->FormProtection->setConfig('validate', false);
}
}
}
L’exemple ci-dessus désactiverait la prévention d’altération de formulaire pour
les routes préfixées par Admin
.
Il peut y avoir des cas dans lesquels vous voudrez désactiver la prévention
d’altération de formulaire pour une action (par exemple des requêtes AJAX). Vous
pouvez « déverrouiller » ces actions en les listant dans
$this->Security->unlockedActions
dans votre beforeFilter()
:
namespace App\Controller;
use App\Controller\AppController;
use Cake\Event\EventInterface;
class WidgetController extends AppController
{
public function initialize(): void
{
parent::initialize();
$this->loadComponent('FormProtection');
}
public function beforeFilter(EventInterface $event)
{
parent::beforeFilter($event);
$this->FormProtection->setConfig('unlockedActions', ['edit']);
}
}
Cet exemple désactiverait toutes les vérifications de sécurité pour l’action
edit
.
Si la validation de protection du formulaire échoue, elle renverra par défaut
une erreur 400. Vous pouvez configurer ce comportement en définissant l’option
de configuration validationFailureCallback
vers une fonction callback du
controller.
En configurant une méthode de callback, vous pouvez personnaliser le mode de fonctionnement de la gestion d’erreur:
public function beforeFilter(EventInterface $event)
{
parent::beforeFilter($event);
$this->FormProtection->setConfig(
'validationFailureCallback',
function (BadRequestException $exception) {
// Vous pouvez soit renvoyer une instance response, soit lever
// l'exception reçue en argument.
}
);
}