Skip to the content
Documentation
Help Start
Reading in:
  • German: 9,059 of 9,059 pages
About the help in other languages
All help pages

ezformtoken and CSRF protection

How ezformtoken protects every POST of a signed-in user against request forgery - the token in forms and the page head, the X-CSRF-Token header, the 403 refusal - and what your extension does.

Download as PDF

Address: https://doc.exponential.earth/exphelp/viewer/help/extension-development/part-8-reference/ezformtoken-and-csrf.md

On this page

ezformtoken and CSRF protection

Part 8, reference 20. Cross-site request forgery (CSRF) is another site making a signed-in user's browser send a POST to your site. The ezformtoken extension shipped with the kernel stops it with a secret token per session. Most of the time it works without your extension doing anything; this page says when it does not, and what to do.

How it works

The extension registers three listeners (its settings/site.ini.append.php):

EventMethodDoes
response/outputezxFormToken::output()adds a hidden field ezxform_token to every <form> of an HTML page, and meta tags csrf-param and csrf-token (with the ID ezxform_token_js) to <head>
request/inputezxFormToken::input()refuses a POST without the right token
session/regenerateezxFormToken::reset()a new token with a new session

Only signed-in users with a session are protected (anonymous visitors have nothing to steal), and only POST requests are checked.

Where the token is looked for

On a POST, input() takes the token from, in this order:

  1. the POST field (ezxform_token, or the field name configured);
  2. the HTTP header X-CSRF-Token, for Ajax requests that post JSON or XML.

A missing or wrong token ends the request with a 403 refusal (a JSON body for Ajax and JSON requests).

What your extension does

SituationWhat to do
A <form method="post"> in a templatenothing: the output filter adds the field
A form built by JavaScriptadd a hidden ezxform_token field with the value of the csrf-token meta tag
An Ajax POST with form datasend ezxform_token; Exp.io.call() and ezjscore's $.ez() do it for you
An Ajax POST with a JSON bodysend the header X-CSRF-Token with the token
A view that changes data on GETchange it to POST: GET is never checked
A JSON page answered by your viewthe token is only added to HTML pages; read it from the page that makes the call

In PHP, ezxFormToken::getToken() returns the current session's token, for templates you render outside the normal output (a dialog fetched by Ajax, for example):

<?php
$tpl = eZTemplate::factory();
$tpl->setVariable( 'ezxform_token', ezxFormToken::getToken() );

Reading the token in JavaScript

var meta = document.querySelector( 'meta[name="csrf-token"]' );
var token = meta ? meta.getAttribute( 'content' ) : '';
fetch( '/myext/save', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': token },
    body: JSON.stringify( { name: 'Ada' } ),
    credentials: 'same-origin'
} );

Never switch it off

ezxFormToken::setIsEnabled( false ) exists for special cases inside the kernel. An extension that disables the protection to make its own form work opens every POST of the site to forgery. Fix the form instead.

Become an Exponential Partner

Partners share their information, provide funding, contribute back and develop the products with us, and that is how Exponential grows. A partner website and dashboard are planned for mid-2027: please become a partner today to speed up our growth rate and land new features faster.

Something wrong on this page? Report an error

Documentation license

This documentation is free documentation, licensed under the GNU Free Documentation License 1.3 or later.

Exponential Copyright © 1998-2026 Exponential Foundation and 7x