Protection Flow
User loads form
↓
Server creates CSRF token
↓
Token stored in session
↓
Token added to form as hidden field
↓
User submits form
↓
Server compares posted token
with session token
↓
Valid ------------------→ Continue request
Invalid or missing -----→ Reject request
What CSRF Means
CSRF stands for Cross-Site Request Forgery. It is a type of attack where a malicious site attempts to trick a user’s browser into submitting a request to your application without the user intentionally performing that action.
A CSRF token helps prove that the submitted form came from your real application page and not from an outside forged request.
The Big Idea
The framework places a secret token into each protected form. That token must match the one stored in the user’s session when the form is submitted. If it is missing or invalid, the request is rejected.
- Login
- Register
- Create Post
- Edit Post
- Delete Post
- Password Reset Requests
Step-by-Step Flow
1. The user opens a form page
A controller renders a form such as login, register, create post, or edit post. Before the form is submitted, the application ensures a CSRF token exists for that session.
2. The server creates or retrieves the token
The token is stored in the session and belongs to the current user session.
$_SESSION['csrf_token']
3. The token is added to the form
The form includes the token as a hidden field so it travels back to the server when the user submits.
<input type="hidden" name="csrf_token"
value="<?= htmlspecialchars($_SESSION['csrf_token'] ?? '') ?>">
Or through a helper:
<?= csrf_field() ?>
4. The user submits the form
The request includes both the visible form data and the hidden CSRF token.
5. The controller validates the token
Before processing the request, the controller compares the submitted token with the session token.
\App\Core\Csrf::validate('/posts/create');
6. The request is accepted or denied
If the token matches, the framework continues and processes the request.
If the token is missing or invalid, the framework stops the request and protects the action.
Example Protected Form Flow
GET /posts/create ↓ Render form with CSRF token ↓ User fills out form ↓ POST /posts ↓ Validate token ↓ Create post if valid
Responsibility in the Framework
Session = stores the token View = outputs the hidden token field Controller = validates the submitted token
This is a good example of MVC parts working together in a security feature.
What the Helper Improves
<?= csrf_field() ?>
Using a helper keeps forms cleaner and more consistent.
- Avoids repeating hidden input markup
- Reduces mistakes
- Keeps views cleaner
- Makes protection easier to apply across the app
What Happens on Failure
If validation fails, the framework should not continue processing the action.
- Show an error message
- Redirect the user
- Stop the request
- Avoid changing any data
Key Idea
A CSRF token is proof that the submitted form came from the real application page, not from a forged request somewhere else.
Snapshot Summary
- The server creates a CSRF token
- The token is stored in the session
- The form includes the token as a hidden field
- The submitted token is checked by the controller
- Valid tokens allow processing
- Missing or invalid tokens stop the request