> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Laravel Fetch Metadata

> A security middleware based on Sec-Fetch-* headers that protects Laravel apps from CSRF attacks and cross-site requests.

## Overview

[revolution/laravel-fetch-metadata](https://github.com/invokable/laravel-fetch-metadata) is a security middleware package that validates the `Sec-Fetch-*` HTTP headers sent by browsers. You can control which requests to allow based on the origin, mode, destination, and whether the request was user-initiated.

By leveraging browser-built-in security features, you can block malicious requests from unauthorized origins without harming the experience for legitimate users.

<Info>
  In Laravel 13, CSRF protection uses the `Sec-Fetch-Site` header for origin validation. See [CSRF protection](/en/csrf) for details.
</Info>

For the full Fetch Metadata specification, see [the MDN documentation](https://developer.mozilla.org/en-US/docs/Glossary/Fetch_metadata_request_header).

## Installation

```bash theme={null}
composer require revolution/laravel-fetch-metadata
```

### Registering middleware aliases

Register middleware aliases in `bootstrap/app.php`.

```php theme={null}
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,
    ]);
})
```

You can also use just some of the middleware. The alias names can be anything you like.

## Middleware overview

### SecFetchSite

The `Sec-Fetch-Site` header describes the relationship between the request's origin and the target origin. By default, only `same-origin` and `none` (direct access) are allowed.

| Value | Description |
| - | - |
| `same-origin` | Same-origin request |
| `same-site` | Request from the same site, such as a subdomain |
| `cross-site` | Request from a different site |
| `none` | Navigation-initiated request such as the user typing a URL directly |

See [the MDN documentation](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Sec-Fetch-Site) for details.

### SecFetchMode

The `Sec-Fetch-Mode` header describes the request mode. By default, `navigate` and `cors` are allowed.

| Value | Description |
| - | - |
| `navigate` | A navigation request such as clicking a link or submitting a form |
| `cors` | CORS request |
| `no-cors` | No-cors request |
| `same-origin` | Same-origin request |
| `websocket` | WebSocket connection request |

See [the MDN documentation](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Sec-Fetch-Mode) for details.

### SecFetchDest

The `Sec-Fetch-Dest` header describes the destination resource type of the request.

See [the MDN documentation](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Sec-Fetch-Dest) for details.

### SecFetchUser

The `Sec-Fetch-User` header indicates whether the request was initiated by user interaction. The only value is `?1` (user interaction).

<Warning>
  Using the `SecFetchUser` middleware will also block search engine crawlers and AI agents. Do not use it on public pages that need to be indexed.
</Warning>

## Routing examples

### Basic usage

```php theme={null}
use Illuminate\Support\Facades\Route;
use Illuminate\Http\Request;

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

### Specifying allowed values via parameters

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

### Specifying multiple parameters

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

### Without an alias

```php theme={null}
use Revolution\FetchMetadata\Middleware\SecFetchSite;

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

### Combining multiple middleware

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

## Error handling

When a `Sec-Fetch-*` header value is invalid, `Symfony\Component\HttpKernel\Exception\BadRequestHttpException` is thrown.

You can customize the response in `bootstrap/app.php`.

```php theme={null}
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);
        }
    });
})
```

## Relationship with CSRF protection

In Laravel 13, the `PreventRequestForgery` middleware now uses the `Sec-Fetch-Site` header for origin validation as the first step in CSRF protection. This package lets you apply Fetch Metadata headers at a finer grain to further harden your application.

See [CSRF protection](/en/csrf) for details.

<Info>
  For the latest updates, see the [GitHub repository](https://github.com/invokable/laravel-fetch-metadata).
</Info>


## Related topics

- [Guide to Building Apps with VOICEVOX Engine API](/en/packages/laravel-voicevox/app-guide.md)
- [Laravel Head](/en/head.md)
- [Laravel Passkeys initial research (passkeys-server + @laravel/passkeys)](/en/blog/passkeys-introduction.md)
- [June 2026 Laravel updates](/en/blog/changelog/202606.md)
- [Laravel MCP](/en/mcp.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.