ZeroTool Workbench

CSP 헤더 생성기

지시문, 해시, nonce로부터 Content-Security-Policy 헤더 구축. 엄격 모드 템플릿과 Report-Only 디버그 모드, Express / Nginx 스니펫 지원. 100% 브라우저.

100% 클라이언트 사이드 데이터가 브라우저 밖으로 나가지 않습니다 무료 · 회원가입 불필요
Mode
Inline script & style hash calculator
Hash will appear here
  

사용 방법

  1. 프리셋을 선택합니다. Strict는 OWASP의 “strict CSP” 권장 구성, Empty는 빈 정책에서 시작합니다.
  2. 모드를 전환합니다. Report-Only로 시작해 위반은 보고하되 실제 사용자 흐름은 막지 않도록 합니다.
  3. 각 지시문에서 키워드 칩(‘self’, ‘strict-dynamic’, ‘none’) 또는 스킴 칩(https:, data:)을 클릭하거나, 호스트/경로를 입력하고 Enter를 누르세요.
  4. 해시 계산기로 특정 인라인 스크립트/스타일을 허용하는 해시를 만들고, + nonce 버튼으로 새 nonce를 즉시 추가할 수 있습니다.
  5. 출력 탭을 전환해 필요한 형식을 복사하세요: HTTP 헤더, HTML <meta>, Express (helmet), Nginx add_header.

Strict CSP 시작 구성

Strict 프리셋은 세 가지 규칙으로 짜여 있습니다: script-src‘self’ ‘strict-dynamic’, object-src‘none’, base-uri‘self’. 요청별 nonce 또는 스크립트별 해시와 결합하면 대부분의 반사형/저장형 XSS 페이로드를 차단할 수 있습니다. 피싱 형 공격까지 막고 싶다면 form-action‘self’, frame-ancestors‘none’으로 잠그세요.

흔한 함정

  • ’none’은 단독으로만 작동합니다. 다른 소스와 함께 적으면 브라우저가 해당 지시문을 무시합니다.
  • frame-ancestors는 HTTP 헤더 전용. <meta>로 보내면 무시되며, report-uri, report-to, sandbox도 동일합니다.
  • 해시/nonce가 있으면 ‘unsafe-inline’은 무시됩니다. 최신 브라우저는 더 안전한 쪽을 우선합니다.
  • default-src는 반드시 정의하세요. 누락된 fetch 지시문은 default-src로 폴백하며, 이것이 없으면 새로 추가될 지시문에도 폴백이 적용되지 않습니다.
  • 커스텀 호스트에 세미콜론을 넣지 마세요. 세미콜론은 정책을 끊어 이후 모든 지시문을 손상시킵니다.

해시 vs. Nonce

정적 인라인 콘텐츠(애널리틱스 스니펫, 크리티컬 CSS, 서버 렌더링되는 보조 스크립트)에는 해시를 사용합니다. 정적 HTML과 엣지 캐시와 잘 맞고, 요청별 값을 필요로 하지 않습니다.

요청마다 새로 렌더링되는 콘텐츠에는 nonce를 사용합니다. 서버가 헤더에 ‘nonce-XYZ’를 넣고, 동일한 값을 모든 <script nonce=“XYZ”>에 새깁니다. ‘strict-dynamic’과 함께 사용하면 신뢰된 스크립트의 자식 스크립트도 신뢰가 상속돼 거대한 호스트 허용 목록을 유지할 필요가 없습니다.

배포 치트시트

  • Nginx: Nginx 탭 내용을 server 블록에 붙여넣고 reload. always 플래그는 오류 응답에도 헤더를 강제합니다.
  • Apache: .htaccesshttpd.confHeader always set Content-Security-Policy ”…”를 작성합니다.
  • Express / Node: helmet 스니펫을 붙여넣고, useDefaultsfalse로 설정해 정책이 helmet 기본값과 조용히 병합되지 않도록 하세요.
  • Cloudflare Pages / Vercel / Netlify: HTTP 헤더 형식을 각 플랫폼의 헤더 설정(_headers, vercel.json, netlify.toml)에 붙여넣습니다.

FAQ

Content Security Policy란 무엇인가요?

CSP는 브라우저에 스크립트, 스타일, 이미지, 폰트, 프레임 등 신뢰할 수 있는 콘텐츠 출처를 알려주는 HTTP 응답 헤더입니다. 출력 인코딩과 함께 사용하면 XSS, 클릭재킹, 데이터 인젝션 공격에 대한 가장 강력한 브라우저 측 방어선이 됩니다.

Enforce와 Report-Only 중 무엇을 먼저 배포해야 하나요?

항상 `Content-Security-Policy-Report-Only`와 `report-uri`(또는 `report-to`) 엔드포인트로 시작하세요. 1~2주 동안 실제 트래픽의 위반 사례를 수집해 잘못된 부분을 코드에서 수정한 다음, 강제형 `Content-Security-Policy`로 전환합니다.

인라인 스크립트에 'unsafe-inline'이 꼭 필요한가요?

가능한 한 피하세요. 최신 CSP는 콘텐츠 기반 해시(`'sha256-...'`, `'sha384-...'`, `'sha512-...'`)와 요청별 nonce(`'nonce-...'`)를 지원합니다. 이 페이지의 해시 계산기로 특정 스니펫에 맞는 해시를 즉시 만들 수 있습니다.

'strict-dynamic'은 어떤 역할을 하나요?

nonce나 해시로 신뢰된 스크립트가 런타임에 다른 스크립트를 모든 CDN 호스트를 나열하지 않고도 로드할 수 있게 합니다. 모던 앱에서 권장되는 패턴이며, 자식 스크립트에 대해 호스트 기반 허용 목록을 무효화하고 일반적인 우회를 차단합니다.

생성된 헤더는 어디에 배포해야 하나요?

원본 서버에서 `Content-Security-Policy`를 전송하세요(Nginx `add_header`, Apache `Header set`, Cloudflare Transform Rules, Vercel `headers` 등). HTML `<meta http-equiv>` 형태는 정적 호스트용 대안이지만 `frame-ancestors`, `report-uri`, `report-to`, `sandbox`는 `<meta>`에서 무시됩니다.