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\Csrf
namespace 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 |