Skip to content

Instantly share code, notes, and snippets.

@laymont
Created April 23, 2025 20:25
Show Gist options
  • Save laymont/7fefb0361b6eea3272d5b1e54be9a914 to your computer and use it in GitHub Desktop.
Save laymont/7fefb0361b6eea3272d5b1e54be9a914 to your computer and use it in GitHub Desktop.
SecureApiLaravel
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class SecureHeadersMiddleware
{
/**
* Handle an incoming request.
*
* @param Closure(Request): (Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
$response = $next($request);
// Content Security Policy (ajusta según tus necesidades)
$response->headers->set(
'Content-Security-Policy',
"default-src 'self'; script-src 'self'; object-src 'none'; frame-ancestors 'none'; base-uri 'self'; form-action 'self';"
);
// Anti-Clickjacking
$response->headers->set('X-Frame-Options', 'DENY');
// Aislamiento contra Spectre
$response->headers->set('Cross-Origin-Opener-Policy', 'same-origin');
$response->headers->set('Cross-Origin-Embedder-Policy', 'require-corp');
// X-Content-Type-Options
$response->headers->set('X-Content-Type-Options', 'nosniff');
// Strict-Transport-Security (solo si usas HTTPS)
if ($request->isSecure()) {
$response->headers->set('Strict-Transport-Security', 'max-age=63072000; includeSubDomains; preload');
}
// Permissions Policy (ajusta según tus necesidades)
$response->headers->set('Permissions-Policy', 'geolocation=(), microphone=()');
// Elimina X-Powered-By si existe
header_remove('X-Powered-By');
// Elimina Server si es posible (algunos servidores lo imponen fuera de PHP)
if (function_exists('header_remove')) {
header_remove('Server');
}
// Opcional: también puedes sobreescribir el header Server
$response->headers->set('Server', '');
return $response;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment