OneWebDesk

CSP 생성기

사이트 리소스에 맞는 Content-Security-Policy 헤더를 생성합니다.

Content-Security-Policy(CSP)는 브라우저가 어떤 출처의 스크립트·스타일·이미지·폰트·연결을 허용할지 지정하는 보안 헤더입니다. 잘 설계된 CSP는 XSS(크로스 사이트 스크립팅)와 데이터 탈취, 클릭재킹 같은 공격의 영향을 크게 줄여 줍니다. 이 CSP 생성기는 default-src, script-src 등 주요 디렉티브별로 허용 소스를 체크박스로 고르고 커스텀 도메인을 추가하면, 그에 맞는 헤더 문자열을 실시간으로 조립해 줍니다.

만든 CSP는 응답 헤더(Content-Security-Policy)나 <meta> 태그로 적용할 수 있습니다. 처음에는 보고 전용(Content-Security-Policy-Report-Only)으로 배포해 위반 리포트를 모으며 정책을 다듬은 뒤 본격 적용하는 것을 권장합니다. 모든 계산은 브라우저 안에서만 일어나며 입력값은 어디에도 전송되지 않습니다.

허용할 디렉티브를 켜고, 소스 키워드를 고르거나 커스텀 도메인을 입력하세요.

default-src
Content-Security-Policy 헤더CSP
default-src 'self'
<meta> 태그
<meta http-equiv="Content-Security-Policy" content="default-src 'self'">

주요 디렉티브 이해하기

CSP는 리소스 종류별로 허용 출처를 나눠 지정합니다. 가장 중요한 출발점은 default-src로, 개별 디렉티브가 지정되지 않은 리소스에 대한 기본 정책 역할을 합니다.

  • default-src: 다른 *-src 디렉티브가 없을 때 적용되는 기본 폴백.
  • script-src: 자바스크립트 실행 출처. 가장 보안에 민감합니다.
  • style-src: CSS 스타일시트와 인라인 스타일 출처.
  • img-src: 이미지 로드 출처.
  • font-src: 웹폰트 출처.
  • connect-src: fetch·XHR·WebSocket·EventSource 등 네트워크 연결 출처.
  • frame-src: iframe으로 삽입할 수 있는 출처.

소스 키워드의 의미와 unsafe-inline의 위험

각 디렉티브에는 키워드와 도메인을 섞어 넣을 수 있습니다. 'self'는 같은 출처(scheme + host + port)를, 'none'은 모든 출처 차단을 의미합니다. data:는 인라인 데이터 URI를, https:는 임의의 HTTPS 출처를 허용합니다.

  • 'unsafe-inline': <script> 인라인 코드나 onclick같은 인라인 핸들러, 인라인 <style>을 허용합니다. 이 키워드를 script-src에 켜면 CSP의 XSS 방어 효과가 사실상 사라지므로 가급적 쓰지 말고, nonce나 hash 방식으로 대체하세요.
  • https:나 와일드카드(*)처럼 지나치게 넓은 출처는 신뢰할 수 없는 제3자 리소스까지 허용할 수 있으니, 실제로 쓰는 CDN·API 도메인으로 좁히는 편이 안전합니다.
  • 'none'은 단독으로만 의미가 있습니다. 다른 출처와 함께 쓰면 효과가 없습니다.

적용과 점진적 도입

  1. 먼저 Content-Security-Policy-Report-Only 헤더로 배포해 위반 리포트를 수집합니다.
  2. 리포트를 보며 정상 동작에 필요한 출처를 디렉티브에 추가해 정책을 다듬습니다.
  3. 위반이 사라지면 본 헤더(Content-Security-Policy)로 전환해 실제 차단을 활성화합니다.

XSS 방어를 강화하려면 script-src에서 'unsafe-inline'을 빼고 nonce·hash 기반으로 운영하는 것이 모범 사례입니다. 적용을 마쳤다면 보안 헤더 점검으로 CSP가 응답에 실제로 내려가고 있는지 확인하세요.

소스 표현식 빠른 참조

디렉티브 값에 자주 들어가는 소스 표현식과 그 의미를 정리했습니다. 'nonce-...'·'sha256-...'·'strict-dynamic'은 작은따옴표가 헤더 문자열에 그대로 포함되어야 합니다(예: script-src 'nonce-r4nd0m').

소스 표현식허용 대상메모
'self'같은 출처(scheme+host+port)서브도메인은 미포함. cdn.example.com은 별도로 추가해야 함
'none'전부 차단단독일 때만 유효
'unsafe-inline'인라인 스크립트/스타일·인라인 핸들러nonce/hash가 함께 있으면 최신 브라우저가 무시함
'unsafe-eval'eval()·new Function()·문자열 setTimeout일부 구형 라이브러리·템플릿 엔진이 요구
'nonce-...'같은 nonce를 가진 인라인 태그요청마다 새로 생성된 무작위 값이어야 함
'sha256-...'해시가 일치하는 인라인 코드코드 한 글자만 바뀌어도 해시 재계산 필요
'strict-dynamic'nonce/hash로 신뢰된 스크립트가 동적으로 부른 스크립트켜면 호스트·https: 화이트리스트가 무시됨
data:data URIimg-src엔 흔하지만 script-src엔 위험

frame-ancestors와 frame-src는 다릅니다

이름이 비슷해 헷갈리지만 방향이 반대입니다. frame-src내 페이지가 어떤 출처를 iframe으로 품을 수 있는가를, frame-ancestors어떤 출처가 내 페이지를 iframe으로 품을 수 있는가(클릭재킹 방어, X-Frame-Options 대체)를 제어합니다. 클릭재킹을 막으려면frame-ancestors 'self' 또는 frame-ancestors 'none'을 쓰세요. 단,frame-ancestors<meta> 태그에서는 동작하지 않으므로 반드시 응답 헤더로 내려야 합니다.

예시로 읽어 보기

Google Fonts와 자체 API를 쓰는 SPA에 적용할 만한 정책을 가정해 보겠습니다.

default-src 'self'; script-src 'self' 'nonce-AbC123'; style-src 'self' https://fonts.googleapis.com; font-src https://fonts.gstatic.com; img-src 'self' data:; connect-src 'self' https://api.example.com; frame-ancestors 'none'

  • 인라인 부트스트랩 스크립트는 <script nonce="AbC123">처럼 같은 nonce를 달아야만 실행됩니다.
  • Google Fonts의 CSS는 fonts.googleapis.com, 실제 폰트 파일은 fonts.gstatic.com으로 출처가 나뉘므로 둘 다 필요합니다.
  • 아이콘을 base64로 인라인하므로 img-srcdata:를 허용했습니다.
  • connect-src에 자체 API만 넣어 다른 도메인으로의 fetch·XHR 유출을 막습니다.
  • frame-ancestors 'none'으로 외부 사이트의 iframe 삽입(클릭재킹)을 차단합니다.

흔한 실수 / 함정

  • 'self'가 서브도메인까지 덮는다고 오해하기 쉽습니다. example.com에서 내려준 CSP의 'self'cdn.example.com을 포함하지 않으므로 서브도메인은 명시적으로 추가해야 합니다.
  • nonce/hash와 'unsafe-inline'을 같이 넣으면 안전해진다고 생각하는 경우가 있는데, CSP3 브라우저는 nonce/hash가 있으면 'unsafe-inline'을 무시합니다(구형 브라우저 폴백 용도로만 의미). 반대로 nonce를 페이지마다 고정값으로 재사용하면 보호 효과가 사라집니다 — 요청마다 새로 생성해야 합니다.

자주 묻는 질문

default-src만 지정하면 충분한가요?
default-src는 다른 디렉티브가 없을 때의 폴백입니다. 하지만 script-src, style-src 등을 명시하지 않으면 모두 default-src를 따르게 되므로, 리소스 종류별로 필요한 만큼 좁혀서 별도 지정하는 것이 더 안전합니다.
unsafe-inline은 절대 쓰면 안 되나요?
스타일에 한해 불가피하게 쓰는 경우는 있지만, script-src에서는 피하는 것이 강력히 권장됩니다. 인라인 스크립트를 허용하면 XSS 공격자가 주입한 코드도 실행될 수 있어 CSP의 핵심 방어가 무력화됩니다. nonce나 hash 방식으로 대체하세요.
생성한 CSP는 어디에 넣나요?
웹 서버나 프레임워크에서 응답 헤더 Content-Security-Policy로 추가하는 것이 가장 권장됩니다. <meta http-equiv="Content-Security-Policy"> 태그로도 적용할 수 있지만 frame-ancestors 등 일부 디렉티브는 메타 태그에서 동작하지 않습니다.
정책이 너무 엄격해서 사이트가 깨지면 어떻게 하나요?
Report-Only 모드로 먼저 배포해 어떤 리소스가 차단되는지 위반 리포트로 확인한 뒤, 필요한 출처를 디렉티브에 추가하며 점진적으로 강화하세요. 한 번에 완벽한 정책을 만들기보다 반복해서 다듬는 편이 안전합니다.
입력한 도메인이 서버로 전송되나요?
아니요. 이 도구는 전적으로 브라우저에서만 동작하며 입력한 도메인이나 선택값은 어떤 서버로도 전송되지 않습니다.

관련 가이드

관련 도구

웹 보안