Path

ez.no / documentation / ez publish / technical manual / 4.6 / features / ez form token extension


Caution: This documentation is for eZ Publish legacy, from version 3.x to 5.x.
For 5.x documentation covering Platform see eZ Documentation Center, for difference between legacy and Platform see 5.x Architecture overview.

eZ Form token extension

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.

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.

If form token does not verify, an exception is currently thrown and an error 500 is send to the HTTP client.

*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.

Warning

Make sure you test this extension extensively with your custom solution before putting it into production on an existing installation.

Known issues (by design)

  • Will break any custom Ajax POST code, see last section for how to modify your 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.

Known issue

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 ">".

Install

  • Unzip/copy “ezfromtoken” into extension/ folder
  • Re-generate autoloads for extensions using:
$ php bin/php/ezpgenerateautoloads.php -e
  • Enable the extension by adding it to [ExtensionSettings]ActiveExtensions[] in settings/override/site.ini.php. Example:
[ExtensionSettings] ActiveExtensions[] ActiveExtensions[]=ezformtoken

Modify custom Ajax code

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.

The output filter will do the following changes on the html code:

  • Add a hidden input tag with name='ezxform_token' for all form tags that have a post method
  • Add a hidden tag with id='ezxform_token_js' after body tag that contains token in title attribute for Ajax use.
  • Replaces any occurrence of @$ezxFormToken@ with form token.

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.

Examples:

A) Using DOM:

Given code like this in template or javascript file:

$.post( url, {}, function(){} );

Replace it with something like:

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:

jQuery.post( url, {}, function(){} );

Replace it with something like:

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.

Geir Arne Waaler (20/09/2011 1:16 pm)

Geir Arne Waaler (20/09/2011 2:08 pm)


Comments

There are no comments.