← 가이드로 / 웹사이트

HTTP 보안 헤더 정리: HSTS·CSP 등 6가지 설정법

HSTS, CSP, X-Frame-Options, Referrer-Policy, Permissions-Policy의 역할과 권장 값, 검토로 표시된 헤더가 항상 취약점은 아닌 이유를 알아보세요.

작성 IPNixa게시

웹사이트 보안 헤더 확인하기

보안 헤더란

모든 HTTP 응답은 Content-Type: text/html처럼 이름과 값으로 이루어진 헤더로 시작합니다. 그중 몇 가지는 브라우저가 페이지를 다루는 방식을 바꿉니다. 보내는 데 비용이 들지 않고 모든 방문자에게 적용되며, 페이지 HTML이 아니라 서버, 호스팅 플랫폼, 콘텐츠 전송 네트워크(CDN)에서 설정합니다.

IPNixa는 Cloudflare가 모든 페이지와 함께 제공하는 _headers 파일에 자체 헤더를 설정합니다. 이 사이트의 검사기는 입력한 주소를 IPNixa 서버에서 요청하고, 리디렉션을 최대 3번까지 따라간 뒤 최종 응답의 헤더를 읽습니다.

가장 중요한 보안 헤더 6가지

IPNixa 검사기가 판정하는 헤더입니다. 표의 값은 흔히 쓰는 안전한 출발점이므로 사이트에 필요한 대로 조정하세요.

헤더별 방어 대상과 일반적인 값
헤더막아 주는 것일반적인 값
Strict-Transport-Security (HSTS)첫 방문 이후 연결이 암호화되지 않은 HTTP로 격하되는 것max-age=31536000; includeSubDomains
Content-Security-Policy (CSP)주입된 스크립트의 실행(교차 사이트 스크립팅 완화)default-src 'self'; script-src 'self'; frame-ancestors 'none'
X-Frame-Options 또는 CSP frame-ancestors다른 사이트가 페이지를 숨겨진 프레임에 불러오는 것(클릭재킹)DENY 또는 frame-ancestors 'none'
X-Content-Type-Options브라우저가 파일 형식을 추측해 데이터를 스크립트로 실행하는 것nosniff
Referrer-Policy경로와 쿼리 문자열을 포함한 전체 페이지 주소가 다른 사이트로 새는 것strict-origin-when-cross-origin
Permissions-Policy페이지나 삽입된 프레임이 카메라, 마이크, 위치를 사용하는 것camera=(), microphone=(), geolocation=()

IPNixa 검사기의 헤더별 판정 기준

각 헤더는 있음, 검토, 없음 세 가지 상태 중 하나로 표시됩니다. 검토는 헤더는 있지만 값이 아래 기준에 맞지 않는다는 뜻입니다. 보안 점수가 아니라 자세히 살펴보라는 신호입니다.

실제 사이트가 보내는 헤더: 표본 조사

2026년 11월 2일, 검사기와 같은 사용자 에이전트로 다섯 개 사이트의 홈페이지를 요청하고 응답을 IPNixa 판정 규칙으로 평가했습니다. 헤더는 자주 바뀌므로 특정 시점의 기록으로 보세요.

홈페이지 다섯 곳의 판정 결과(2026년 11월 2일)
사이트HSTSCSP프레임 제어nosniffReferrerPermissions
github.com있음검토있음있음있음없음
ipnixa.com있음검토있음있음있음있음
www.wikipedia.org있음없음없음없음없음없음
www.google.com없음보고 전용있음없음없음없음
example.com없음없음없음없음없음없음

표본 읽기: 검토가 취약하다는 뜻은 아닙니다

GitHub의 정책은 스크립트를 자체 리소스 호스트와 특정 해시로만 제한하므로 엄격한 편입니다. 검토로 표시된 이유는 style-src가 'unsafe-inline'을 허용하기 때문인데, 판정 규칙은 정책 전체에서 이 키워드를 찾습니다. 인라인 스타일은 인라인 스크립트보다 위험이 훨씬 작으므로, 이는 보안 구멍이라기보다 의도적인 절충입니다.

IPNixa 사이트는 다른 이유로 검토로 표시됩니다. 정책에 frame-ancestors 'none'만 있어 프레임 삽입은 막지만 스크립트는 제한하지 않기 때문입니다. 결과를 있는 그대로 공개합니다.

Google 홈페이지는 스크립트 정책을 Content-Security-Policy-Report-Only로 보내 위반을 차단하지 않고 보고만 하며, 이 응답에는 HSTS도 없었습니다. 대형 사이트는 브라우저 프리로드 목록 같은 다른 방법으로 HTTPS를 강제할 수 있습니다. Wikipedia 포털 페이지는 매우 긴 HSTS max-age를 보내지만 그 밖의 헤더는 거의 없습니다. 이 결과로 각 사이트의 전반적인 보안 수준을 알 수는 없으며, 각 응답이 어떤 브라우저 보호 장치를 요청하는지만 보여 줍니다.

내 사이트에 보안 헤더 추가하기

헤더는 한 번에 하나씩 추가하세요. 추가할 때마다 사이트를 새로고침하고 페이지, 로그인, 삽입된 동영상, 결제 양식이 정상적으로 작동하는지 확인한 뒤 다음 헤더로 넘어갑니다.

  1. 위험이 적은 헤더부터 시작하세요. X-Content-Type-Options: nosniff, Referrer-Policy: strict-origin-when-cross-origin, X-Frame-Options: DENY입니다. 단, 다른 사이트가 내 페이지를 프레임에 넣어야 한다면 X-Frame-Options는 제외합니다.
  2. HSTS는 max-age를 300처럼 짧게 시작하고, 모든 하위 도메인이 HTTPS로 작동하는지 확인한 뒤 31536000으로 늘리세요. includeSubDomains는 모든 하위 도메인이 HTTPS를 지원할 때만 추가합니다.
  3. Content-Security-Policy를 작성해 먼저 Content-Security-Policy-Report-Only로 보내세요. 위반 보고서를 수집하거나 브라우저 콘솔을 지켜보면서 정상적인 출처는 수정하거나 허용한 다음, 실제로 적용되는 헤더로 전환합니다.
  4. 사용하지 않는 강력한 기능을 나열한 Permissions-Policy를 추가하세요. 예: camera=(), microphone=(), geolocation=().
  5. nginx에서는 always 플래그와 함께 add_header를, Apache에서는 Header always set을 사용하세요. 정적 호스팅이나 CDN에서는 플랫폼의 헤더 파일이나 응답 헤더 규칙을 사용합니다.
  6. IPNixa 헤더 검사를 다시 실행하세요. 빠진 헤더마다 nginx, Apache, _headers 파일에 바로 붙여 넣을 수 있는 줄을 보여 줍니다.

HSTS 프리로드와 기타 주의 사항

HSTS 프리로드 목록은 브라우저에 내장되어 있어 첫 방문부터 HTTPS를 사용하게 합니다. 도메인을 등록하려면 max-age 1년 이상, includeSubDomains, preload 지시문이 필요하며, 목록에서 빠지더라도 사용자에게 반영되기까지 몇 달이 걸립니다. 내부용을 포함한 모든 하위 도메인이 계속 HTTPS를 쓸 수 있을 때만 등록하세요.

X-XSS-Protection은 더 이상 쓰이지 않습니다. 최신 브라우저는 이 헤더를 무시하며 CSP가 그 역할을 대신합니다. 교차 출처 격리 헤더(Cross-Origin-Opener-Policy, Cross-Origin-Embedder-Policy, Cross-Origin-Resource-Policy)는 검사기가 판정하지 않습니다. 공유 메모리 같은 기능을 쓰는 사이트에만 필요하고, 켜면 외부 삽입 콘텐츠가 차단될 수 있기 때문입니다.

자주 묻는 질문

헤더가 없으면 방문하기에 위험한 사이트인가요?

아니요. 보안 헤더는 특정 공격에 대해 브라우저 쪽 보호를 더해 줄 뿐입니다. 헤더가 없어도 잘 관리되는 사이트일 수 있고, 헤더를 모두 갖춰도 다른 결함이 있을 수 있습니다. 결과는 방문자를 위한 판정이 아니라 사이트 운영자를 위한 점검 목록으로 활용하세요.

검사기에 없던 헤더가 내 브라우저에는 보이는 이유는 무엇인가요?

사이트는 페이지, 국가, 로그인 상태, CDN 위치에 따라 다른 헤더를 보낼 수 있습니다. 검사기는 입력한 주소에 대해 Cloudflare 네트워크에서 쿠키 없이 가져온 응답 하나를 읽습니다.

X-Frame-Options와 frame-ancestors 중 무엇을 써야 하나요?

CSP의 frame-ancestors가 최신 방식이며 특정 사이트만 허용할 수도 있습니다. X-Frame-Options도 함께 보내면 오래된 브라우저까지 보호할 수 있습니다. 둘 다 있으면 최신 브라우저는 frame-ancestors를 따릅니다.

로그인이 필요한 페이지도 검사할 수 있나요?

아니요. 검사기는 쿠키나 인증 정보를 보내지 않으며 사설 주소와 로컬 주소는 거부합니다. 로그인이 필요한 페이지나 사설 네트워크의 페이지라면 브라우저 개발자 도구나 curl -I로 원본 응답 헤더를 복사해 검사기에 붙여 넣으세요. 붙여 넣은 헤더는 브라우저 안에서 분석합니다.

출처·참고 자료