### Install via Composer Source: https://github.com/jeffersongoncalves/laravel-security-headers/blob/master/README.md Install the package via Composer. ```bash composer require jeffersongoncalves/laravel-security-headers ``` -------------------------------- ### Skip a header by setting null in config Source: https://github.com/jeffersongoncalves/laravel-security-headers/blob/master/resources/boost/skills/security-headers-development/SKILL.md Set a header value to null in the config to omit it from the response. This example omits X-Frame-Options. ```php 'headers' => [ 'X-Frame-Options' => null, // omitted from the response ], ``` -------------------------------- ### Publish laravel-security-headers config Source: https://github.com/jeffersongoncalves/laravel-security-headers/blob/master/resources/boost/skills/security-headers-development/SKILL.md Publishes the package configuration file (config/laravel-security-headers.php) to the application's config directory. Use this after installation to customize headers, CSP directives, and HSTS settings. ```bash php artisan vendor:publish --tag="laravel-security-headers-config" ``` -------------------------------- ### Run tests, coverage, static analysis, and formatting Source: https://github.com/jeffersongoncalves/laravel-security-headers/blob/master/resources/boost/skills/security-headers-development/SKILL.md Commands to run the test suite, generate coverage, perform static analysis with PHPStan, and format code with Pint. ```bash # Run all tests vendor/bin/pest # Run with coverage vendor/bin/pest --coverage # Static analysis vendor/bin/phpstan analyse # Code formatting vendor/bin/pint ``` -------------------------------- ### Publish Config File Source: https://github.com/jeffersongoncalves/laravel-security-headers/blob/master/README.md Publish the package configuration file. ```bash php artisan vendor:publish --tag="security-headers-config" ``` -------------------------------- ### Configure HSTS with max-age, include-subdomains, and preload Source: https://github.com/jeffersongoncalves/laravel-security-headers/blob/master/resources/boost/skills/security-headers-development/SKILL.md Configure HSTS. Output is 'max-age=' plus '; includeSubDomains' and/or '; preload' when those flags are truthy. Never emitted on insecure requests or in local environment. ```php 'hsts' => [ 'enabled' => true, 'max-age' => 31536000, 'include-subdomains' => true, 'preload' => true, ], ``` -------------------------------- ### Run tests with composer test Source: https://github.com/jeffersongoncalves/laravel-security-headers/blob/master/README.md Run the test suite for the package. ```bash composer test ``` -------------------------------- ### Configure CSP report-only mode and violation reporting Source: https://github.com/jeffersongoncalves/laravel-security-headers/blob/master/README.md Enable report-only mode to emit Content-Security-Policy-Report-Only instead of the enforcing header. report-uri and report-to are appended as CSP directives when non-null. ```php 'csp' => [ 'enabled' => true, 'report-only' => true, 'report-uri' => 'https://example.com/csp-report', // legacy endpoint 'report-to' => 'csp-endpoint', // Reporting-API group name // ... ], ``` -------------------------------- ### Configure default strict CSP directives Source: https://github.com/jeffersongoncalves/laravel-security-headers/blob/master/README.md Default strict, first-party-only CSP configuration. No 'unsafe-*' or third-party origins; set csp.enabled to false to drop the header entirely. ```php 'csp' => [ 'enabled' => true, 'directives' => [ 'default-src' => "'self'", 'script-src' => "'self'", 'style-src' => "'self'", 'img-src' => "'self' data:", 'object-src' => "'none'", 'base-uri' => "'self'", 'form-action' => "'self'", 'frame-ancestors' => "'self'", ], ], ``` -------------------------------- ### Configure static security headers Source: https://github.com/jeffersongoncalves/laravel-security-headers/blob/master/README.md Configure static security headers in config/security-headers.php. Each entry is stamped onto every response; set any value to null to skip that header. ```php 'headers' => [ 'X-Content-Type-Options' => 'nosniff', 'X-Frame-Options' => 'SAMEORIGIN', 'Referrer-Policy' => 'strict-origin-when-cross-origin', 'Permissions-Policy' => 'camera=(), microphone=(), geolocation=(), payment=(), usb=(), browsing-topics=()', 'Cross-Origin-Opener-Policy' => 'same-origin-allow-popups', // Disable a header by setting it to null: 'X-Permitted-Cross-Domain-Policies' => null, ], ``` -------------------------------- ### Apply to Web Group (Laravel 11+) Source: https://github.com/jeffersongoncalves/laravel-security-headers/blob/master/README.md Apply the middleware to the web group in bootstrap/app.php for Laravel 11+. ```php use Illuminate\Foundation\Configuration\Middleware; use JeffersonGoncalves\SecurityHeaders\Middleware\SecurityHeaders; ->withMiddleware(function (Middleware $middleware) { $middleware->web(prepend: [ SecurityHeaders::class, ]); }) ``` -------------------------------- ### Test SecurityHeaders middleware with Pest Source: https://github.com/jeffersongoncalves/laravel-security-headers/blob/master/resources/boost/skills/security-headers-development/SKILL.md Directly test the SecurityHeaders middleware by passing a Request and a closure that returns a Response. Covers assertions for X-Content-Type-Options, HSTS on secure requests, HSTS omission on insecure requests, null config header omission, and custom CSP directive rendering. Note that Testbench runs in the 'testing' environment, so HSTS is applied for secure requests in tests. ```php use Illuminate\Http\Request; use Illuminate\Http\Response; use JeffersonGoncalves\SecurityHeaders\Middleware\SecurityHeaders; function runSecurityHeaders(Request $request) { return (new SecurityHeaders)->handle($request, fn () => new Response('OK')); } it('stamps nosniff', function () { $response = runSecurityHeaders(Request::create('https://example.com')); expect($response->headers->get('X-Content-Type-Options'))->toBe('nosniff'); }); it('adds HSTS on a secure non-local request', function () { $response = runSecurityHeaders(Request::create('https://example.com')); expect($response->headers->get('Strict-Transport-Security')) ->toBe('max-age=31536000; includeSubDomains; preload'); }); it('omits HSTS on an insecure request', function () { $response = runSecurityHeaders(Request::create('http://example.com')); expect($response->headers->has('Strict-Transport-Security'))->toBeFalse(); }); it('omits a header set to null in config', function () { config()->set('laravel-security-headers.headers.X-Frame-Options', null); $response = runSecurityHeaders(Request::create('https://example.com')); expect($response->headers->has('X-Frame-Options'))->toBeFalse(); }); it('renders a custom CSP directive from config', function () { config()->set('laravel-security-headers.csp.directives.img-src', "'self' https://cdn.example.com"); $response = runSecurityHeaders(Request::create('https://example.com')); expect($response->headers->get('Content-Security-Policy')) ->toContain("img-src 'self' https://cdn.example.com"); }); ``` -------------------------------- ### Configure Content-Security-Policy directives Source: https://github.com/jeffersongoncalves/laravel-security-headers/blob/master/resources/boost/skills/security-headers-development/SKILL.md Configure Content-Security-Policy directives. Directives are joined with '; ' in declaration order; arrays are joined with a single space. ```php 'csp' => [ 'enabled' => true, 'directives' => [ 'default-src' => "'self'", 'script-src' => ["'self'", "'unsafe-inline'", 'https://www.googletagmanager.com'], 'img-src' => "'self' data: https:", 'frame-ancestors' => "'self'", 'object-src' => "'none'", 'upgrade-insecure-requests' => null, // valueless ], ], ``` -------------------------------- ### Attach Middleware via Alias Source: https://github.com/jeffersongoncalves/laravel-security-headers/blob/master/README.md Attach the security-headers middleware to a route group using the auto-registered alias. ```php Route::middleware('security-headers')->group(function () { // ... }); ``` -------------------------------- ### Legacy Kernel Middleware Group Source: https://github.com/jeffersongoncalves/laravel-security-headers/blob/master/README.md Add the middleware to the web group in app/Http/Kernel.php for Laravel 10 style. ```php protected $middlewareGroups = [ 'web' => [ \JeffersonGoncalves\SecurityHeaders\Middleware\SecurityHeaders::class, // ... ], ]; ``` -------------------------------- ### Opt-in permissive CSP for GTM/gtag/Alpine.js Source: https://github.com/jeffersongoncalves/laravel-security-headers/blob/master/README.md Permissive CSP for Google Tag Manager, gtag, and Alpine.js. Requires 'unsafe-inline' and 'unsafe-eval', removing XSS protection; pair with output sanitization for untrusted markup. ```php 'directives' => [ 'default-src' => "'self'", 'script-src' => "'self' 'unsafe-inline' 'unsafe-eval' https://www.googletagmanager.com https://www.google-analytics.com https://static.cloudflareinsights.com", 'style-src' => "'self' 'unsafe-inline'", 'img-src' => "'self' data: https:", 'font-src' => "'self' data:", 'connect-src' => "'self' https://www.google-analytics.com https://*.google-analytics.com https://*.analytics.google.com https://www.googletagmanager.com https://cloudflareinsights.com", 'frame-src' => "'self' https://www.googletagmanager.com", 'frame-ancestors' => "'self'", 'base-uri' => "'self'", 'form-action' => "'self'", 'object-src' => "'none'", 'upgrade-insecure-requests' => null, ], ``` -------------------------------- ### Use nonces for inline scripts with @cspNonce Source: https://github.com/jeffersongoncalves/laravel-security-headers/blob/master/README.md Allow specific inline scripts with a per-request nonce. The middleware substitutes {nonce} with a fresh random value; the Blade @cspNonce directive emits the same value for that request. ```php 'script-src' => "'self' 'nonce-{nonce}'", ``` ```blade ``` -------------------------------- ### Configure HSTS header in Laravel Source: https://github.com/jeffersongoncalves/laravel-security-headers/blob/master/README.md Configuration for the HSTS security header. HSTS is only stamped over real HTTPS and never in excluded environments (default ['local']). The 'preload' option defaults to false and is a near-irreversible commitment if enabled and submitted to hstspreload.org. ```php 'hsts' => [ 'enabled' => true, 'max-age' => 31536000, 'include-subdomains' => true, 'preload' => false, // Environments in which HSTS is never stamped (even over HTTPS). // Set to [] to stamp HSTS in every environment. 'exclude_environments' => ['local'], ], ``` -------------------------------- ### Add Cross-Origin-Resource-Policy header to config Source: https://github.com/jeffersongoncalves/laravel-security-headers/blob/master/resources/boost/skills/security-headers-development/SKILL.md Add a new managed header by inserting its default value into the 'headers' array in config/laravel-security-headers.php. The middleware iterates this map, so no code change is needed; setting the value to null skips the header. ```php 'headers' => [ // ... 'Cross-Origin-Resource-Policy' => 'same-origin', ], ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.