Zend Basic Tutorial
Zend Forms
Zend Database
Zend Advanced
CSRF (Cross-Site Request Forgery) is an attack where a malicious site tricks a logged-in user into submitting a request to a different site (e.g., transferring money, changing password) without their consent.
Zend Framework uses a hidden CSRF token field in forms to validate that the request is legitimate.
composer require laminas/laminas-session
<?php
declare(strict_types=1);
namespace Application\Form;
use Laminas\Form\Form;
use Laminas\Form\Element\Csrf;
class LoginForm extends Form
{
public function __construct($name = null)
{
parent::__construct('login');
$this->add([
'name' => 'email',
'type' => 'Text',
'options' => ['label' => 'Email'],
]);
// ✅ CSRF Token Field
$this->add([
'type' => Csrf::class,
'name' => 'csrf',
'options' => [
'csrf_options' => [
'timeout' => 600, // Token valid for 10 minutes
],
],
]);
$this->add([
'name' => 'password',
'type' => 'Password',
'options' => ['label' => 'Password'],
]);
$this->add([
'name' => 'submit',
'type' => 'Submit',
'attributes' => [
'value' => 'Login',
'class' => 'btn btn-primary'
],
]);
}
}
use Application\Form\LoginForm;
use Laminas\View\Model\ViewModel;
public function homeAction()
{
$form = new LoginForm();
$request = $this->getRequest();
if ($request->isPost()) {
$form->setData($request->getPost());
if ($form->isValid()) {
$data = $form->getData();
dd($data);
// Proceed (e.g., create user)
} else {
// $form->getMessages() contains validation errors
}
}
return new ViewModel(['form' => $form]);
}
<?= $this->form()->openTag($form) ?>
<?= $this->formRow($form->get('email')) ?>
<?= $this->formRow($form->get('csrf')) ?> <!-- 🛡️ CSRF Token -->
<?= $this->formRow($form->get('password')) ?>
<?= $this->formSubmit($form->get('submit')) ?>
<?= $this->form()->closeTag() ?>
Laminas\Validator\Csrfnamespace Application;
use Laminas\Mvc\MvcEvent;
use Laminas\Session\SessionManager;
use Laminas\Session\Container;
class Module
{
public function onBootstrap(MvcEvent $e)
{
$sessionManager = new SessionManager();
$sessionManager->start(); // ✅ This replaces session_start()
// ✅ Set as default session manager for all containers
Container::setDefaultManager($sessionManager);
}
public function getConfig()
{
return include __DIR__ . '/../config/module.config.php';
}
}
use Laminas\Session\Container;
public function homeAction()
{
$request = $this->getRequest();
if ($request->isPost()) {
$postedToken = $request->getPost('csrf');
$container = new Container('csrf');
// 🛡️ Validate CSRF manually
if ($postedToken === $container->token) {
// ✅ Valid CSRF
$password = $request->getPost('password');
$email = $request->getPost('email');
// ... Save or process the data ...
return new ViewModel(['message' => 'Form submitted successfully']);
}else{
// ❌ Invalid CSRF
return new ViewModel(['error' => 'Invalid CSRF token']);
}
}
// For GET: show the form
$container = new Container('csrf');
$token = bin2hex(random_bytes(32));
$container->token = $token;
return new ViewModel([
'csrf_token' => $token,
]);
}
<?php if (isset($csrf_token)): ?> <form method="POST" action=""> <label>Email: <input type="email" name="email"></label><br> <label>Password: <input type="password" name="password"></label><br> <!-- 🛡️ CSRF Token --> <input type="hidden" name="csrf" value="<?= $this->escapeHtmlAttr($csrf_token) ?>"> <button type="submit">Submit</button> </form> <?php elseif(isset($message)): ?> <h1><?= $message ?></h1> <?php else: ?> <h1><?= $error ?></h1> <?php endif; ?>
|
Use Case |
Why CSRF Matters |
|---|---|
|
User Registration |
Prevent fake/auto form submissions |
|
Payment Gateways |
Prevent unwanted charges or redirects |
|
Admin Panel |
Block unauthorized POST/DELETE requests |
|
API Tokens |
Protect sensitive data update forms |