Date de publication: le mardi 22 novembre 2011 à 09h12
Dernière modification: par Pascal BOYER le mardi 22 novembre 2011 à 12h35
Introduction
This extension aims to stop any CSRF* (cross-fire request forgery) attack against eZ Publish. To accomplish that input and output filter events added in eZ Publish 4.5 "Matterhorn" is used to be able to verify all POST requests using a per user session form token.
Cette extension a pour objectif de stopper toute attaque de type CSRF* (cross-fire request forgery) porter contre les installations eZ Publish. Pour parvenir à ce résultat, le filtre des événements d'entrée et de sortie ajouté à eZ Publish 4.5 est utilisé pour vérifier toutes les requêtes POST grâce à un jeton de formulaire pour chaque session utilisateur.
This is all done transparently for html/xhtml forms, but requires changes to all Ajax POST code. The changes needed to eZ Publish are included in 4.5, and the last section in this documentation explains how you can modify your custom Ajax code to work with this extension.
Bien que tout ceci soit réalisé de manière transparente pour les formulaires html/xhtml, il n'en demeure pas moins nécessaire de modifier tous les codes Ajax POST. Quant aux modifications à apporter à eZ Publish, elles sont incluses dans la version 4.5. Le dernier paragraphe de cet article est consacré aux transformations de votre code Ajax à réaliser pour qu'il fonctionne avec l'extension.
If form token does not verify, an exception is currently thrown and an error 500 is send to the HTTP client.
Lorsque le jeton de formulaire ne remplit pas son rôle de contrôle, une exception est générée et une erreur 500 envoyée au client HTTP.
*Cross-fire Request Forgery is an attack which forces an end user to execute unwanted actions on a web application in which he/she is currently authenticated. With a little help of social engineering (like sending a link via email/chat), an attacker may force the users of a web application to execute actions of the attacker's choosing. A successful CSRF exploit can compromise end user data and operation in case of a normal user. If the targeted end user is the administrator account, this can compromise the entire web application.
* Le Cross-fire Request Forgery est une attaque visant à forcer un utilisateur final à exécuter, sur une application web auprès de laquelle il est authentifié, une action non souhaitée. Avec une petite aide de l'ingénierie sociale (comme l'envoi d'un lien via email/chat), un attaquant peut forcer les utilisateurs d'une application web à exécuter des actions que l'attaquant lui-même a déterminées/définies. Un exploit CSRF réussi peut compromettre les données d'un utilisateur final et le fonctionnement de l'application dans le cas d'un utilisateur normal. Lorsque la cible de l'attaque est un compte administrateur, cela peut même compromettre l'intégralité de l'application web.
Warning / Avertissement
Make sure you test this extension extensively with your custom solution before putting it into production on an existing installation.
Prenez soin de tester intensivement cette extension avec vos solutions personnalisées avant de la mettre en production sur votre installation.
Known issues (by design) / Problèmes connus (de conception)
-
Will break any custom Ajax POST code, see last section for how to modify your code.
L'extension cassera tout code Ajax POST - consultez le dernier paragraphe pour savoir comment modifier votre code.
-
Mis-configured reverse proxies or mis-configured “site.ini[HTTPHeaderSettings]” settings causing logged in user response to be cached will lead to situations where form tokens does not verify.
Un proxy inverse mal configuré ou une erreur dans la section [HTTPHeaderSettings] du fichier site.ini qui conduirait à la mise en cache des réponses de connexion des utilisateurs mèneront à des situations où les jetons de formulaires ne rempliront pas leur rôle.
Known issue / Problème connu
When the extension is enabled, a filter is applied to add an hidden span tag as the first child of body. This filter does not work if an attribute of the body contains the character ">".
Lorsque l'extension est activée, un filtre est appliqué pour ajouter une balise span cachée en tant que premier enfant de body. Ce filtre ne fonctionnera pas si un attribut de body contient le caractère «>». (???)
Install / Installation
-
Unzip/copy “ezfromtoken” into extension/ folder
Extraire et copier ezfromtoken dans le répertoire extension/
-
Re-generate autoloads for extensions using:
Régénérer les autochargements des extensions avec la commande:
php bin/php/ezpgenerateautoloads.php -e
-
Enable the extension by adding it to [ExtensionSettings]ActiveExtensions[] in settings/override/site.ini.php. Example:
Activer l'extension en l'ajoutant au tableau ActiveExtensions[] de la section [ExtensionSettings] du fichier settings/override/site.ini.php. Exemple:
[ExtensionSettings] ActiveExtensions[] ActiveExtensions[]=ezformtoken
Modify custom Ajax code / Modifier le code Ajax personnalisé
If your custom Ajax code only uses ezjscore jQuery.ez() or Y.io.ez(), you are already covered and don't need to look further. This section is about making sure code that uses Ajax functions directly on any library or natively includes the correct post form token if available.
Si votre code Ajax n'utilise que jQuery.ez() ou Y.io.ez() d'ezjscore, alors vous voilà déjà protégé et vous pouvez vous épargner la lecture de la suite de ce paragraphe dont l'objet est d'indiquer comment sécurisé du code qui, soit utilise des fonctions Ajax directement au-dessus d'une librairie, soit inclut nativement le jeton de formulaire post correct.
The output filter will do the following changes on the html code:
Le filtre de sortie apporte les modifications suivantes au code html:
-
Add a hidden input tag with name='ezxform_token' for all form tags that have a post method
Ajoute une balise span cachée avec name='ezxform_token' à l'intérieur de toutes les balises form associées à la méthode post.
-
Add a hidden tag with id='ezxform_token_js' after body tag that contains token in title attribute for Ajax use.
Ajoute une balise cachée avec id='ezxform_token_js' après la balise body contenant token dans l'attribut title pour l'utilisation d'Ajax.
-
Replaces any occurrence of @$ezxFormToken@ with form token.
Remplace toute occurrence de @$ezxFormToken@ par un jeton de formulaire.
This is done in such a way to ensure it has no negative impact on the eZ Publish cache. Only the eZ Publish response is covered, not external javascript/stylesheet/image files. Hence example #A below uses DOM to get token for Ajax post requests.
Using the hidden tag with id='ezxform_token_js' is the best option for Ajax code and it is explained in example #A. If your Ajax code is executed before body tag, then you will have to use option #3 as explained in example #B.
Ces modifications sont réalisées de façon à s'assurer qu'elles n'aient aucun impacte négatif sur le cache d'eZ Publish. Seule la réponse d'eZ Publish est couverte et non les fichiers externes javascript/stylesheet/image. L'exemple A ci-dessous utilise DOM pour obtenir le jeton pour les requêtes Ajax POST.
L'utilisation de la balise cachée avec id='ezxform_token_js' constitue la meilleure option pour du code Ajax et est expliquée par l'exemple A. Si votre code Ajax est exécuté avant la balise body, alors vous devrez utiliser l'option 3 détaillée par l'exemple B.
Exemples
A) Using DOM / Utilisation de DOM
Given code like this in template or javascript file:
Soit le code suivant présent dans un template ou un fichier javascript:
$.post( url, {}, function(){} );
Replace it with something like:
Remplacez-le par quelque chose comme ça:
var _token = '', _tokenNode = document.getElementById('ezxform_token_js'); if ( _tokenNode ) _token = 'ezxform_token=' + _tokenNode.getAttribute('title'); $.post( url, _token, function(){} );
B) Using form token replace string / (???)
Given code like this in your template before body tag:
Soit le code suivant présent dans votre template avant la balise body:
jQuery.post( url, {}, function(){} );
Replace it with something like:
Remplacez-le par quelque chose comme ça:
jQuery.post( url, 'ezxform_token=@$ezxFormToken@', function(){} );
Note: Example #B only works if code is inside a template that is part of (x)html output from eZ Publish.
Note: L'exemple B ne fonctionne que si le code est placé dans un template faisant partie de la sortie (x)html renvoyée par eZ Publish.
Commentaires














