본문으로 건너뛰기
AZ Tools

Content-Security-Policy 빌더

디렉티브별 소스 리스트로 CSP 헤더 빌드, 3개 시작 프리셋·위험한 와일드카드 실시간 경고.

프리셋
디렉티브
헤더
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; connect-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'
<meta> 태그
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; connect-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'">

빈 디렉티브는 default-src로 폴백. default-src 'self' 먼저 설정 후 개별 소스 좁히기.

사용법

  1. 프리셋에서 시작(Strict는 모두 'self', Relaxed는 인라인·와일드카드 허용, API only는 내비게이션 차단).
  2. 각 디렉티브 편집 — 비우면 제외.
  3. 새 정책 출시 시 report-only 켜기: 위반은 보고되지만 차단되지 않음.

자세한 설명

펼치기

지시어별 폼에서 Content-Security-Policy 헤더를 조합합니다. 각 지시어는 공백으로 구분된 소스 목록을 받습니다('self', 'none', 'unsafe-inline' 같은 키워드나 스킴/호스트 소스). 툴은 unsafe-inline, unsafe-eval, 와일드카드가 든 정책을 표시하고, 빈 지시어는 출력에서 빼며, 응답 헤더 형태와 그에 상응하는 <meta> 태그를 함께 내놓습니다(보고 전용 모드에서는 헤더만 내놓습니다. 브라우저는 <meta>로 전달된 보고 전용 정책을 무시하기 때문입니다). 새 정책을 운영에 적용하는 동안에는 보고 전용 모드로 바꿔 쓰면 됩니다.

두 출력 형태는 비슷해 보이지만 동등하지 않습니다. <meta> 태그는 frame-ancestors, report-uri, sandbox를 담을 수 없고, 문서에서 그것이 나타난 지점부터만 효력이 있어서 파서가 이미 지나온 것은 보호되지 않습니다. 응답 헤더에는 그런 제약이 없으므로 서버를 통제할 수 있다면 이쪽을 택하는 것이 맞습니다.

default-src는 하한선이 아니라 대체값입니다. 없는 지시어는 여기서 물려받지만, 직접 쓴 지시어는 해당 자원 종류에 대해 이것을 통째로 대체합니다. 그래서 엄격한 default-src 'self'가 있는 정책에 script-src https://cdn.example.com을 더하면, 'self'를 다시 적지 않는 한 스크립트에 대해서는 'self'가 빠집니다. frame-ancestors와 base-uri를 비롯한 몇몇 지시어는 아예 default-src로 되돌아가지 않으며, 생략하면 그냥 제한이 없습니다.

'unsafe-inline'이 경고를 받는 데는 이유가 있습니다. 대부분의 정책이 존재하는 이유인 그 보호를 꺼 버리기 때문입니다. 또한 nonce나 해시가 든 정책에서는 조용히 무시되는데, 특정 인라인 스크립트를 허용하는 현대적인 방법이 그것이며, 이 상호작용은 정책이 읽히는 것과 다르게 동작하는 흔한 원인입니다.

보고 전용 모드가 올바른 배포 방법입니다. 브라우저가 정책을 평가해 무엇이 깨졌을지 보고하되 아무것도 막지 않으므로, 잊고 있던 제삼자 스크립트와 인라인 핸들러가 드러납니다. 두 헤더가 서로 독립이라는 점은 알아 두십시오. 보고 전용 정책을 내보낸다고 이미 적용 중인 정책이 약해지지 않으며, 그것만으로는 아무것도 강제하지 않습니다.

자주 묻는 질문

헤더 vs <meta> — 뭐 써?

HTTP 헤더 우선. <meta>는 응답 헤더 편집 불가일 때(정적 호스트 등) 편리하지만 frame-ancestors·report-uri/report-to 정의 불가 → 항상 덜 강력.

와일드카드가 왜 경고?

소스 리스트의 *는 임의 URL 매치 → 정책 무력화. 특정 오리진에 핀하거나 'self' 사용 — 진짜 서드파티 스크립트 필요하면 명시적으로 나열.

사이트를 망가뜨리지 않고 정책을 적용하려면?

먼저 Content-Security-Policy-Report-Only로 보내라. 브라우저는 정책을 평가해 차단됐을 항목을 보고하면서도 실제로는 전부 로드하므로, 강제하기 전에 실제 트래픽에서 위반 사례를 모을 수 있다. 보고가 잠잠해지면 강제 헤더로 옮기면 된다. 자기 페이지를 짐작해서 쓴 정책은 거의 언제나 잊고 있던 무언가를 막는다.

출처 도메인을 허용했는데도 인라인 스크립트가 계속 막히는 이유는?

호스트 소스는 그 호스트에서 가져온 파일만 커버하기 때문이다. 페이지 안에 직접 쓴 코드는 대조할 URL이 없으므로 'unsafe-inline'이나 그 내용 그대로의 해시, 또는 서버가 헤더와 태그 양쪽에 넣는 논스가 필요하다. 인라인 스타일, style 속성, onclick 같은 이벤트 핸들러 속성도 마찬가지다.

관련 도구