디렉티브와 소스를 체크하면 이 페이지가 응답 헤더나 <meta> 태그에 쓸 올바른 한 줄 Content-Security-Policy를 조립합니다 — 그리고 중요한 노트도 함께: 어떤 디렉티브가 default-src로 절대 폴백하지 않는지, 해시나 nonce가 언제 unsafe-inline을 조용히 무시하는지, strict-dynamic이 무엇을 끄는지. 내장 SHA-256/384/512 해시 생성기가 인라인 스크립트와 스타일을 'sha256-…' 소스로 바꿉니다. 모든 것이 브라우저에서 돌고 아무것도 업로드되지 않습니다.
Fetch 디렉티브 — 콘텐츠가 어디서 올 수 있는가
체크 안 한 디렉티브는 정책에 없고, 소스 없이 체크만 한 것은 무시됩니다. 'none'은 같은 행의 다른 상자를 취소합니다. 추가 소스 상자는 쉼표 목록을 받습니다: 호스트 이름(cdn.example.com), 스킴(https:), 인용 있/없는 해시와 nonce.
디렉티브
'self'
'none'
'unsafe-inline'
'unsafe-eval'
'strict-dynamic'
data:
blob:
추가 소스
문서 디렉티브 — 페이지 자신이 할 수 있는 일
이 넷은 default-src로 폴백하지 않습니다. 빼면 "제한 없음"을 뜻하므로 완전한 정책은 명시적으로 설정합니다.
디렉티브
'self'
'none'
추가 소스
스위치, nonce, 리포팅
script nonce
report-uri
report-to
정책
아직 빌드된 것이 없습니다. 소스를 체크하고 정책 빌드를 누르세요.
인라인 스크립트/스타일용 해시 생성기
<script>와 </script> 사이(또는 스타일 블록)의 정확한 내용을 — 바이트 단위로, 앞뒤 줄 바꿈 없이 — 붙여넣고 알고리즘을 고르세요. 결과가 CSP 3가 기대하는 'sha256-…' 소스입니다.
해시 출력이 여기에 나타납니다.
될 수 있으면 meta 태그가 아니라 헤더로 배포하세요. 응답 헤더가 완전한 CSP입니다. frame-ancestors, report-uri, report-to는 거기서만 동작하고 헤더는 HTML 첫 바이트가 파싱되기 전에 적용됩니다. meta 태그는 서버 설정이 없는 정적 파일의 폴백입니다. 사이트가 실제로 보내는 헤더는 보안 헤더 검사기에서 확인하고 원시 응답 블록은 HTTP 헤더 파서에서 분해하세요.
자체 테스트 빌더를 고정 상태에 대해 재구동합니다: 소스 순서, 'none' 상호 배제, OWASP 기준선 문자열, nonce와 해시 인용, base-uri/form-action/frame-ancestors의 무폴백 노트, nonce/해시에 의한 unsafe-inline 무시, strict-dynamic 노트, Report-Only 헤더 이름, meta 태그 제외, 독립 계산된 SHA 벡터에 대한 해시 생성기, 부정 경로. 아무것도 전송되지 않습니다.
Content Security Policy란?
한 문장으로: CSP는 서버가 페이지와 함께 보내는 허용 목록으로, 스크립트·스타일·이미지·연결이 정확히 어디서 올 수 있는지 브라우저에게 알립니다 — 공격자가 HTML을 주입해도 주입된 스크립트는 소스가 목록에 없어 여전히 로드에 실패합니다.
'unsafe-inline' vs 해시와 nonce. 디렉티브에 nonce나 해시 소스가 있으면 CSP 3는 'unsafe-inline'을 무시합니다 — 아주 오래된 브라우저만을 위해 남습니다. "nonce를 추가하고 안전을 위해 unsafe-inline을 남겼다"가 실제로는 최신 브라우저가 nonce를 시행한다는 뜻인 이유입니다. 생성기가 그 조합을 표시해 사고가 아니라 결정이 되게 합니다.
strict-dynamic이 허용 목록을 끕니다.script-src에 strict-dynamic이 있으면 스크립트에 대해 호스트 소스, 스킴, 'self', 'unsafe-inline', data:가 모두 무시됩니다. nonce와 해시만 중요하고 그것들이 로드한 스크립트가 더 로드할 수 있습니다. 로더 스크립트를 돌리는 현대적 방법입니다 — 하지만 script-src 나머지 목록을 장식으로 만듭니다.
meta 태그는 2급입니다.frame-ancestors, report-uri, report-to는 <meta http-equiv>에서 무시됩니다. 생성기는 정책의 어떤 부분이 조용히 적용되지 않을지 보여줍니다.
흔한 실수
default-src *에 긴 예외 목록으로 시작하기. 반대로 하세요. 조인 default-src 'self'에서 시작해 넓힐 필요가 있는 디렉티브만 넓히세요. 좁은 정책은 테스트 중 크게 실패하고 넓은 정책은 영원히 조용히 실패합니다.
script-src 'unsafe-inline' 'unsafe-eval'을 배달하고 끝이라 부르기. 그 정책은 XSS 공격이 하려는 거의 아무것도 막지 않습니다. 스크립트에 nonce나 해스를 쓰고 strict-dynamic을 더하고 프로덕션에서 회귀를 잡으려 report-only를 계속 돌리세요.
default-src가 모든 것을 덮지 않는다는 것을 잊기.base-uri, form-action, frame-ancestors, sandbox에는 폴백이 없습니다 — 실전 CSP 배포에서 가장 많이 인용되는 구멍입니다.
시행 모드로 먼저 테스트하기. 수집기와 함께 Report-Only로 일주일 돌리고 보고서를 읽은 뒤 시행으로 전환하세요. 결제를 깨는 정책은 정책이 없는 것보다 나쁩니다.
공백을 다르게 해싱하기. 해시는 인라인 블록의 정확한 바이트를 덮습니다. 끝 줄 바꿈을 자르는 "친절한" 빌드 단계가 모든 해시를 바꿉니다. 소스가 아니라 배달되는 것에서 해시를 생성하세요.
FAQ
모든 디렉티브를 나열하면 default-src가 필요한가요? 아니오. 하지만 바닥으로 두는 것이 좋은 위생입니다. 미래 브라우저의 새 fetch 디렉티브가 "허용"이 아니라 당신의 기준선을 기본으로 받습니다.
upgrade-insecure-requests는 실제로 무엇을 하나요? 브라우저에게 페이지가 불러올 모든 http:// URL — 이미지, 스타일, fetch — 을 요청 전에 https://로 다시 쓰라고 알립니다. 이주 도구이며 최종 상태는 http:// URL이 전혀 없는 페이지입니다.
nonce 아니면 해시? 서버 응답을 통제하면 nonce(응답마다 무작위 값, 헤더와 각 script 태그 양쪽에). HTML이 정적이거나 캐시되면 해시. 정적 nonce는 절대 안 됩니다 — 변하지 않는 nonce는 몇 단계 거친 unsafe-inline일 뿐입니다.
정책은 배달되는데 위반이 도착하지 않는 이유는? Report-Only인지(보고만), report-uri가 POST를 받는 수집기를 가리키는지, 현대의 report-to 디렉티브가 필요로 하는 Reporting-Endpoints/Report-To 장치도 설정했는지 확인하세요.
CSP가 다른 보호를 대체하나요? 아니오. 한 층일 뿐입니다. 출력을 계속 이스케이프하고 쿠키를 HttpOnly와 Secure 뒤에 두고 HSTS를 유지하세요. 이 사이트의 보안 헤더 검사기가 전체 묶음을 평가합니다.