Web Security
Beginner
1 min read
Configuring Access-Control Headers Securely
Example
<?php
// Laravel: secure CORS configuration via fruitcake/laravel-cors (included since L8)
// config/cors.php
return [
'paths' => ['api/*', 'sanctum/csrf-cookie'],
// SECURE: explicit allowlist — never use '*' with credentials
'allowed_origins' => [
'https://app.example.com',
'https://admin.example.com',
],
// Dynamic origin validation (more flexible for multi-tenant apps)
'allowed_origins_patterns' => [
// '/^https:\/\/[\w-]+\.example\.com$/', // any subdomain of example.com
],
'allowed_methods' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
'allowed_headers' => ['Content-Type', 'Authorization', 'X-Requested-With'],
'exposed_headers' => ['X-RateLimit-Remaining', 'X-RateLimit-Limit'],
'max_age' => 86400,
'supports_credentials' => true, // Required for cookie-based auth; disallows '*' origin
];
// Middleware stack in bootstrap/app.php:
// ->withMiddleware(function (Middleware $middleware) {
// $middleware->api(prepend: [
// \Illuminate\Http\Middleware\HandleCors::class,
// ]);
// })
// Manual CORS headers (for reference / non-Laravel contexts):
// header('Access-Control-Allow-Origin: https://app.example.com');
// header('Access-Control-Allow-Credentials: true');
// header('Vary: Origin');
// header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
// header('Access-Control-Allow-Headers: Content-Type, Authorization');
// header('Access-Control-Max-Age: 86400');
Related Resources
Web Security Reference
Complete tag & property list
Web Security How-To Guides
Step-by-step practical guides
Web Security Exercises
Practice what you've learned
More in Web Security