CDN 엣지에서 한 번에 적용하는 OWASP 보안 헤더 6가지, 실전 설정 가이드

🤖 AI Summary
OWASP Secure Headers Project가 권장하는 HTTP 보안 헤더 6가지는 XSS, 클릭재킹, MIME 스니핑, 프로토콜 다운그레이드 공격을 HTTP 응답 헤더 설정만으로 차단합니다. 이 글에서는 HSTS, CSP, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy 각각의 역할과 OWASP 권장값을 정리하고, CDN 엣지에서 모든 응답에 일괄 적용하는 장점, 그리고 CSP를 Report-Only로 먼저 검증한 뒤 Enforce로 전환하는 2단계 배포 전략을 안내합니다. 모든 권장값과 설명은 OWASP Secure Headers Project와 MDN Web Docs의 1차 출처 문서를 기준으로 정리했습니다.
블로그 목차
보안 헤더 없어도 사이트는 돌아가지만, 공격엔 무방비입니다
HTTP 보안 헤더는 웹사이트가 정상 동작하는 데 필수는 아닙니다. 설정이 없어도 페이지는 잘 뜨고 결제도 되죠. 그런데 설정이 없는 사이트는 XSS, 클릭재킹, 프로토콜 다운그레이드, MIME 스니핑 같은 공격에 그대로 노출됩니다. 공격자가 쓰기엔 너무 좋은 환경이죠.
다행히 해결책이 복잡하지 않습니다. OWASP Secure Headers Project가 권장하는 6가지 헤더를 응답에 붙이는 것만으로 주요 웹 공격 범주를 일괄 차단할 수 있거든요. 이 글에서는 각 헤더의 역할과 OWASP·MDN 공식 문서에서 제시한 권장 설정값을 정리하고, CDN 엣지에서 한 번에 적용하는 방법과 CSP 단계별 배포 전략까지 짚어봅니다.
OWASP가 권장하는 6가지 보안 헤더
OWASP Secure Headers Project 문서에 정리된 핵심 헤더와 각 헤더의 방어 대상을 먼저 한 장에 정리했어요. 표의 권장값은 OWASP 프로젝트 페이지에서 직접 인용한 수치입니다.

이어서 헤더별 OWASP 권장값과 역할을 표로 정리했습니다. 실제 설정 파일에 붙여넣을 수 있는 형태예요.
헤더 | OWASP 권장값 | 방어 대상 |
|---|---|---|
Strict-Transport-Security |
| 프로토콜 다운그레이드, 쿠키 하이재킹 |
Content-Security-Policy |
| XSS, 데이터 주입 |
X-Frame-Options |
| 클릭재킹 |
X-Content-Type-Options |
| MIME 스니핑 |
Referrer-Policy |
| Referer 유출 |
Permissions-Policy |
| 카메라·마이크·결제 API 등 강력 기능 남용 |
HSTS, HTTPS 강제로 가장 먼저 붙여야 할 헤더
HSTS는 브라우저에게 이 사이트는 HTTPS로만 접속하라고 알려주는 헤더입니다. MDN 공식 문서에 따르면 "HTTPS로만 접속되어야 하며 HTTP 접속 시도는 자동으로 HTTPS로 업그레이드된다"고 돼 있죠. 덧붙여 "유효하지 않은 인증서 에러를 사용자가 우회할 수 없게 한다"는 설명도 같은 문서에 있습니다.
권장 max-age는 2년(63072000초)입니다. MDN은 "1년도 수용 가능하지만 2년이 권장값"이라고 안내해요. 여기에 includeSubDomains를 붙이면 하위 도메인 전체에 정책이 확장됩니다.
한 가지 주의할 점이 있어요. MDN은 "HSTS 정책은 브라우저가 최소 한 번은 보안 연결에 성공해 HSTS 헤더를 받은 뒤에야 적용된다"고 경고합니다. 즉 사용자가 이전에 한 번도 방문한 적 없는 상태에서 HTTP로 접속하면 그 최초 요청은 여전히 공격 위험에 노출되죠. 이를 완화하려면 HSTS preload list에 등록해야 합니다. preload를 쓰려면 max-age가 최소 31536000(1년) 이상이고 includeSubDomains가 반드시 포함돼야 하죠.
CSP, 가장 강력하지만 가장 조심히 붙여야 할 헤더
Content-Security-Policy는 6가지 중 가장 강력한 보안 헤더예요. MDN은 "CSP는 웹사이트 관리자가 브라우저가 로드할 수 있는 리소스를 제어하는 HTTP 응답 헤더"라고 정의하고, "이를 통해 크로스사이트 스크립팅 공격을 방어한다"고 설명합니다.
주요 directive 3묶음
Fetch directives, 리소스 로딩 제어,
default-src·script-src·style-src·img-src·connect-src·font-src·object-srcDocument directives, 문서 컨텍스트 제어,
base-uri·sandboxNavigation directives, 이동 및 삽입 제어,
form-action·frame-ancestors
OWASP 권장 기본 정책은 다음과 같습니다.
이 정책은 "자기 자신 도메인에서만 리소스를 로드하고, 폼 제출과 베이스 URI도 자기 도메인으로 제한하며, object 태그는 아예 차단하고, 이 페이지를 어떤 프레임에도 포함시키지 않고, 레거시 HTTP 요청은 자동으로 HTTPS로 업그레이드한다"는 의미예요. 꽤 엄격한 편이라 인라인 스크립트·외부 CDN 리소스를 많이 쓰는 사이트는 적용 시 기능이 깨질 수 있습니다.
CSP를 안전하게 배포하는 2단계 전략
MDN이 명시적으로 권장하는 배포 절차입니다. 한 번에 Content-Security-Policy를 적용하지 말고, 먼저 Report-Only 모드로 검증부터 하세요.

MDN 원문은 "이 방식은 테스트 단계에서 위반을 보고하되 코드 실행을 차단하지 않을 때 사용한다"고 설명합니다. report-uri 또는 report-to 지시자로 위반 리포트를 수집하고, 내부 대시보드에서 실제 사이트가 어떤 리소스를 요청하는지 파악한 뒤 Enforce로 전환하는 흐름이에요. 이 단계를 건너뛰면 결제 페이지·외부 위젯·분석 스크립트가 한꺼번에 깨지는 사고가 발생합니다.
나머지 4가지 헤더, 설정 한 줄로 큰 공격 차단
HSTS와 CSP를 붙였다면 나머지 4가지는 한 줄 설정으로 각 공격 범주를 닫을 수 있어요.
X-Frame-Options, 클릭재킹 차단
공격자가 우리 사이트를 자기 페이지의 iframe 안에 숨겨두고 사용자를 속여 클릭하게 만드는 게 클릭재킹이죠. X-Frame-Options: deny를 붙이면 어떤 사이트도 우리 페이지를 프레임에 넣을 수 없습니다. OWASP 권장값은 deny예요. CSP의 frame-ancestors 'none'과 함께 쓰면 구형 브라우저까지 커버할 수 있습니다.
X-Content-Type-Options, MIME 스니핑 방지
브라우저가 응답 본문을 보고 MIME 타입을 추측하는 걸 "스니핑"이라 하는데, 이 추측이 악용되면 이미지 파일처럼 보이게 올린 스크립트가 실행되는 사고가 날 수 있어요. X-Content-Type-Options: nosniff 한 줄이면 차단됩니다.
Referrer-Policy, Referer 정보 유출 제어
사용자가 외부 링크를 클릭할 때 브라우저가 "어느 페이지에서 왔다"는 정보를 보내는데, 이 Referer에 내부 URL 경로가 포함돼 정보가 새나가는 경우가 있어요. OWASP 권장값은 no-referrer로 Referer 정보를 아예 보내지 않는 설정입니다.
Permissions-Policy, 브라우저 강력 기능 제한
카메라, 마이크, 위치 정보, 결제 API 같은 강력한 브라우저 기능을 써야 할 페이지만 허용하도록 좁히는 헤더예요. OWASP는 기본적으로 대부분 기능을 () 빈 값으로 차단하고 필요한 것만 열어주도록 권장합니다. 광고 태그나 외부 스크립트가 몰래 카메라에 접근하는 시나리오를 구조적으로 차단하는 효과가 있죠.
왜 CDN 엣지에서 적용하는 게 유리한가
보안 헤더는 애플리케이션 서버에서도 설정할 수 있지만, CDN 엣지에서 다루면 세 가지 실무적 장점이 있습니다.
오리진 코드 무수정, 레거시 프레임워크라 응답 헤더 수정이 까다로운 시스템도 CDN 레이어에서 일괄 주입 가능
멀티 오리진 일관성, 서로 다른 서비스가 섞인 구조에서도 엣지에서 동일 정책을 강제할 수 있음
즉시 롤백, CSP가 의도치 않은 리소스를 차단했을 때 CDN 설정만 되돌리면 즉시 반영
특히 CSP처럼 정책을 자주 조정해야 하는 헤더일수록 CDN 엣지 관리 장점이 커지죠. 스피디 S-CDN에서 보안 헤더 적용을 고려하고 계시다면 스피디 기술팀 문의로 구체 방안을 받아볼 수 있습니다.
이것만 기억하세요
OWASP Secure Headers Project가 권장하는 6가지 헤더(HSTS, CSP, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy)는 XSS·클릭재킹·MIME 스니핑·프로토콜 다운그레이드 공격을 HTTP 응답 헤더만으로 차단합니다. HSTS는 max-age=63072000 with includeSubDomains 조합이 표준이고, CSP는 반드시 Report-Only로 먼저 검증한 뒤 Enforce로 전환해야 기능 사고를 막을 수 있어요. 헤더 관리는 애플리케이션보다 CDN 엣지에서 다루는 쪽이 오리진 수정 없이 즉시 반영·즉시 롤백이 가능해 실무에서 훨씬 유리합니다.
자주 묻는 질문 (FAQ)
Q. 모든 헤더를 한 번에 적용해도 되나요?
HSTS와 보조 4가지(X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy)는 대부분 사이트에서 한 번에 적용해도 기능 문제가 거의 없습니다. 다만 CSP는 반드시 Report-Only 모드로 먼저 검증한 뒤 Enforce로 전환하는 것이 안전합니다. 외부 스크립트나 인라인 스타일이 많은 사이트에서 CSP를 바로 적용하면 기능이 깨질 수 있기 때문입니다.
Q. HSTS를 잘못 설정하면 어떤 문제가 생기나요?
HSTS는 브라우저에 캐시되므로 max-age 기간 동안 HTTP 접속이 강제로 차단됩니다. 테스트 없이 바로 2년짜리 HSTS를 붙였다가 HTTPS 인증서 문제가 생기면 복구가 까다로워요. 초기 적용 시에는 짧은 max-age로 시작해서 안정성을 확인한 뒤 권장값인 63072000초로 늘리는 방법이 실무적입니다. preload list 등록은 더더욱 충분한 검증 후에 진행해야 합니다.
Q. CSP Report-Only 검증은 얼마나 오래 돌려야 하나요?
정답은 없지만 최소 1~2주 이상 실제 트래픽을 받으면서 리포트를 누적 관찰하는 것을 권장합니다. 결제·로그인·외부 위젯 같은 중요 경로에서 위반 리포트가 0건이 되는 시점이 Enforce 전환 시그널입니다. 트래픽 패턴이 복잡한 대형 사이트라면 한 달 이상 걸리기도 합니다.
Q. X-Frame-Options과 CSP frame-ancestors 중 뭐가 우선인가요?
최신 브라우저는 CSP의 frame-ancestors를 우선 적용합니다. 다만 구형 브라우저 호환성을 위해 두 헤더를 함께 설정하는 것이 일반적입니다. OWASP 권장값도 X-Frame-Options에는 deny, CSP에는 frame-ancestors 'none'을 함께 포함하고 있으니 병행 설정이 안전합니다.



