A02: Security Misconfiguration
What is security misconfiguration?
Security Misconfiguration is when an application is deployed with unsafe settings or exposed internal tooling.
In Laravel this often means debug is enabled, cookies/sessions are not hardened, dev/admin panels are publicly reachable, or CORS / proxy / Sanctum stateful domains are configured too loosely.
Typical Laravel failure
APP_ENV=localin production.APP_DEBUG=truein production.- Weak cookie/session settings.
- Exposed Horizon, Telescope, debug routes, or storage.
- Bad CORS / trusted proxy / stateful domain configuration.
- Default settings left untouched.
Impact
- Sensitive information disclosure (debug pages, stack traces, environment leakage).
- Unauthorized access to internal tooling (Horizon/Telescope) and operational data.
- Session compromise risk (weak cookie flags, missing HTTPS-only cookies).
- Cross-origin auth bypass or CSRF-like issues via sloppy CORS/Sanctum stateful domains.
- Expanded attack surface that turns minor bugs into full compromise.
Laravel 12 remediation
Production must have APP_ENV=production and APP_DEBUG=false.
- Review
config/session.php,config/cors.php,config/sanctum.php,config/logging.php. - Lock down admin/dev tools by environment and authorization.
- Use secure cookies:
secure,http_only,same_site, HTTPS-only. - Define exact Sanctum first-party domains (
SANCTUM_STATEFUL_DOMAINS).
Laravel documents configurable logging channels and security-related configuration surfaces, and Sanctum requires explicit stateful domain configuration for first-party requests.
Concrete fix (blog)
Start in .env (production-safe baseline):
APP_ENV=productionAPP_DEBUG=false # Cookies / sessionSESSION_SECURE_COOKIE=trueSESSION_HTTP_ONLY=trueSESSION_SAME_SITE=lax # Sanctum (SPA / first-party)SANCTUM_STATEFUL_DOMAINS=app.example.com # CORS (lock down to your real frontend origins)CORS_ALLOWED_ORIGINS=https://app.example.comCORS_SUPPORTS_CREDENTIALS=true
Then harden the relevant config surfaces.
config/session.php
Secure cookie flags (avoid relying on defaults):
// config/session.php 'secure' => env('SESSION_SECURE_COOKIE', env('APP_ENV') === 'production'),'http_only' => env('SESSION_HTTP_ONLY', true),'same_site' => env('SESSION_SAME_SITE', 'lax'),
config/cors.php
Lock CORS to your real frontend origins. If you use Sanctum cookies, you typically need credentials enabled.
// config/cors.php 'paths' => ['api/*', 'sanctum/csrf-cookie'],'allowed_origins' => ['https://app.example.com'],'supports_credentials' => true,
config/sanctum.php
Make first-party cookie auth explicit (do not allow wide patterns or "*" domains):
// config/sanctum.php 'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', 'app.example.com')),
config/logging.php
Keep logging configurable, but avoid leaking secrets and avoid noisy debug in production.
// config/logging.php 'default' => env('LOG_CHANNEL', 'stack'),
LOG_CHANNEL=stackLOG_LEVEL=warning