NAME
Mojolicious::Plugin::Fondation::CSRF - CSRF protection plugin for Fondation — route condition, OpenAPI integration, JS injection
VERSION
version 0.01
SYNOPSIS
# In myapp.conf
plugin 'Fondation' => {
dependencies => [
'Fondation::SessionStore', # sessions required for CSRF tokens
'Fondation::CSRF',
],
};
# Per-route opt-in (when auto_protect is disabled):
$r->post('/secure-action')->requires('fondation.csrf')->to('mycontroller#action');
# With exemptions:
'Fondation::CSRF' => {
auto_protect => 1,
exemptions => [qr{^/webhook/}, qr{^/api/public/}],
},
DESCRIPTION
Mojolicious::Plugin::Fondation::CSRF provides Cross-Site Request Forgery
protection for Fondation applications. It uses Mojolicious' built-in CSRF
token mechanism (stored in session, validated via "csrf_protect" in Validation).
Three protection layers, all using the same underlying Mojo validation:
-
- Route condition
fondation.csrf— explicit opt-in on any route
- Route condition
-
- OpenAPI auto-protection — POST/PUT/PATCH/DELETE routes generated
by Fondation::OpenAPI automatically get
requires('fondation.csrf')
- OpenAPI auto-protection — POST/PUT/PATCH/DELETE routes generated
by Fondation::OpenAPI automatically get
-
around_dispatchblanket protection — all mutating requests (POST/PUT/PATCH/DELETE) are checked unless the path matches an exemption
Token transmission works two ways, both handled automatically by Mojo:
- Form field
csrf_token— standard HTML forms via "csrf_field" in TagHelpers - Header
X-CSRF-Token— AJAX requests (the plugin provides a JS zone that reads the CSRF meta tag and patchesfetchandXMLHttpRequest)
CONFIGURATION
-
auto_protect
Enable/disable the
around_dispatchblanket protection. Default:1(enabled). Set to0to use only explicit route conditions. -
exemptions
Arrayref of regex patterns. Paths matching any pattern are skipped by
around_dispatch. Useful for webhooks, public API endpoints, etc. Default:[](no exemptions).
DEPENDENCIES
Mojolicious::Plugin::Fondation.
Sessions must be enabled (Fondation::SessionStore or Mojolicious' default
signed cookies). The CSRF token lives in $c->session->{csrf_token}.
STATIC JS FILE
The plugin ships share/public/js/csrf.js — a standalone script that
reads the CSRF token from <meta name="csrf-token"> and auto-injects
it as X-CSRF-Token header on all fetch and XMLHttpRequest
POST/PUT/PATCH/DELETE calls.
Add it to your assetpack.def:
< js/csrf.js
Or include it directly in your layout:
<script src="/js/csrf.js"></script>
The meta tag must be present in the page. Fondation::Layout-Bootstrap provides it by default:
<meta name="csrf-token" content="<%= csrf_token %>">
END-TO-END FLOW
When the CSRF plugin is loaded alongside the standard Fondation stack (Layout-Bootstrap, Asset, OpenAPI, Auth), protection works automatically:
-
- Layout-Bootstrap injects
<meta name="csrf-token">in<head>.
- Layout-Bootstrap injects
-
csrf.js(loaded via AssetPack bundle or<script src>) patchesfetchandXMLHttpRequestto injectX-CSRF-Tokenon all mutating AJAX calls.
-
- HTML forms (login, etc.) include
<%= csrf_field %>to embed the token as a hidden field.
- HTML forms (login, etc.) include
-
- OpenAPI routes (POST/PUT/PATCH/DELETE) automatically get
requires('fondation.csrf')via theopenapi_routes_addedhook.
- OpenAPI routes (POST/PUT/PATCH/DELETE) automatically get
-
- HTML POST routes are protected by
around_dispatchwhenauto_protectis enabled (default), or by explicitrequires('fondation.csrf').
- HTML POST routes are protected by
-
- Mojo's
csrf_protectvalidates the token from form field orX-CSRF-Tokenheader against the session token.
- Mojo's
HOW TOKEN VALIDATION WORKS
The route condition and around_dispatch both delegate to Mojo's
csrf_protect validation:
-
- Mojo generates a unique token on first session access
-
- Token is stored in
$c->session->{csrf_token}
- Token is stored in
-
- Client sends the token back (form field or
X-CSRF-Tokenheader)
- Client sends the token back (form field or
-
csrf_protectcompares the submitted token with the session token
-
- Mismatch → validation error
csrf_token→ 403
- Mismatch → validation error
SEE ALSO
Mojolicious::Plugin::Fondation, Mojolicious::Plugin::Fondation::OpenAPI, Mojolicious::Guides::Routing, Mojolicious::Validator::Validation
AUTHOR
Daniel Brosseau dab@cpan.org
COPYRIGHT AND LICENSE
This software is copyright (c) 2026 by Daniel Brosseau.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.