Alpha ZealPHP is early-stage and under active development. APIs may change between minor versions until v1.0. Feedback and bug reports welcome on GitHub.
API Index — Namespaces, Packages, Reports, Indices

CsrfMiddleware
in package
implements MiddlewareInterface

FinalYes

CSRF Protection Middleware.

Generates a per-session CSRF token on safe requests (GET/HEAD/OPTIONS) and validates it on state-changing requests (POST/PUT/PATCH/DELETE).

Token sources checked (first match wins):

  1. $_POST['_csrf_token'] (form hidden field)
  2. X-CSRF-Token request header (AJAX/htmx)

The token is stored in $g->session['_csrf_token'] and exposed via $g->memo['csrf_token'] for templates to read.

Usage in app.php:

$app->addMiddleware(new CsrfMiddleware());

In templates:

<input type="hidden" name="_csrf_token" value="<?= $g->memo['csrf_token'] ?>">

With htmx:

<body hx-headers='{"X-CSRF-Token": "<?= $g->memo['csrf_token'] ?>"}'>

To exempt paths (e.g. webhooks):

$app->addMiddleware(new CsrfMiddleware(exempt: ['/api/webhook', '/api/stripe']));

Table of Contents

Interfaces

MiddlewareInterface

Constants

FIELD_NAME  : mixed = '_csrf_token'
HEADER_NAME  : mixed = 'X-CSRF-Token'
SAFE_METHODS  : mixed = ['GET', 'HEAD', 'OPTIONS']
TOKEN_LENGTH  : mixed = 32

Properties

$exempt  : array<int, string>

Methods

__construct()  : mixed
process()  : ResponseInterface
Generate or validate the CSRF token for the current request.
pathMatchesExempt()  : bool
Segment-boundary exemption match (#342).

Constants

SAFE_METHODS

private mixed SAFE_METHODS = ['GET', 'HEAD', 'OPTIONS']

Properties

$exempt

private array<int, string> $exempt

URL path prefixes that skip CSRF validation.

Methods

__construct()

public __construct([array<int, string> $exempt = [] ]) : mixed
Parameters
$exempt : array<int, string> = []

URL prefixes to skip validation (e.g. ['/api/webhook']).

process()

Generate or validate the CSRF token for the current request.

public process(ServerRequestInterface $request, RequestHandlerInterface $handler) : ResponseInterface

Safe methods (GET/HEAD/OPTIONS) and exempt path prefixes pass through without validation. All other methods require a matching token submitted via the _csrf_token POST field or the X-CSRF-Token header; a mismatch or missing token returns a 403 response immediately.

Parameters
$request : ServerRequestInterface
$handler : RequestHandlerInterface
Return values
ResponseInterface

pathMatchesExempt()

Segment-boundary exemption match (#342).

private static pathMatchesExempt(string $path, string $prefix) : bool

An exempt entry exempts the request path only on an exact match or a true path-segment boundary — NOT a loose str_starts_with prefix. So '/api/stripe' exempts /api/stripe and /api/stripe/charge, but NEVER /api/stripeKeyUpdate (the historical CSRF-bypass: an attacker appended text to an exempt prefix to skip validation on a sibling state-changing route). Same class of fix as the #232 ScopedMiddleware segment-safe scope. A trailing-slash entry ('/api/stripe/') keeps its prefix semantics for the subtree below it (the next char after the prefix is already the / boundary).

Parameters
$path : string
$prefix : string
Return values
bool
On this page