Saltar al contenido principal

Descripción general

revolution/laravel-fetch-metadata es un paquete de middleware de seguridad que valida las cabeceras HTTP Sec-Fetch-* que envía el navegador. Puedes controlar qué peticiones se permiten en función del origen, el modo, el destino y si ha habido interacción del usuario. Aprovechando las funcionalidades de seguridad integradas en el navegador, puedes evitar peticiones maliciosas desde orígenes no autorizados sin perjudicar la experiencia de los usuarios legítimos.
En Laravel 13, la protección CSRF pasó a usar la cabecera Sec-Fetch-Site para la verificación del Origin. Consulta los detalles en Protección CSRF.
Para más información sobre la especificación de Fetch Metadata, consulta la documentación de MDN.

Instalación

composer require revolution/laravel-fetch-metadata

Registro de alias del middleware

Registra los alias de los middlewares en bootstrap/app.php.
use Illuminate\Foundation\Configuration\Middleware;
use Revolution\FetchMetadata\Middleware\SecFetchSite;
use Revolution\FetchMetadata\Middleware\SecFetchMode;
use Revolution\FetchMetadata\Middleware\SecFetchDest;
use Revolution\FetchMetadata\Middleware\SecFetchUser;

->withMiddleware(function (Middleware $middleware) {
    $middleware->alias([
        'sec-fetch-site' => SecFetchSite::class,
        'sec-fetch-mode' => SecFetchMode::class,
        'sec-fetch-dest' => SecFetchDest::class,
        'sec-fetch-user' => SecFetchUser::class,
    ]);
})
También puedes usar solo algunos de los middlewares. Los nombres de los alias son personalizables.

Descripción de los middlewares

SecFetchSite

La cabecera Sec-Fetch-Site indica la relación entre el origen de la petición y el origen objetivo. Por defecto, solo se permiten same-origin y none (acceso directo).
ValorDescripción
same-originPetición desde el mismo origen
same-sitePetición desde el mismo site (por ejemplo, subdominios)
cross-sitePetición desde un site distinto
nonePetición iniciada por navegación, como cuando el usuario introduce la URL directamente
Consulta los detalles en la documentación de MDN.

SecFetchMode

La cabecera Sec-Fetch-Mode indica el modo de la petición. Por defecto se permiten navigate y cors.
ValorDescripción
navigatePetición de navegación como clics en enlaces o envío de formularios
corsPetición CORS
no-corsPetición no-cors
same-originPetición del mismo origen
websocketPetición de conexión WebSocket
Consulta los detalles en la documentación de MDN.

SecFetchDest

La cabecera Sec-Fetch-Dest indica el tipo de recurso destino de la petición. Consulta los detalles en la documentación de MDN.

SecFetchUser

La cabecera Sec-Fetch-User indica si la petición se ha iniciado por una interacción del usuario. Su único valor es ?1 (con interacción del usuario).
Si usas el middleware SecFetchUser, también bloquearás a los rastreadores de buscadores y a los agentes de IA. No lo uses en páginas públicas que deban ser indexadas.

Ejemplos de uso en rutas

Uso básico

use Illuminate\Support\Facades\Route;
use Illuminate\Http\Request;

Route::post('user/update-password', function (Request $request) {
    //
})->middleware('sec-fetch-site');

Indicar valores permitidos como parámetros

Route::post('user/update-password', function (Request $request) {
    //
})->middleware('sec-fetch-site:cross-site');

Indicar varios parámetros

Route::post('user/update-password', function (Request $request) {
    //
})->middleware('sec-fetch-site:same-origin,cross-site');

Sin usar alias

use Revolution\FetchMetadata\Middleware\SecFetchSite;

Route::post('user/update-password', function (Request $request) {
    //
})->middleware(SecFetchSite::class.':same-origin,cross-site');

Combinar varios middlewares

Route::post('user/update-profile', function (Request $request) {
    //
})->middleware(['sec-fetch-site:same-origin', 'sec-fetch-mode:navigate']);

Manejo de errores

Si el valor de las cabeceras Sec-Fetch-* no es válido, se lanza Symfony\Component\HttpKernel\Exception\BadRequestHttpException. Puedes personalizar la respuesta en bootstrap/app.php.
use Illuminate\Http\Request;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;

->withExceptions(function (Exceptions $exceptions) {
    $exceptions->render(function (BadRequestHttpException $e, Request $request) {
        if ($request->expectsJson()) {
            return response()->json([
                'message' => $e->getMessage(),
            ], 400);
        }
    });
})

Relación con la protección CSRF

En Laravel 13, el middleware PreventRequestForgery realiza como primer paso de la protección CSRF una verificación del Origin mediante la cabecera Sec-Fetch-Site. Este paquete permite aprovechar las cabeceras de Fetch Metadata con una granularidad aún mayor y reforzar la seguridad de la aplicación. Consulta los detalles en Protección CSRF.
Consulta la información más actualizada en el repositorio de GitHub.
Última modificación el 13 de julio de 2026