GitHub

CSRF Protection

The TinyMVC framework provides built-in CSRF (Cross-Site Request Forgery) protection middleware to secure your application against malicious requests.

CSRF Middleware Configuration

The framework comes with a base CSRF middleware that can be extended. The default configuration is located at:

app/Http/Middlewares/CsrfProtectionMiddleware.php

Example configuration:

<?php

namespace App\Http\Middlewares;

use Spark\Foundation\Http\Middlewares\CsrfProtection;

class CsrfProtectionMiddleware extends CsrfProtection
{
    /**
    * URIs that should be excluded from CSRF verification
    * @var array
    */
    protected array $except = [
        '/api/*' // Exclude all API routes from CSRF protection
    ];
}

Registering CSRF Middleware

The middleware is registered in bootstrap/middlewares.php:

return [
    'csrf' => \App\Http\Middlewares\CsrfProtectionMiddleware::class,
    // Other middlewares...
];

Global Registration

To apply CSRF protection to all routes, register it globally in bootstrap/app.php:

->withMiddleware(function (Middleware $middleware) {
    $middleware->merge(require __DIR__ . '/middlewares.php');
    $middleware->queue(['csrf']);
})

Route-Specific Registration

To apply CSRF protection to specific routes:

// Single route
Route::post('/profile/create', CreateUserProfile::class)->middleware('csrf');

// Route group
Route::group(['middleware' => ['csrf']], function() {
    Route::post('/profile/create', CreateUserProfile::class);
});

Working with CSRF Tokens

The framework provides helper functions for CSRF tokens:

Helper Description Example
csrf_token() Returns the current CSRF token <?= csrf_token() ?>
csrf() Generates a hidden input field with the CSRF token <?= csrf() ?>

Form Example

<form method="POST" action="/submit">
    <?= csrf() ?>
    <!-- Other form fields -->
    <button type="submit">Submit</button>
</form>

AJAX Requests

For AJAX requests using Axios, the framework automatically handles CSRF protection:

  • The encrypted CSRF token is stored in a cookie named XSRF-TOKEN
  • Axios automatically reads this cookie and includes it in requests as X-XSRF-TOKEN header
  • No additional configuration is needed for Axios requests
Note: The CSRF token cookie is HttpOnly and Secure when served over HTTPS.

CORS Middleware

The framework includes a CORS (Cross-Origin Resource Sharing) middleware for handling cross-origin requests, particularly useful for APIs.

CORS Middleware Configuration

The default CORS middleware is located at:

app/Http/Middlewares/CorsControlMiddleware.php

Example configuration:

<?php

namespace App\Http\Middlewares;

use Spark\Foundation\Http\Middlewares\CorsAccessControl;

class CorsControlMiddleware extends CorsAccessControl
{
    protected array $allowed = [
        'origin' => '*',
        'methods' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
        'headers' => ['Content-Type', 'Authorization', 'X-Requested-With'],
        'credentials' => 'true',
        'age' => 86400,
    ];
}

Configuration Options

Option Description Default
origin Allowed origins (use '*' for all or specify domains) *
methods Allowed HTTP methods ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS']
headers Allowed headers ['Content-Type', 'Authorization', 'X-Requested-With']
credentials Whether to allow credentials true
age Max age of the CORS preflight request (seconds) 86400 (24 hours)

Registering CORS Middleware

Similar to CSRF middleware, CORS middleware can be registered:

Global Registration

->withMiddleware(function (Middleware $middleware) {
    $middleware->merge(require __DIR__ . '/middlewares.php');
    $middleware->queue(['cors']);
})

Route-Specific Registration

// API route group
Route::group(['middleware' => ['cors']], function() {
    Route::get('/api/data', ApiController::class);
});
Best Practice: For API routes, you might want to disable CSRF protection (as shown in the CSRF middleware's $except array) while enabling CORS middleware.

Combining CSRF and CORS

For web routes that need both CSRF protection and CORS:

Route::group(['middleware' => ['csrf', 'cors']], function() {
    // Your routes here
});