{csrf}

The hidden form field holding the CSRF token of the visitor's session, or the bare token.

Forms and security Single tags

Syntax

{csrf}
{csrf token}

Options

token
Bare option: the token alone instead of the hidden field - for a script that sends it back in an X-CSRF-Token header.

Description

{csrf} writes <input type="hidden" name="padCsrfToken" value="..."> with the token of the visitor's session: 64 hex characters, made on first use - the session starts here when the visitor has none. A form carries it back, and padCsrfValid() in the page's PHP tells whether the request brought the session's token, in that field or an X-CSRF-Token header. {csrf token} is the bare token, for a script that sends the header itself.

The token is one per session, not one per form: two tabs and the back button keep working. A POST made from another site can make the browser send the session cookie, but cannot read the page to learn the token.

With $padCsrf = TRUE in the configuration every <form method="post"> that posts back to the site gets the field without asking, and every POST, PUT, PATCH or DELETE without the token is answered 403 before the application runs. A {form} writes the field by itself as well. {csrf} is for a form the page builds some other way, or for an application that checks posts itself.

The token differs per visitor, so a page holding one is never stored in the page cache, and the examples here are shown, not run.

Examples

The hidden field

A form the page writes as plain HTML carries the session's token back; padCsrfValid () checks it in the PHP.

Templateexamples/csrf/1-field.src
<form method="post" action="?orders/save">
  {csrf}
  <input name="number" value="1042">
  <button>Save</button>
</form>

{# renders: <input type="hidden" name="padCsrfToken" value="9f2c...64 hex characters..."> #}

The bare token for a script

{csrf token} is the token alone - a fetch sends it back in the X-CSRF-Token header.

Templateexamples/csrf/2-token.src
<meta name="csrf-token" content="{csrf token}">

<script>{ignore}
  const token = document.querySelector('meta[name="csrf-token"]').content;
  fetch('?orders/save', { method: 'POST', headers: { 'X-CSRF-Token': token }, body: new FormData(form) });
{/ignore}</script>

See also

  • {form} A form that posts back to the page, carrying the session's CSRF token and its own name, its fields refilling when it came back.
  • {nonce} This request's Content-Security-Policy nonce, for a script or style the policy lets run.