메인 콘텐츠로 건너뛰기

개요

revolution/laravel-fetch-metadata는 브라우저가 전송하는 Sec-Fetch-* HTTP 헤더를 검증하는 보안 미들웨어 패키지입니다. 요청의 발생원·모드·대상·사용자 조작 유무에 기반해 허용할 요청을 제어할 수 있습니다. 브라우저에 내장된 보안 기능을 활용함으로써, 정상 사용자의 경험을 해치지 않으면서도 부정한 오리진으로부터의 악의적인 요청을 방지할 수 있습니다.
Laravel 13에서는 CSRF 보호의 Origin 검증에 Sec-Fetch-Site 헤더가 사용되게 되었습니다. 자세한 내용은 CSRF 보호를 참조하세요.
Fetch Metadata에 대한 자세한 사양은 MDN 문서를 참조하세요.

설치

composer require revolution/laravel-fetch-metadata

미들웨어 별칭 등록

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,
    ]);
})
일부 미들웨어만 사용할 수도 있습니다. 별칭 이름은 임의로 변경할 수 있습니다.

미들웨어 설명

SecFetchSite

Sec-Fetch-Site 헤더는 요청의 발생원과 타깃 오리진의 관계를 나타냅니다. 기본값으로는 same-originnone(직접 접근)만 허용합니다.
설명
same-origin동일 오리진에서의 요청
same-site서브도메인 등 동일 사이트에서의 요청
cross-site다른 사이트에서의 요청
none사용자가 직접 URL을 입력하는 등 내비게이션 시작 요청
자세한 내용은 MDN 문서를 참조하세요.

SecFetchMode

Sec-Fetch-Mode 헤더는 요청의 모드를 나타냅니다. 기본값으로는 navigatecors를 허용합니다.
설명
navigate링크 클릭이나 폼 전송 등의 내비게이션 요청
corsCORS 요청
no-corsno-cors 요청
same-origin동일 오리진 요청
websocketWebSocket 접속 요청
자세한 내용은 MDN 문서를 참조하세요.

SecFetchDest

Sec-Fetch-Dest 헤더는 요청의 대상 리소스 타입을 나타냅니다. 자세한 내용은 MDN 문서를 참조하세요.

SecFetchUser

Sec-Fetch-User 헤더는 요청이 사용자의 조작에 의해 개시되었는지 여부를 나타냅니다. 값은 ?1(사용자 조작 있음)뿐입니다.
SecFetchUser 미들웨어를 사용하면 검색 엔진 크롤러나 AI 에이전트도 차단됩니다. 인덱스가 필요한 공개 페이지에는 사용하지 마세요.

라우팅에서의 사용 예시

기본적인 사용

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

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

파라미터로 허용할 값을 지정

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

여러 파라미터 지정

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

별칭을 사용하지 않는 경우

use Revolution\FetchMetadata\Middleware\SecFetchSite;

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

여러 미들웨어 조합

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

에러 처리

Sec-Fetch-* 헤더의 값이 부정한 경우, Symfony\Component\HttpKernel\Exception\BadRequestHttpException이 throw됩니다. 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);
        }
    });
})

CSRF 보호와의 관계

Laravel 13에서는 PreventRequestForgery 미들웨어가 CSRF 보호의 첫 단계로서 Sec-Fetch-Site 헤더에 의한 Origin 검증을 수행하게 되었습니다. 이 패키지는 나아가 더 세밀한 단위로 Fetch Metadata 헤더를 활용하여, 애플리케이션의 보안을 강화할 수 있습니다. 자세한 내용은 CSRF 보호를 참조하세요.
최신 정보는 GitHub 저장소를 참조하세요.
마지막 수정일 2026년 7월 13일