HTTPQUERY
한국어

Content-Security-Policy

사용법

Content-Security-Policy(CSP) 헤더는 사이트 관리자에게 리소스 로딩에 대한 세밀한 제어권을 줍니다. 정책을 선언하면 서버는 승인된 출처에서만 스크립트, 스타일, 이미지, 폰트를 비롯한 리소스를 로드하도록 브라우저에 지시합니다. 정책에 맞지 않는 리소스는 차단되고 브라우저가 위반 사항을 보고합니다.

정책은 세미콜론으로 구분된 하나 이상의 디렉티브로 구성됩니다. 각 디렉티브는 리소스 유형을 지정하고 그 유형에 허용되는 출처를 나열합니다.

Content-Security-Policy: <directive> <source>; <directive>
  <source>

새 정책을 먼저 보고 전용 모드로 배포하는 것이 일반적인 관행입니다. Content-Security-Policy-Report-Only 헤더는 같은 구문을 사용하되 리소스를 차단하지 않고 위반 사항만 기록하므로, 관리자가 강제 적용 전에 정책을 테스트할 수 있습니다.

Fetch 지시어

Fetch 디렉티브는 특정 리소스 유형이 로드되는 위치를 제어합니다.

default-src

default-src 디렉티브는 다른 모든 fetch 디렉티브의 대체 수단 역할을 합니다. 특정 fetch 디렉티브가 없으면 브라우저는 default-src로 되돌아갑니다.

Content-Security-Policy: default-src 'self'

script-src

script-src 디렉티브는 JavaScript 실행의 출처를 제한합니다. nonce 기반과 해시 기반 허용 목록은 호스트 기반 규칙보다 강력한 보호를 제공합니다.

script-src-elem

script-src-elem 디렉티브는

script-src-attr

script-src-attr 디렉티브는 onclick이나 onload 같은 인라인 이벤트 핸들러를 관장하며,

style-src

style-src 디렉티브는 인라인 스타일과 외부 스타일시트 링크를 포함하여 CSS 스타일시트의 유효한 출처를 지정합니다.

style-src-elem

style-src-elem 디렉티브는

style-src-attr

style-src-attr 디렉티브는 style 속성을 통해 DOM 요소에 직접 적용되는 인라인 스타일을 관장합니다.

img-src

img-src 디렉티브는 이미지와 파비콘의 유효한 출처를 지정합니다.

connect-src

connect-src 디렉티브는 fetch(), XMLHttpRequest, WebSocket, EventSource를 비롯한 스크립트 인터페이스로 접근 가능한 URL을 제한합니다.

font-src

font-src 디렉티브는 @font-face로 로드되는 폰트의 유효한 출처를 지정합니다.

frame-src

frame-src 디렉티브는 과

media-src

media-src 디렉티브는

object-src

object-src 디렉티브는 와 요소의 출처를 제한합니다(은 HTML 명세에서 제거된 레거시 요소입니다). 이들 요소는 거의 필요하지 않으므로 ‘none’으로 설정하기를 권장합니다.

child-src

child-src 디렉티브는 웹 워커와 중첩 브라우징 컨텍스트에 허용되는 출처를 정의합니다. 더 구체적인 frame-src와 worker-src 디렉티브가 있으면 그것이 child-src를 덮어씁니다.

worker-src

worker-src 디렉티브는 Worker, SharedWorker, ServiceWorker 스크립트에 적용됩니다.

manifest-src

manifest-src 디렉티브는 웹 애플리케이션 매니페스트 파일의 유효한 출처를 지정합니다.

fenced-frame-src

fenced-frame-src 디렉티브는 요소에 로드되는 중첩 브라우징 컨텍스트의 유효한 출처를 지정합니다. 이 디렉티브가 없으면 브라우저는 frame-src로, 그다음 default-src로 되돌아갑니다.

Document 지시어

Document 디렉티브는 문서 환경의 속성을 관장합니다.

base-uri

base-uri 디렉티브는 요소에 허용되는 URL을 제한하여, 공격자가 상대 링크의 기준 URL을 바꾸지 못하게 막습니다.

sandbox

sandbox 디렉티브는

Navigation 디렉티브는 사용자와 폼이 요청을 보내는 위치를 제어합니다.

form-action

form-action 디렉티브는 폼 제출 대상으로 받아들여지는 URL을 제한합니다.

frame-ancestors

frame-ancestors 디렉티브는 ,

navigate-to 디렉티브는 문서가 어떤 메커니즘으로든 이동할 수 있는 URL을 제한하기 위해 제안되었습니다. 이 디렉티브는 CSP Level 3 명세에서 제거되었으며 어떤 상용 브라우저에도 출시된 적이 없습니다.

Reporting 지시어

Reporting 디렉티브는 위반 보고 동작을 제어합니다.

report-to

report-to 디렉티브는 Reporting-Endpoints 헤더가 정의한 보고 그룹 이름을 지정합니다. 위반 보고서는 지정된 그룹과 연결된 엔드포인트로 전송됩니다.

report-uri

report-uri 디렉티브는 지정된 URL로 위반 보고서를 보냅니다. 이 디렉티브는 report-to로 대체되는 중이지만 하위 호환성을 위해 여전히 널리 배포되어 있습니다.

upgrade-insecure-requests

upgrade-insecure-requests 디렉티브는 페이지의 모든 HTTP URL을 HTTPS로 취급하라고 브라우저에 지시합니다. 많은 리소스가 여전히 안전하지 않은 URL을 참조하는 HTTP에서 HTTPS로의 마이그레이션 기간에 유용합니다.

require-trusted-types-for

require-trusted-types-for 디렉티브는 DOM XSS 인젝션 싱크에 Trusted Types 정책을 강제하여, 문자열 대신 타입이 지정된 객체를 요구합니다.

trusted-types

trusted-types 디렉티브는 Trusted Types 정책 이름의 허용 목록을 지정하여, 페이지가 어떤 정책을 생성할 수 있는지 제한합니다.

소스 값

디렉티브는 리소스가 어디서 로드되는지 정의하는 소스 표현식을 받습니다.

‘self’

현재 오리진(동일한 스킴, 호스트, 포트)에 일치합니다. 하위 도메인은 포함하지 않습니다.

‘none’

해당 디렉티브의 모든 출처를 차단합니다. 지정된 유형의 리소스는 전혀 로드되지 않습니다.

‘unsafe-inline’

인라인

‘unsafe-eval’

eval(), Function() 및 유사한 구조를 통한 동적 코드 평가를 허용합니다.

‘unsafe-hashes’

모든 인라인 스크립트를 허용하지 않으면서, 해시로 식별된 특정 인라인 이벤트 핸들러만 허용합니다.

‘strict-dynamic’

이미 신뢰된 스크립트가 로드한 스크립트까지 신뢰를 확장합니다. nonce 기반 정책과 결합하면 모든 스크립트 호스트를 일일이 허용 목록에 넣을 필요가 없어집니다.

‘nonce-*’

서버가 응답마다 생성하는 암호학적 nonce(한 번만 쓰이는 숫자)입니다. 정책의 nonce 값은

Content-Security-Policy: script-src 'nonce-abc123'

‘sha256-’, ‘sha384-’, ‘sha512-*’

인라인 스크립트나 스타일 내용의 해시입니다. 브라우저는 각 인라인 블록의 해시를 계산하여 그 결과를 허용 목록의 해시와 비교합니다.

host-source

허용되는 오리진을 지정하는 호스트 또는 URL 패턴입니다. 하위 도메인 와일드카드(*.example.re), 특정 포트(example.re:443), 경로 접두사(example.re/scripts/)를 지원합니다.

scheme-source

https: 나 data: 같은 스킴으로, 지정된 프로토콜로 제공되는 모든 리소스를 허용합니다.

‘report-sample’

script-src나 style-src 값에 추가하는 ‘report-sample’ 키워드는 위반 보고서에 위반한 코드의 짧은 샘플을 포함해 달라고 브라우저에 요청합니다. 문제가 된 인라인 스크립트나 스타일을 찾는 데 도움이 됩니다.

예시

동일 출처에서만 리소스를 허용하는 제한적인 정책으로, 모든 인라인 스크립트와 외부 리소스 로딩을 차단합니다.

Content-Security-Policy: default-src 'self'

스크립트와 이미지에 각각 다른 규칙을 적용한 정책입니다. 스크립트는 동일 출처에서만 로드되고, 이미지는 전용 이미지 CDN에서도 로드됩니다.

Content-Security-Policy: default-src 'self';
  img-src 'self' images.example.re

스크립트에 대한 nonce 기반 정책입니다. 페이지를 로드할 때마다 새 nonce가 생성되며, 일치하는 nonce 속성을 가진

Content-Security-Policy: script-src 'nonce-r4nd0m';
  style-src 'self'

‘strict-dynamic’과 nonce를 결합한 정책입니다. 신뢰된 스크립트는 개별 호스트 허용 목록 없이도 추가 스크립트를 자유롭게 로드할 수 있습니다.

Content-Security-Policy: script-src 'strict-dynamic'
  'nonce-r4nd0m'

규칙을 강제하면서 모니터링을 위해 위반 사항을 엔드포인트로 보고하는 정책입니다.

Content-Security-Policy: default-src 'self';
  report-to csp-violations

문제 해결

CSP 위반은 브라우저 콘솔에 차단된 리소스 URI와 차단을 일으킨 디렉티브를 담은 “Refused to…” 메시지로 나타납니다.

CSP를 추가한 뒤 인라인 스크립트가 차단됩니다. 브라우저가 Refused to execute inline script because it violates the following Content Security Policy directive: “script-src …” 를 기록합니다. 기본 정책은 모든 인라인

인라인 스타일이 차단됩니다. style-src에 ‘unsafe-inline’이나 일치하는 nonce/해시가 없으면 콘솔에 Refused to apply inline style 이 표시됩니다. 런타임에 스타일을 주입하는 프레임워크가 이 위반을 유발합니다. style-src에 nonce를 추가하거나, nonce 기반 스타일로 전환하는 동안 ‘unsafe-inline’을 사용하십시오.

디렉티브에 도메인이 없어 외부 리소스가 차단됩니다. Refused to load the script 나 Refused to connect 오류는 해당 리소스의 오리진이 관련 디렉티브에 나열되어 있지 않다는 뜻입니다. 브라우저 콘솔을 열어 위반 메시지에서 차단된 오리진을 확인하고, 그 오리진을 올바른 디렉티브(script-src, img-src, connect-src 등)에 추가하십시오. 없는 디렉티브는 기본값으로 되돌아가므로 default-src도 함께 확인하십시오.

eval()이 기본적으로 차단됩니다. eval(), new Function(), 템플릿 컴파일러에 의존하는 라이브러리는 Refused to evaluate a string as JavaScript 를 유발합니다. script-src에 ‘unsafe-eval’을 추가하면 기능은 복구되지만 정책이 약해집니다. 가능하다면 eval()을 쓰지 않도록 코드를 리팩터링하는 편이 좋습니다.

CSP에서 Google Tag Manager나 분석 스크립트가 깨집니다. 태그 관리자는 스크립트를 동적으로 주입하므로, 주입되는 각 스크립트에 nonce나 호스트 허용 목록 항목이 필요합니다. script-src에 GTM 도메인(https://www.googletagmanager.com)을, connect-src와 img-src에 https://www.google-analytics.com 을 추가하십시오. nonce 기반 정책에서는 ‘strict-dynamic’을 사용하여, 신뢰된 GTM 스크립트가 로드한 스크립트가 개별 호스트 항목 없이 신뢰를 물려받게 하십시오.

브라우저 콘솔에서 위반 사항 디버깅하기. DevTools를 열고 Console 탭에서 CSP 위반 메시지를 확인하십시오. 각 메시지는 차단된 URI, 위반된 디렉티브, 전체 정책을 알려 줍니다. Chrome에서는 Network 탭이 차단된 요청을 (blocked:csp) 상태로 표시합니다. Firefox도 Console과 Network 패널에서 비슷한 수준의 정보를 제공합니다.

Report-Only 모드로 정책을 안전하게 테스트하기. 먼저 Content-Security-Policy-Report-Only 헤더로 정책을 배포하십시오. 이렇게 하면 어떤 리소스도 차단하지 않고 위반 사항만 기록합니다. 위반 보고서를 모니터링하고 빠진 출처를 보완한 뒤, 보고 스트림이 깨끗해지면 강제 적용하는 Content-Security-Policy 헤더로 전환하십시오.