본문으로 건너뛰기
>_ITDITD웹 보안 플랫폼

프레임워크별

Laravel 보안 — 프로덕션 하드닝 레퍼런스

Laravel 프로덕션 하드닝 레퍼런스: 우선순위순 체크리스트, 위험한 기본값, 그리고 시크릿·설정부터 인가·의존성 CVE까지 영역별 지침에 자기 점검 체크리스트를 더했습니다. 방어 중심이며 공격 절차는 없습니다.

게시 2026-07-02 업데이트 2026-07-02 7분 읽기

대상: Laravel을 프로덕션에서 운영하는 모두. 여기에 공격 절차는 없습니다 — 이 문서는 하드닝을 위한 실무 레퍼런스입니다: 우선순위순 체크리스트, 위험한 기본값, 영역별 지침, 그리고 자기 점검. 프레임워크 전반의 그림은 프레임워크별 보안 입구를 참고하세요.

우선순위순 하드닝 체크리스트

이 표를 위에서부터 처리하세요. P0은 나머지의 전제, P1은 사고가 가장 자주 나오는 곳, P2는 지속적인 운영 위생입니다.

P0 ── 전제(먼저 한다)

프로덕션 디버그 off / 시크릿을 공개 표면 밖에 권한 600으로 / APP_KEY 관리

P1 ── 최대 사고 원인

인가(Policy/Gate) / Mass Assignment 제어 / 의존성 CVE / 프로덕션 캐시

P2 ── 운영 위생

세션/CSRF/쿠키 / 업로드 검증 / HTTPS, 헤더, 속도 제한

기초부터 하드닝: P0(전제) → P1(최대 사고 원인) → P2(운영 위생).
우선순위대책구체적 내용(Laravel)
P0프로덕션 디버그 비활성화APP_DEBUG=false / APP_ENV=production, config:cache로 고정. 에러 페이지에 내부 정보를 흘리지 않기
P0시크릿을 공개 표면 밖으로.env, 백업, 키를 public/ 밖에, 권한 600. storage/logs는 비공개
P0APP_KEY 안전 관리암호화·서명 쿠키·세션의 근간. 환경에서 주입, 유출 시 교체
P1명시적 인가Policy / Gate + authorize() / can 미들웨어, 소유자/권한으로 스코프
P1Mass Assignment 제어$fillable 선언; $request->all() 통째 대입 회피, validated() 사용
P1Composer CVE 모니터링composer audit / osv-scanner; 실행 중인 버전으로 판단, 빠르게 패치
P1프로덕션 캐시config:cache route:cache view:cache로 설정 신뢰성 + 속도
P2세션/쿠키 안전secure http_only same_site 설정; 로그인 시 세션 재생성
P2업로드 검증타입/크기 검증, public/ 밖에 저장, 실행 권한 없음
P2HTTPS/헤더/속도 제한HTTPS 강제, HSTS, 로그인/API에 throttle

1. 시크릿과 APP_KEY (P0)

Laravel은 기본적으로 .env를 도큐먼트 루트 밖(프로젝트 루트)에 둡니다. 사고는 대부분 시크릿을 있어서는 안 될 곳에 두는 것에서 나옵니다.

  • .env, DB 덤프, 백업, 키 파일을 public/ 절대 두지 마세요. 시크릿은 앱 루트 밖에 권한 600(소유자만)으로 두세요.
  • storage/storage/logs/를 노출하지 마세요(로그에는 시크릿이나 개인 정보가 들어갈 수 있습니다). .env를 리포지토리에 커밋하지 마세요.
  • **APP_KEY**는 암호화, 서명 URL, 암호화된 쿠키, 세션의 근간입니다. 환경에서 주입하고 유출되면 즉시 교체하세요(이는 기존 암호화 데이터/세션을 무효화한다는 점에 유의).

일반 원칙은 공개 디렉터리에 시크릿을 두지 않기를, 실제 전면 노출 사례는 .env 전면 노출 사례를 참고하세요.

2. 프로덕션 설정: DEBUG, 환경, 캐시 (P0)

1

APP_DEBUG=false / APP_ENV=production

프로덕션에서는 디버그를 끄세요. 켜져 있으면 예외 페이지가 환경 변수와 접속 정보를 흘리고, 고의의 에러로 빼내집니다.
2

캐시로 설정 고정

php artisan config:cache(+ route:cache view:cache)는 설정을 확실히 반영시키고 앱을 빠르게 합니다. 주의: config:cache 이후 config/ 밖의 env()는 null을 반환하므로, 앱에서는 config('...')로 값을 참조하세요.
3

프로덕션에 진단 도구를 노출하지 않기

프로덕션에서 Telescope / Horizon / Debugbar를 비활성화하거나 접근 제한하세요. 상세 에러와 스택 트레이스를 공개 표면에서 떼어내세요.

3. 인가: Broken Access Control (P1 — 최대 원인)

가장 흔한 프로덕션 사고는 "인증은 됐지만 인가가 없다"입니다. 로그인할 수 있다고 해서 그 동작이 허용되는 것은 아닙니다.

흔히 하는(위험)

  • 인가 없음 — "로그인 = 조회/수정 가능"
  • route-model 바인딩이 타인의 ID를 가져옴
  • Model::create($request->all())가 모든 필드를 수용
  • is_admin 같은 권한 필드를 사용자 입력에서 대입

올바른

  • Policy / Gate + authorize() / can 미들웨어, 매번 소유자/권한으로 스코프
  • 조회도 소유자 스코프(예: where('user_id', $me))
  • $request->validated()(FormRequest)로 입력 제한
  • $fillable 선언으로 Mass Assignment 차단

IDOR이란 무엇인가를 참고하세요. 핵심은 모든 조회/수정/삭제 경로에 소유권 검사를 두는 것입니다.

4. 인젝션과 출력

Laravel의 Eloquent/쿼리 빌더는 값을 플레이스홀더로 바인딩하고, Blade는 기본적으로 출력을 이스케이프합니다. 규칙은 그 안전장치를 스스로 끄지 않는 것입니다.

  • SQL: whereRaw / DB::raw에 사용자 입력을 문자열 연결로 섞지 마세요. 원시 SQL이 필요할 때도 바인딩을 쓰세요(→ SQL 인젝션이란 무엇인가).
  • XSS: Blade {{ }}는 이스케이프하고, {!! !!}원시 출력입니다. 사용자 입력을 {!! !!}에 넘기지 마세요. HTML을 내보내야 한다면 새니타이즈 후에만(→ XSS란 무엇인가).
  • 검증: 사용 전에 **FormRequest / validate()**로 타입/범위/허용값을 검증하세요.

5. 세션, CSRF, 쿠키 (P2)

  • CSRF: web 미들웨어의 CSRF 보호를 전역으로 비활성화하지 마세요. 폼에는 @csrf를, SPA에는 적절한 토큰 처리를 쓰세요(→ CSRF란 무엇인가).
  • 쿠키/세션: config/session.phpsecure(HTTPS), http_only, same_site를 설정하세요. 로그인 시 세션을 재생성해 고정(fixation)을 막으세요(Laravel의 인증은 재생성합니다).
  • 무차별 대입: 로그인에 throttle / 로그인 시도 제한을 적용하세요.

6. 파일 업로드와 공개 파일 (P2)

  • mime 타입, 확장자, 크기를 검증하고, 클라이언트가 제공한 파일명을 신뢰하지 마세요.
  • public/ 밖에(예: storage/) 실행 권한 없이 저장하세요. 공개가 필요한 것만 통제된 경로로 제공하세요.
  • 전달에도 인가를 두어, 순차적인 직접 링크로 타인의 파일을 가져갈 수 없게 하세요.

7. HTTPS, 보안 헤더, 속도 제한 (P2)

  • HTTPS 강제(URL::forceScheme('https') 등) + HSTS. 로드 밸런서 뒤에서는 스킴이 올바르게 감지되도록 TrustProxies를 쓰세요.
  • 보안 헤더(X-Content-Type-Options 등; CSP는 자신의 에셋 구성에 맞춰 설계). 본인 사이트는 보안 헤더 체커로 점검하세요.
  • 속도 제한: 로그인, API, 비밀번호 재설정에 throttle을 적용하세요.

8. 의존성과 버전 (P1)

  • Composer 의존성 CVE를 composer audit나 osv-scanner로 모니터링하고, 실행 중인 버전으로 판단하며, 빠르게 패치하세요(→ 의존성 CVE 모니터링 · 취약점 대응 실무).
  • Laravel과 PHP를 지원되는 버전으로 유지하세요. EOL 버전을 방치하지 마세요(고칠 수 없는 구멍이 쌓입니다).

점검: 당신의 Laravel은 실제로 하드닝됐는가?

만드는 것으로 끝이 아닙니다 — 점검해야 비로소 끝입니다. 다음은 본인 사이트/환경에 대한 방어적 자기 점검입니다.

1

시크릿을 URL로 가져올 수 없다

본인 도메인에서 /.env/storage/logs/laravel.log에 접근해 404를 반환하는지 확인하세요(가져와지면 즉시 수정하고 키를 교체).
2

프로덕션에 디버그 노출 없음

에러를 유발하고(예: 존재하지 않는 라우트) 일반 에러 페이지가 표시되는지 확인하세요 — 환경 변수나 스택 트레이스가 없어야 합니다.
3

인가가 유지된다

테스트 환경에서 타인의 리소스 ID를 요청해 거부되는지 확인하세요(조회·수정·삭제 경로 모두).
4

쿠키/세션과 의존성

세션 쿠키가 Secure/HttpOnly/SameSite를 갖는지, 그리고 composer audit클린한지 확인하세요.

본 사이트의 관점: 견고한 기본값이 있어도 인가와 의존성은 당신의 몫

Laravel은 좋은 기본값을 많이 갖췄지만, 누가·무엇을·해도 되는가라는 인가의존성 신선도는 앱·운영 고유이므로 어떤 프레임워크도 자동으로 지켜줄 수 없습니다. 본 사이트가 반복해서 봐온 사고도 정교한 공격보다 설정/운영 패턴입니다: "인증은 됐는데 소유권 검사가 없다", "프로덕션에 디버그가 열려 있다", "시크릿이 노출됐다". 그래서 무게 중심은 위 표를 위에서부터 처리하고, 화려하지 않은 일을 하는 것입니다 — 모든 조회/수정을 소유자로 스코프하고, 의존성을 CVE로 모니터링하기.

다음으로 읽기

FAQ

QLaravel을 지키려면 무엇부터 해야 하나요?
A

세 가지 P0 항목입니다: (1) 프로덕션에서 APP_DEBUG=false를 보장하고 config:cache로 설정을 고정한다, (2) .env와 시크릿 파일을 공개 디렉터리 밖에 두고 권한을 엄격히 한다, (3) APP_KEY를 안전하게 관리한다(암호화·서명 쿠키·세션의 근간이므로 유출 시 교체). 이것들은 나머지 모든 것의 전제입니다. 그다음에는 인가(Policy/Gate)와 Composer 의존성 CVE 모니터링으로 넘어갑니다.

QAPP_DEBUG=true인 채로 내보내면 무엇이 위험한가요?
A

디버그가 켜져 있으면, 예외 페이지에 스택 트레이스뿐 아니라 설정 값·환경 변수·접속 정보 같은 내부 정보가 표시될 수 있습니다. 공격자는 일부러 에러를 일으켜 이를 빼낼 수 있습니다. 프로덕션에서는 APP_DEBUG=false와 APP_ENV=production으로 설정하고 config:cache로 확실히 고정하세요. 또한 Telescope나 Debugbar 같은 진단 도구를 프로덕션에 노출하지 마세요.

Qconfig:cache 이후에 env()가 null을 반환하는 이유는?
A

config:cache는 속도를 위해 설정을 하나의 파일로 컴파일하며, 그 이후 config 파일 밖에서 호출한 env()는 null을 반환합니다(캐시 시점의 .env만 읽힙니다). 해결책은 env()를 config/ 안에서만 쓰고, 앱에서는 config('...')로 값을 참조하는 것입니다. 프로덕션에서는 config/route/view를 캐시하는 것이 정석입니다 — 설정이 확실히 반영되고 앱이 빨라집니다.

Q'로그인했으면 허용된다'를 어떻게 막나요?
A

인증(로그인)과 인가(그 동작이 허용되는지)는 다릅니다. Laravel에서는 Policy/Gate를 구현하고 authorize()나 can 미들웨어를 써서 모든 조회/수정/삭제를 소유자나 권한으로 스코프하세요. 또한 $fillable을 선언해 Mass Assignment를 제어하고, $request->all()을 통째로 대입하지 마세요. 이것이 없으면 URL의 ID를 바꾸는 것만으로 타인의 데이터에 도달합니다(IDOR).

QComposer 의존성 취약점은 어떻게 관리하나요?
A

composer audit나 osv-scanner로 알려진 CVE를 기계적으로 모니터링하고, 실행 중인 버전으로 판단하며, 빠르게 패치하세요(composer.json 선언이 아니라 실제로 설치된 것으로 판단). 또한 Laravel과 PHP를 지원되는 버전으로 유지하고 EOL 버전을 방치하지 마세요. 의존성 신선도는 정교한 공격보다 사고에서 더 현실적인 요인입니다.