보안 헤더 설정 방법, Apache·Nginx 예시

핵심 요약
  • 보안 헤더는 서버 응답에 붙이는 한 줄 규칙으로, 브라우저가 위험한 동작을 스스로 막게 한다.
  • X-Content-Type-Options, Referrer-Policy, Permissions-Policy는 부작용이 적어 먼저 적용하고, HSTS와 CSP는 단계적으로 적용한다.
  • Apache는 Header always set, Nginx는 add_header 끝에 always를 붙이고, 적용 뒤 응답 헤더를 직접 확인한다.

보안 헤더는 웹서버가 페이지를 보내면서 함께 붙이는 짧은 설명서입니다. “이 사이트는 HTTPS로만 열어라”, “다른 사이트 안에 끼워 넣지 마라” 같은 지시를 브라우저에 전하면 브라우저가 위험한 동작을 대신 막아 줍니다. 사이트 코드를 고치지 않고 서버 설정만으로 추가할 수 있어 소규모 홈페이지에도 부담이 적습니다.

이 글은 가장 많이 쓰는 6개 헤더를 하나씩 설명하고 Apache와 Nginx 설정 예시를 한곳에 모았습니다. 값은 2026년 10월 24일 기준 MDN과 OWASP 문서로 확인했습니다. 검사 결과에서 부족하다고 나온 헤더가 있다면 아래 소제목에서 해당 항목을 바로 찾아보세요.

6개 헤더 한눈에 보기

헤더역할OWASP 권장 예시위험도
Strict-Transport-SecurityHTTPS로만 접속하도록 기억시킴max-age=63072000; includeSubDomains; preload높음, 단계 적용
Content-Security-Policy불러올 수 있는 자원을 제한사이트마다 다름높음, 단계 적용
X-Content-Type-Options파일 형식 추측 금지nosniff낮음
Referrer-Policy이동 시 이전 주소 노출 범위strict-origin-when-cross-origin낮음
X-Frame-Options다른 사이트 프레임 삽입 차단DENY중간
Permissions-Policy카메라·위치 같은 기능 제한geolocation=(), camera=(), microphone=()낮음

Strict-Transport-Security (HSTS)

브라우저에게 이 사이트는 HTTPS로만 접속하라고 일정 기간 기억시킵니다. MDN에 따르면 max-age 가 필수이며 초 단위입니다. includeSubDomains 는 하위 도메인까지 적용합니다. 이 헤더는 HTTPS 응답에서만 인정되고 HTTP로 보낸 헤더는 브라우저가 무시합니다.

잘못 적용하면 인증서 문제 때 사용자가 경고를 넘길 수 없어 길게 접속이 막힐 수 있으므로 짧은 기간부터 시작합니다. 단계별 방법과 preload 주의점은 HSTS 설정 방법 글에서 자세히 다룹니다.

HSTS·CSP 같은 보안 헤더가 어떻게 설정되어 있는지 바로 확인할 수 있습니다.

보안 헤더 검사하기

Content-Security-Policy (CSP)

브라우저가 불러올 수 있는 스크립트, 이미지, 프레임의 출처를 제한해 XSS 피해를 줄입니다. OWASP는 CSP에 하나의 권장값을 두지 않고 복잡하다고 설명합니다. 사이트가 쓰는 외부 서비스에 따라 정책이 달라지기 때문입니다. 처음에는 Content-Security-Policy-Report-Only 로 차단 없이 위반만 기록해 보고, 다듬은 뒤 적용하세요. 자세한 과정은 Content-Security-Policy 적용 가이드에 있습니다.

X-Content-Type-Options

값은 nosniff 하나뿐입니다. MDN에 따르면 브라우저가 내용을 보고 파일 형식을 추측하지 못하게 해, 업로드된 텍스트 파일이 HTML처럼 실행되는 일을 막습니다. 효과를 내려면 서버가 모든 파일에 정확한 Content-Type 을 보내야 합니다. 부작용이 거의 없어 가장 먼저 적용하기 좋습니다.

Referrer-Policy

다른 사이트로 이동할 때 이전 주소가 얼마나 전달되는지 정합니다. MDN 기준 브라우저 기본값은 strict-origin-when-cross-origin 이고, OWASP도 같은 값을 권장하며 브라우저 기본값에 맡기지 말고 명시하라고 안내합니다. 주소에 개인 정보나 토큰이 들어가는 사이트라면 더 엄격한 no-referrer 도 선택지입니다.

X-Frame-Options

내 페이지를 다른 사이트의 <iframe> 안에 넣는 행위를 막아 클릭재킹(보이지 않는 프레임 위에서 클릭을 유도하는 기법)을 방어합니다. 값은 DENY 또는 SAMEORIGIN 이며 ALLOW-FROM 은 더 이상 쓰지 않습니다. MDN은 외부 출처를 허용하려면 CSP의 frame-ancestors 를 쓰라고 안내합니다. 두 헤더를 함께 두어도 되지만 관리 지점은 하나로 정하는 편이 헷갈리지 않습니다.

Permissions-Policy

카메라, 마이크, 위치 정보 같은 브라우저 기능을 페이지와 그 안의 프레임이 쓸 수 있는지 정합니다. 쓰지 않는 기능은 () 로 끕니다. MDN은 이 헤더가 실험적 기능이고 브라우저 지원이 제한적이라고 표시하므로 지원 현황을 확인하고 쓰세요. 사이트가 지도나 영상통화처럼 해당 기능을 실제로 쓴다면 그 기능만 허용 목록에 넣어야 합니다.

Apache 설정 예시

mod_headers 모듈이 켜져 있어야 합니다. always 를 붙이면 오류 응답에도 헤더가 붙습니다. 가상호스트 또는 .htaccess 에 넣습니다.

<IfModule mod_headers.c>
  Header always set X-Content-Type-Options "nosniff"
  Header always set Referrer-Policy "strict-origin-when-cross-origin"
  Header always set X-Frame-Options "SAMEORIGIN"
  Header always set Permissions-Policy "geolocation=(), camera=(), microphone=()"
  # HTTPS 가상호스트에서만, 처음엔 짧은 max-age로 시작
  Header always set Strict-Transport-Security "max-age=300"
  # CSP는 Report-Only로 먼저 시험
  Header always set Content-Security-Policy-Report-Only "default-src 'self'"
</IfModule>

설정을 바꾼 뒤에는 apachectl configtest 로 문법을 확인하고 재시작이 아닌 reload로 반영하세요.

Nginx 설정 예시

add_header 는 기본적으로 200, 301 같은 일부 상태 코드에만 붙습니다. 오류 응답까지 붙이려면 always 가 필요합니다. nginx 문서에 따르면 하위 블록에 add_header 가 하나라도 있으면 상위 설정을 상속하지 않으니, location 안에서 다른 add_header 를 쓰면 보안 헤더도 그곳에 다시 적어야 합니다.

server {
    listen 443 ssl;
    server_name example.com;

    add_header X-Content-Type-Options "nosniff" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header Permissions-Policy "geolocation=(), camera=(), microphone=()" always;
    add_header Strict-Transport-Security "max-age=300" always;
    add_header Content-Security-Policy-Report-Only "default-src 'self'" always;
}

nginx -t 로 확인한 뒤 nginx -s reload 로 반영합니다.

적용 후 확인과 함께 정리할 항목

응답 헤더는 아래 명령으로 직접 볼 수 있습니다.

curl -sI https://example.com/ | grep -iE 'strict-transport|content-security|x-content-type|referrer|x-frame|permissions'

OWASP는 X-Powered-By 헤더를 제거하고 Server 헤더도 제거하거나 중립 값으로 바꾸라고 안내합니다. 방법은 서버 버전 정보 숨기기 글에 있습니다. 헤더 확인은 외부에서 보이는 응답만 보기 때문에 사이트 내부 취약점까지 판단하지 못한다는 점을 기억하세요.

보안 헤더 검사HSTS·CSP·X-Content-Type-Options 등 6개 헤더의 값 평가을 무료로 확인할 수 있습니다.

보안 헤더 검사하기

자주 묻는 질문

보안 헤더가 없으면 사이트가 바로 해킹되나요?

그렇지는 않습니다. 보안 헤더는 취약점을 고치는 수단이 아니라 피해 가능성을 줄이는 추가 방어층입니다. 코드와 소프트웨어 업데이트를 대신하지 못합니다.

X-XSS-Protection 헤더도 넣어야 하나요?

OWASP는 이 헤더가 더 이상 권장되지 않으며 오히려 문제를 만들 수 있어 설정하지 않거나 0으로 두라고 안내합니다. XSS 방어는 CSP와 출력 이스케이프에 맡기세요.

헤더를 넣었는데 반영되지 않습니다.

Apache는 mod_headers 모듈이 켜져 있는지, Nginx는 하위 블록에 다른 add_header가 있어 상위 설정이 덮어써지지 않았는지 확인하세요. 캐시나 CDN이 이전 응답을 보여 주는 경우도 많습니다.

모든 헤더를 한꺼번에 적용해도 되나요?

권장하지 않습니다. HSTS는 잘못 설정하면 오랫동안 접속이 막힐 수 있고, CSP는 사이트 기능이 깨질 수 있습니다. 부작용이 적은 헤더부터 넣고 두 헤더는 단계적으로 늘리세요.

확인한 자료

기술 정보는 2026-10-24에 위 자료로 확인했습니다. 소프트웨어 버전·기본값·서비스 정책은 바뀔 수 있으므로 적용 전 각 문서의 최신 내용을 확인하세요. 이 글은 일반 정보이며 특정 서비스 가입을 권하지 않습니다.

Next
웹사이트 보안

HSTS 설정 방법, max-age와 단계적 적용

HSTS 헤더의 max-age, includeSubDomains, preload 의미와 Apache·Nginx 설정 예시, 5분에서 1년까지 단계적 적용 순서, preload 등록 전 주의점을 정리했습니다.

가이드 보기 →
웹사이트 보안

CSP 적용 가이드, Report-Only부터 시작

CSP를 안전하게 적용하는 순서를 정리했습니다. Report-Only로 시작하는 방법, default-src·script-src·frame-ancestors 등 주요 지시어, unsafe-inline 문제와 nonce, Apache·Nginx 예시를 다룹니다.

가이드 보기 →
서버 보안

서버 버전 정보 숨기기, Apache Nginx PHP

Apache ServerTokens·ServerSignature, Nginx server_tokens, PHP expose_php 설정으로 응답 헤더의 버전 노출을 줄이는 방법과 적용 후 curl 확인법, 이 설정의 한계를 정리했습니다.

가이드 보기 →
웹사이트 보안

웹사이트 악성코드 감염 대처, 초기 대응과 증거 보존

웹사이트 악성코드 감염이 의심될 때 먼저 할 일을 순서대로 정리했습니다. 격리, 증거 보존, 비밀번호 교체, 정리와 재발 방지, Search Console 검토 요청까지 다룹니다.

가이드 보기 →
웹사이트 보안

홈페이지 해킹 확인 방법, Search Console 점검

내 홈페이지가 해킹됐는지 확인하는 순서를 정리했습니다. 검색 결과 스팸, 리디렉션, Search Console 보안 문제 보고서, 파일·로그 점검과 공개 검사의 한계까지 다룹니다.

가이드 보기 →