CSRF Protection
The documentation is constantly evolving and updated alongside the project's progress. Since it is developed in parallel with the code, some sections may temporarily refer to earlier versions of the system-these are gradually adapted to the current state of the application. If you notice any outdated information, please report it or open an Issue / Pull Request.
Documentation
# CSRF Protection
Cross-Site Request Forgery (CSRF) protection helps prevent a third-party site from causing a user's browser to submit an unwanted request to your application.
DBM Framework provides CsrfTokenManager for validating a submitted
token against the token stored in the current session. The manager
validates tokens; it does not generate them. In templates, use
getCsrfToken() to obtain a token for a form.
# How it works
- Render a form and include a CSRF token in a hidden field.
- The browser submits the token with the form.
- The controller validates the submitted token using
CsrfTokenManager.
- Reject the request if the token is missing, invalid, or expired.
- Continue with the requested operation only after validation
succeeds.
# 1. Add a token to the form
Use the template helper getCsrfToken():
<form method="POST" action="/example/submit">
<input
type="hidden"
name="csrf_token"
value="{{ $this->getCsrfToken() }}"
>
<button type="submit">Submit</button>
</form>
The helper reads the token from the session and creates one when it is missing or expired. In the current implementation, the token is refreshed after 15 minutes.
Session support must be enabled, and the session must be available when the template is rendered and when the request is validated. Configure the application's session handling or session middleware accordingly.
# 2. Validate the token in the controller
Inject CsrfTokenManager and validate the submitted value before
processing the form:
use Dbm\Http\Controller\BaseController;
use Dbm\Security\CsrfTokenManager;
use Psr\Http\Message\ResponseInterface;
final class ExampleController extends BaseController
{
public function __construct(
private readonly CsrfTokenManager $csrf,
) {}
public function submit(): ResponseInterface
{
$token = $this->request()->getPost('csrf_token');
if (!is_string($token) || !$this->csrf->isValid($token)) {
// Reject the request; do not perform the requested operation.
return $this->redirect('example_form');
}
// Process the submitted data only after CSRF validation succeeds.
// ...
return $this->redirect('example_form');
}
}
Replace example_form with a route name registered by your application.
The example redirects after an invalid token; applications may instead
return an HTTP 403 response using their configured response-handling
approach. If you use a flash message, keep the message generic and ask
the user to reload the form.
CsrfTokenManager::isValid() returns true only when the supplied
token is a string and matches the token stored in the session. The
comparison uses hash_equals().
# Important security notes
- Validate the token before performing any operation that changes
application state.
- Do not put CSRF tokens in URLs.
- Use POST (or another appropriate non-safe HTTP method) for
state-changing form submissions; do not change application state through GET requests.
- CSRF validation does not authenticate the user and does not
authorize an operation. Protect the route with the application's authentication and permission checks as well.
- Keep session handling consistent between token generation and
validation.
- A token can expire. If validation fails, ask the user to reload the
form and submit it again.
- CSRF tokens are one part of a broader security design; they do not
replace input validation, output escaping, or route access control.
# Related documentation
- Security Components --- security
helpers, permissions, JWT, passwords, and rate limits.
- Template Features --- template helpers,
including getCsrfToken().
Keep relative links aligned with the actual filenames used by your documentation site.