개발자를 위한 Laravel 보안 모범 사례 및 솔루션 (2026) - TuxCare

지원 종료(EOL)된 PHP용 php2shell 패치(CVE-2026-109618 및 CVE-2026-109619)가 출시되었습니다. 수요가 많아 평소보다 영업팀의 답변이 늦어지고 있으므로, 패치된 패키지를 가장 빠르게 확보하려면 온라인에서 Runtimes용 ELS를 구매하시기 바랍니다 (새 탭에서 열림). 패치 FAQ 읽어보기

이 블로그 글의 AI 요약으로 바로 가기

  • Perplexity를 사용하여 이 게시물을 요약해 주세요
  • Gemini로 이 게시물을 요약해 주세요

주요 내용

  • 2026년 5월 발생한 Packagist 공격 사건은 버전 번호만으로는 Composer 설치가 안전하다고 단정할 수 없음을 보여주었습니다.
  • Laravel 13은 완전히 지원되며, Laravel 12는 보안 수정만 제공되며, 그보다 이전 버전은 지원이 종료되었습니다.
  • CVE-2026-48019는 12.60.0보다 낮은 모든 Laravel 릴리스와 13.10.0 이전 버전의 Laravel 13에 영향을 미칩니다.
  • 라라벨의 위험 요소 대부분은 옵트아웃, 원시 쿼리, 그리고 아무도 업데이트하지 않은 종속성에 숨어 있습니다.

라라벨의 보안은 프레임워크 자체보다는 설치 후의 관리 방식과 더 밀접한 관련이 있습니다. 기본 설정이 하나 비활성화되거나, 원시 쿼리가 하나 실행되거나, 아무도 업데이트하지 않은 종속성이 하나만 있어도 보통 보안 취약점이 발생하기에 충분합니다.

이 가이드에서는 여전히 운영 환경에 유입되고 있는 위협 요소, 이를 차단하는 방법, API를 안전하게 보호하는 방법, 그리고 지원이 종료된 버전을 계속 사용해야 하는 경우의 대처 방안을 단계별로 설명합니다.

라라벨 애플리케이션에서 보안이 중요한 이유

단 한 번의 보안 침해만으로도 수년간 쌓아온 고객의 신뢰를 무너뜨리고, 법적 책임을 초래하며, 공격자에게 서버 접속 정보를 넘겨줌으로써 운영 중인 다른 모든 시스템까지 노출시킬 수 있습니다. 게다가 침입 경로도 달라졌습니다. 2026년 버라이즌 DBIR 에 따르면, 취약점 악용이 현재 침해 사고의 가장 흔한 초기 접근 경로로 나타났으며, 전체 침해 사고의 31%에서 확인되었고(전년도의 20% 대비), 반면 인증 정보 악용은 13%로 감소했습니다.

Laravel은 기본적으로 특정 유형의 문제들을 아예 차단해 줍니다. Eloquent는 쿼리 값을 매개변수화하고, Blade는 기본적으로 출력 값을 이스케이프 처리하며, 요청 위조(RFO) 미들웨어는 아무도 요청하지 않았음에도 웹 그룹에 포함되어 있습니다. 하지만 개발자가 이 기능들을 비활성화하면 이러한 보호 기능은 모두 사라지며, 권한 부여, 잘못된 구성, 서버 측 요청 위조(SSRF), 비즈니스 로직, 또는 취약한 의존성 등은 전혀 다루지 못합니다. 이러한 문제들은 영원히 개발자 여러분의 몫으로 남습니다.

라라벨에서 흔히 발생하는 보안 위협

라라벨에서 흔히 발생하는 보안 위협

이스케이프 처리되지 않은 Blade 출력을 통한 크로스사이트 스크립팅

블레이드의 {{ }} 구문은 출력 시 자동으로 이스케이프 처리됩니다. {!! !!} 구문은 그렇지 않으며, CMS 필드나 리치 텍스트 편집기에서 저장된 HTML을 렌더링해야 할 때 사람들이 주로 사용하는 구문입니다.

저장된 HTML에 스크립트 태그가 포함되어 있다면, 해당 페이지를 불러오는 모든 사용자의 브라우저에서 그 스크립트가 실행됩니다. 따라서 해당 코드가 {!! !!}에 도달하기 전에 서버 측에서 먼저 정제해야 합니다.

원시 표현식을 통한 SQL 인젝션

Eloquent와 쿼리 빌더는 쿼리 값을 매개변수화하므로, 일반적인 쿼리의 경우 인젝션에 대해 걱정할 필요가 없습니다. 사용자 입력이 DB::raw(), whereRaw(), havingRaw(), 또는 orderByRaw().

컬럼과 방향 이름은 매개변수로 바인딩할 수 없기 때문에 흔히 간과되는 부분입니다. 대신 고정된 배열을 기준으로 허용 목록에 포함시키세요. 이 점은 라라벨에만 국한된 문제도 아닙니다. PHP 개발자들이 지난 20년 동안 문자열로 구성된 SQL을 작성할 때 계속 저지르던 바로 그 실수입니다.

인증 및 세션 처리 오류

Laravel의 인증 스캐폴딩은 탄탄합니다. 문제는 그 주변에서 발생합니다. 로그인 시 속도 제한이 없고, 만료되지 않는 토큰 재설정, 권한 변경 후 세션이 재생성되지 않는 문제, 그리고 setRememberToken을 생략하는 사용자 정의 비밀번호 변경 흐름으로 인해 비밀번호 변경 후에도 ‘내 정보 기억하기’ 세션이 유효하게 유지되는 등의 문제들이 있습니다. 

인증과 권한 부여를 별도로 확인하십시오. 인증된 사용자라면 누구나 /admin 에 접근할 수 있게 하는 로그인 기능은 로그인 양식의 버그가 아니라 권한 부여 취약점입니다.

Laravel 보안 모범 사례

1. Laravel과 그 종속 라이브러리에 패치를 적용해 두세요

실행 매주 또는 2주마다 composer outdated를 매주 또는 2주에 한 번씩 실행하여 어떤 패키지에 새 버전이 있는지 확인한 다음, `composer update` 명령어를 실행하여 composer.json에서 설정한 제약 조건에 따라 최신 버전을 가져오세요. Laravel의 릴리스 노트 와 GitHub 보안 권고 사항도 주시하세요. 새로 발견된 프레임워크 취약점은 이곳에 가장 먼저 게시되기 때문입니다. 도 주시하세요. 새로 공개된 프레임워크의 취약점은 이곳에 가장 먼저 게시되기 때문입니다.

라라벨의 현재 정책에 따르면, 각 릴리스는 출시일로부터 18개월 동안 버그 수정 지원을, 2년 동안 보안 수정 지원을 받습니다. 또한 더 이상 LTS(장기 지원) 등급도 없습니다. 라라벨 6이 마지막 LTS 릴리스였으며, 6개월 주기의 마이너 릴리스에서 연간 메이저 릴리스로 전환되는 과정에서 지원 기간이 변경되었기 때문에, 아래에 나열된 이전 릴리스들의 지원 기간이 모두 동일한 패턴을 따르지 않는 것입니다.

버전 릴리스 날짜 버그 수정 내역 (~) 다음 날짜까지의 보안 수정 사항
13 3월 17, 2026 Q3 2027 3월 17, 2028
12 2월 24, 2025 8월 13, 2026 2월 24, 2027
11 3월 12, 2024 9월 3, 2025 3월 12, 2026
10 2월 14, 2023 8월 6, 2024 2월 4, 2025
9 2월 8, 2022 8월 8, 2023 2월 6, 2024
8 9월 8, 2020 7월 26, 2022 1월 24, 2023
7 3월 3, 2020 10월 6, 2020 3월 3, 2021
6 (LTS) 9월 3, 2019 1월 25, 2022 9월 6, 2022
5.8 2월 26, 2019 8월 26, 2019 2월 26, 2020
5.7 9월 4, 2018 3월 4, 2019 9월 4, 2019
5.6 2월 7, 2018 8월 7, 2018 2월 7, 2019
5.5 (LTS) 8월 30, 2017 8월 30, 2019 8월 30, 2020
5.4 1월 24, 2017 7월 24, 2017 1월 24, 2018

CVE-2026-48019 은 보안 패치를 제때 적용하지 않을 경우 어떤 대가를 치르게 되는지 보여줍니다. 이는 Laravel의 기본 이메일 유효성 검사 규칙에 존재하는 CRLF 주입 취약점으로, Symfony Mailer와 Symfony Mime이 특정 문자 시퀀스를 처리하는 방식과 결합되어 인증되지 않은 공격자가 발신 메일을 조작하여 Bcc 헤더를 삽입하거나, 메시지 내용을 변경하거나, 앱을 중계 서버로 변환할 수 있게 합니다. 이 보안 권고에서는 12.60.0 미만의 모든 릴리스와 Laravel 13부터 13.9.0까지가 영향을 받는 것으로 명시하고 있으며, 수정 사항은 12.60.0 및 13.10.0에 반영되었습니다. Laravel 11의 보안 지원 기간은 2026년 3월에 이미 종료되었으므로, 11 및 그 아래의 모든 브랜치는 해당 범위에 속하지만 업스트림에서 패치된 릴리스는 제공되지 않습니다.

당장 대규모 업그레이드가 현실적으로 어렵다면, TuxCare의 Laravel용 Endless Lifecycle Support는 는 Composer를 통해 보안 수정 사항을 특정 베이스라인(현재 5.4.36부터 12.58.0까지)으로 역포트하며, 요청 시 다른 버전도 제공됩니다.

2. 모든 보호 기능 제외 요청을 코드 검토 단계로 간주하라

Every Laravel security default ships with an escape hatch, and each one deserves a second pair of eyes before it goes out. {!! !!} in Blade turns off output escaping. DB::raw() and whereRaw() accept raw SQL, so any untrusted input has to arrive as a binding rather than concatenated into the string. Model::unguard(), $guarded = [],and Laravel 13’s #[Unguarded] attribute all open mass assignment on every column. 

요청 위조 방지 기능에는 별도의 예외 처리 메커니즘이 있으며, API 위치가 변경되었습니다. Laravel 13에서는 preventRequestForgery(except: […]) 를 bootstrap/app.php에서 루트를 제외할 수 있습니다. 11 및 12 버전에서는 동일한 기능이 validateCsrfTokens()가 호출되며, 그 이전 버전에서는 $except 속성을 사용합니다. 또한, 해당 요청 위조 방지 미들웨어 클래스를 withoutMiddleware()메서드에 전달하여 이 기능을 비활성화할 수도 있습니다.에 전달하여 CSRF 미들웨어를 적용하지 않도록 설정할 수도 있습니다.

이 모든 사항을 grep 기반의 CI 검사에 추가하고, 해당 사항이 포함된 풀 리퀘스트를 제출한 작성자가 설명란에 그 사유를 명시하도록 하십시오.

3. 서버 측 유효성 검사와 인증을 별도로 수행하기

유효성 검사는 데이터의 형식이 올바른지 확인합니다. 권한 검사는 해당 사용자가 해당 데이터에 대해 작업을 수행할 수 있는지 확인합니다. 한 가지 검사를 통과했다고 해서 다른 검사 결과와 관련이 있는 것은 아닙니다.

검토가 가능한 곳에 유효성 검사 규칙을 배치할 수 있도록 폼 요청 클래스를 사용하고, 모든 모델 액션에는 Policy 또는 Gate를 적용하세요. 클라이언트 측 유효성 검사는 사용자 경험을 개선해 주지만, 보안에는 전혀 도움이 되지 않습니다.

4. 구성 및 비밀 정보 보호

설정 APP_DEBUG=false 을 예외 없이 프로덕션 환경에서 설정하십시오. Laravel의 공식 문서에서는 디버그 모드를 켜 둔 채로 둘 경우의 위험성에 대해 명확히 경고하고 있습니다. 민감한 구성 값이 최종 사용자에게 노출될 수 있으며, 디버그 오류 페이지는 오류를 유발한 사용자에게 상세한 스택 트레이스를 제공하게 됩니다.

유지 .env 파일을 버전 관리 대상에서 제외하고, 웹 루트가 /public를 가리키는지 확인한 후, APP_KEY 를 교체하십시오. 애플리케이션 내의 모든 암호화된 값과 서명된 쿠키는 해당 키에 의존하므로, 이전 키를 APP_PREVIOUS_KEYS 에 이전 키를 기재해야 합니다. 그렇지 않으면 이전에 암호화된 데이터를 더 이상 복호화할 수 없으며, 인증된 모든 세션이 로그아웃됩니다. 

5. 사고 발생 후가 아니라 정해진 일정에 따라 의존성을 감사하라

실행 CI에서 composer audit 를 CI에서 실행하여, 알려진 취약점이 있는 패키지가 분기별 보고서에 노출되는 대신 빌드 과정에서 실패하도록 합니다.

composer audit –format=summary

라라벨의 공식 패키지에도 CVE가 부여됩니다. CVE-2026-39976 는 laravel/passport의 인증 우회 취약점으로, 13.7.1 버전에서 수정되었으며, 이 취약점은 client_credentials 토큰이 실제 사용자 계정으로 연결될 수 있는 문제였습니다. 이 문제는 UUID 클라이언트 ID가 비활성화된 경우에만 발생하는데, 이는 스캐너가 단순히 패키지에 문제가 있다고만 알려줄 때 놓치기 쉬운 세부 사항입니다. 정기적인 보안 감사 및 취약점 패치을 위한 문서화된 절차를 함께 수립하십시오.

주의: 2026년 5월 22일부터 23일까지, 한 공격자가 Packagist에 있는 4개의 Laravel-Lang 패키지에 대해 Packagist에 있는 4개의 Laravel-Lang 패키지에 대해 과거 릴리스 태그 아래에 악성 코드를 재게시했습니다. 기존의 모든 태그가 새로운 커밋으로 리디렉션되었으므로, 귀하의 composer.json 에 표시된 버전 번호만으로는 실제로 어떤 버전이 설치되었는지 알 수 없었습니다. 자신이 영향을 받았는지 확인하려면 composer.lock에서 확인된 커밋, 빌드 실행 시점, 그리고 당시 공개된 침해 징후를 종합적으로 검토해야 했습니다.

Laravel API 보안

대부분의 API는 상태 비저장형이며 토큰 기반인데, 이는 단순히 보안 수준을 약화시키는 것이 아니라 보안 모델 자체를 변화시킵니다. 베어러 토큰은 세션 쿠키와 달리 브라우저에 자동으로 첨부되지 않기 때문에, CSRF 방어는 더 이상 중요한 통제 수단이 아닙니다. 대신 중요한 역할을 하는 것은 인증, 모든 작업에 대한 권한 부여, 누군가가 실제로 구성한 CORS 정책, 속도 제한, 그리고 토큰 수명 주기입니다. Sanctum의 SPA 모드와 같은 상태 유지형 설정은 세션 쿠키를 사용하고 CSRF 보호가 필요하기 때문에 예외에 해당합니다.

하지만 정말로 한 가지 부족한 점이 있습니다. 아무도 그 반응을 지켜보고 있지 않기 때문에, API에 대한 느린 열거 공격이 누군가 알아차리기 전까지 며칠 동안 계속될 수 있습니다.

Laravel API 보안

‘Sanctum’과 ‘Passport’ 중 신중하게 선택하세요

Sanctum은 최소한의 설정만으로 토큰 및 SPA 인증을 처리하며, 대부분의 애플리케이션에 적합합니다. Passport는 완전한 OAuth2를 구현하며, 타사 인증 흐름이 진정으로 필요한 경우에만 유용합니다.

Passport의 더 넓은 적용 범위는 더 큰 위험을 수반합니다. 어떤 방식을 선택하든 토큰의 적용 범위를 좁게 설정하고 만료 기간을 지정해야 합니다. 만료 기간이 없는 토큰은 누군가가 이를 취소해야 한다는 사실을 기억해 낼 때까지 유효한 상태로 남아 있기 때문에, 정보 유출을 차단하기가 매우 어렵습니다.

모든 공개 엔드포인트에 대한 요청 제한

Laravel의 스로틀 미들웨어는 한 줄로 구현되며, API 경로에서 이를 빠뜨리기 쉽습니다. 이 미들웨어가 없으면, 자격 증명 도용 공격과 열거 공격이 서버가 허용하는 한도 내에서 어떤 속도로든 실행될 수 있습니다.

사용자별 및 IP별 요청 제한을 적용하며, 로그인, 비밀번호 재설정, 그리고 이메일이나 SMS를 발송하는 모든 기능에 대해서는 더 엄격한 제한을 적용합니다. 오류가 발생했을 때 아무런 메시지 없이 실패하는 대신 429 오류 코드를 반환합니다.

애플리케이션 바로 아래 계층의 보안을 강화하십시오

API의 보안 수준은 이를 제공하는 호스트의 보안 수준에 달려 있습니다. TLS를 적용하고, 디렉터리 목록 표시를 비활성화하며, Laravel 릴리스 주기와는 별개로 OS와 PHP 런타임에 대한 패치를 적용하십시오.

서버가 해킹당하면 애플리케이션 수준의 보안은 무용지물이 됩니다. 라라벨 코드베이스 내에서 어떤 작업을 하든, 그 기반이 되는 서버 자체는 별도의 기준으로 보안을 강화하고 패치를 적용해야 합니다.

참고: Laravel 13에서는 요청 위조 방지 기능을 다음과 같이 공식화했습니다. PreventRequestForgery로 공식화했으며, 이는 브라우저의 Sec-Fetch-Site 헤더에 대한 원본 확인을 추가합니다. 동일 원본 요청은 토큰 없이도 허용되며, 원본 확인을 통과하지 못한 요청은 대신 토큰 유효성 검사로 넘어갑니다. Laravel 문서에 따르면 이 헤더는 HTTPS를 통해서만 전송되므로, 일반 HTTP의 경우 여전히 전적으로 토큰에 의존합니다. 미들웨어에서 실제로 무엇을 확인하는지 꼼꼼히 확인한 후, 해당 미들웨어의 적용을 제외할 대상을 결정하십시오.

라라벨 보안 업체 및 솔루션

TuxCare의 지속적인 라이프사이클 지원

ELS는 핵심 개발팀이 더 이상 유지 관리하지 않는 Laravel 버전에 보안 수정 사항을 역포트하여 Composer를 통해 제공하므로, 의존성 관리 워크플로에는 변화가 없습니다. TuxCare는 EOL(지원 종료)된 PHP 런타임도 지원합니다 . 이는 구형 Laravel 애플리케이션이 업스트림에서 더 이상 패치를 제공하지 않는 PHP 버전을 사용 중인 경우에 특히 중요합니다.

ELS는 향후 업그레이드를 대신할 수 있는 대안이 아닙니다. 이는 업스트림에서 더 이상 패치를 제공하지 않는 브랜치에 대한 장기적인 보안 지원으로, EOL(지원 종료) 브랜치에 대한 CVE 수정 패치를 계속 받아볼 수 있으며, 타인의 일정에 얽매이지 않고 자신의 일정에 맞춰 마이그레이션을 계획할 수 있게 해줍니다.

현재 지원되는 Laravel 버전은 다음과 같습니다: 5.4.36, 5.5.50, 5.6.40, 5.7.29, 5.8.38, 6.20.45, 7.30.7, 8.12.0, 8.12.1, 8.12.2, 8.12.3, 8.83.29, 9.52.21, 10, 11, 12.58.0.

의존성 스캔

다음으로 시작하세요 composer audit부터 시작해 보세요. 무료이고 이미 설치되어 있으니까요. 이 명령어는 설치된 패키지를 검사하므로, 전이적 의존성도 검사 범위에 포함되며, composer audit –locked 명령어는 vendor 디렉터리가 없을 때 대신 lock 파일을 확인합니다. Snyk, GitHub Dependabot, Aikido는 여기에 지속적인 모니터링, 알림, 자동화된 업데이트 풀 리퀘스트 기능을 추가로 제공하며, CI를 면밀히 감시하는 사람이 없을 때 특히 유용합니다. 소규모 팀의 경우 Dependabot이 합리적인 기본 옵션입니다. 이 도구들 중 어느 것도 해결하지 못하는 문제는 EOL(지원 종료) 패키지인데, 이 경우 애초에 업그레이드할 고정된 버전이 존재하지 않습니다.

실행 시 보호 및 모니터링

웹 애플리케이션 방화벽은 취약점이 공개된 후 패치가 적용되기까지 시간을 벌어줄 뿐, 그 이상은 아닙니다. Cloudflare, AWS WAF, 그리고 OWASP Core Rule Set과 같은 정기적으로 관리되는 규칙 세트를 적용한 ModSecurity는 많은 일반적인 인젝션 및 XSS 페이로드를 PHP에 도달하기 전에 차단할 수 있지만, 차단 범위는 활성화한 규칙에 전적으로 달려 있습니다. 방화벽과 로그 모니터링을 함께 사용하면, 공격 시도가 일반적인 잘못된 요청과 구별되도록 할 수 있습니다.

TuxCare를 통해 Laravel 애플리케이션 보안 강화하기

Laravel 애플리케이션을 지원 기간 내에 유지하는 데 팀들이 어려움을 겪곤 합니다. 주요 업그레이드에는 호환성 변경 사항이 수반되며, 이는 같은 스프린트 내에서 기능 출시와 일정을 다투게 됩니다. 사용 중인 버전이 EOL(지원 종료)을 지났고 이번 분기에 마이그레이션이 진행되지 않는다면, TuxCare의 라라벨 ‘Endless Lifecycle Support’ 는 여러분이 이전할 준비가 될 때까지 패치를 계속 적용해 드립니다.

요약
개발자를 위한 Laravel 보안 모범 사례 및 솔루션 (2026)
기사 이름
개발자를 위한 Laravel 보안 모범 사례 및 솔루션 (2026)
설명
XSS, CSRF, SQL 인젝션 및 기타 위협으로부터 애플리케이션을 보호하기 위한 Laravel 보안 모범 사례를 알아보세요. 2026년 개발자를 위한 실용적인 가이드입니다.
작성자
게시자 이름
TuxCare
게시자 로고

4,500명 이상의 Linux 및 오픈 소스 전문가와 함께하세요!

한 달에 두 번. 스팸이 없습니다.

목차
필요한 오픈 소스 보안에 대한 답변 얻기

4,500명 이상의 Linux 및 오픈 소스 전문가와 함께하세요!

한 달에 두 번. 스팸이 없습니다.